return true;
}
+static void slab_stat_cb(void *arg, const char *slab_name,
+ unsigned size, unsigned free,
+ unsigned total)
+{
+ PktBuf *buf = arg;
+ unsigned alloc = total * size;
+ pktbuf_write_DataRow(buf, "siiii", slab_name,
+ size, total - free, free, alloc);
+}
+
+/* Command: SHOW MEM */
+static bool admin_show_mem(PgSocket *admin, const char *arg)
+{
+ PktBuf *buf;
+
+ buf = pktbuf_dynamic(256);
+ if (!buf) {
+ admin_error(admin, "no mem");
+ return true;
+ }
+ pktbuf_write_RowDescription(buf, "siiii", "name",
+ "size", "used", "free", "memtotal");
+ objcache_stats(slab_stat_cb, buf);
+ admin_flush(admin, buf, "SHOW");
+ return true;
+}
+
/* Command: SHOW CONFIG */
static bool admin_show_config(PgSocket *admin, const char *arg)
{
SEND_generic(res, admin, 'N',
"sssss",
"SNOTICE", "C00000", "MConsole usage",
- "D\n\tSHOW [HELP|CONFIG|DATABASES"
- "|POOLS|CLIENTS|SERVERS|VERSION]\n"
- "\tSHOW [FDS|SOCKETS|ACTIVE_SOCKETS|LISTS]\n"
+ "D\n\tSHOW HELP|CONFIG|DATABASES"
+ "|POOLS|CLIENTS|SERVERS|VERSION\n"
+ "\tSHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM\n"
"\tSET key = arg\n"
"\tRELOAD\n"
"\tPAUSE [<db>]\n"
{"users", admin_show_users},
{"version", admin_show_version},
{"totals", admin_show_totals},
+ {"mem", admin_show_mem},
{NULL, NULL}
};
return objcache_total_count(cache) - objcache_free_count(cache);
}
+static void run_slab_stats(ObjectCache *cache, slab_stat_fn fn, void *arg)
+{
+ unsigned free = statlist_count(&cache->freelist);
+ fn(arg, cache->name, cache->final_size, free, cache->total_count);
+}
+
+void objcache_stats(slab_stat_fn fn, void *arg)
+{
+ ObjectCache *cache;
+ List *item;
+
+ statlist_for_each(item, &objcache_list) {
+ cache = container_of(item, ObjectCache, head);
+ run_slab_stats(cache, fn, arg);
+ }
+}
+