* limit */
extern int bluesky_max_threads;
+/* A general-purpose counter for gathering run-time statistics. */
+struct bluesky_stats {
+ const char *name;
+ int64_t count;
+ int64_t sum;
+};
+struct bluesky_stats *bluesky_stats_new(const char *name);
+void bluesky_stats_add(struct bluesky_stats *stats, int64_t value);
+void bluesky_stats_dump_all();
+
/* BlueSky status and error codes. Various frontends should translate these to
* the appropriate error code for whatever protocol they implement. */
typedef enum {
g_hash_table_foreach(fs->inodes, inode_dump, fs);
}
+
+/* Statistics counters: for operation counts, bytes transferred, etc. */
+static GStaticMutex stats_lock = G_STATIC_MUTEX_INIT;
+static GList *stats_list = NULL;
+
+struct bluesky_stats *bluesky_stats_new(const char *name)
+{
+ struct bluesky_stats *stats = g_new0(struct bluesky_stats, 1);
+ stats->name = name;
+ g_static_mutex_lock(&stats_lock);
+ stats_list = g_list_append(stats_list, stats);
+ g_static_mutex_unlock(&stats_lock);
+ return stats;
+}
+
+void bluesky_stats_add(struct bluesky_stats *stats, int64_t value)
+{
+ __sync_fetch_and_add(&stats->count, (int64_t)1);
+ __sync_fetch_and_add(&stats->sum, value);
+}
+
+void bluesky_stats_dump_all()
+{
+ g_static_mutex_lock(&stats_lock);
+ for (GList *item = stats_list; item != NULL; item = item->next) {
+ struct bluesky_stats *stats = (struct bluesky_stats *)item->data;
+ g_print("%s: count=%"PRIi64" sum=%"PRIi64"\n",
+ stats->name, stats->count, stats->sum);
+ }
+ g_static_mutex_unlock(&stats_lock);
+}
GMutex *lock;
GCond *cond_idle;
int pending; /* Count of operations not yet complete. */
+
+ struct bluesky_stats *stats_get, *stats_put;
};
GHashTable *store_implementations;
store->lock = g_mutex_new();
store->cond_idle = g_cond_new();
store->pending = 0;
+ store->stats_get = bluesky_stats_new(g_strdup_printf("Store[%s]: GETS",
+ type));
+ store->stats_put = bluesky_stats_new(g_strdup_printf("Store[%s]: PUTS",
+ type));
g_free(scheme);
return store;
}
"[%p] complete: elapsed = %"PRIi64" ns, latency = %"PRIi64" ns",
async, elapsed, latency);
}
+
+ if (async->op == STORE_OP_GET) {
+ bluesky_stats_add(async->store->stats_get, 1);
+ } else if (async->op == STORE_OP_PUT) {
+ bluesky_stats_add(async->store->stats_put, 1);
+ }
}
void bluesky_store_async_submit(BlueSkyStoreAsync *async)
BlueSkyFS *fs;
BlueSkyStore *store;
+static void shutdown_handler(int num)
+{
+ g_print("SIGINT caught, shutting down...\n");
+ g_print("Proxy statistics:\n");
+ bluesky_stats_dump_all();
+ exit(1);
+}
+
int main(int argc, char *argv[])
{
int i;
signal(SIGPIPE, SIG_IGN);
+ signal(SIGINT, shutdown_handler);
bluesky_init();
g_set_prgname("nfsd");
if (fs_dump_requested) {
bluesky_debug_dump(fs);
+ bluesky_stats_dump_all();
fs_dump_requested = 0;
}