MEDIUM: memory: add accounting for failed allocations
We now keep a per-pool counter of failed memory allocations and
we report that, as well as the amount of memory allocated and used
on the CLI.
diff --git a/src/dumpstats.c b/src/dumpstats.c
index b83dfb8..67686d3 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -2672,6 +2672,9 @@
"Uptime: %dd %dh%02dm%02ds\n"
"Uptime_sec: %d\n"
"Memmax_MB: %d\n"
+ "PoolAlloc_MB: %d\n"
+ "PoolUsed_MB: %d\n"
+ "PoolFailed: %d\n"
"Ulimit-n: %d\n"
"Maxsock: %d\n"
"Maxconn: %d\n"
@@ -2724,6 +2727,9 @@
up / 86400, (up % 86400) / 3600, (up % 3600) / 60, (up % 60),
up,
global.rlimit_memmax,
+ (int)(pool_total_allocated() / 1048576L),
+ (int)(pool_total_used() / 1048576L),
+ pool_total_failures(),
global.rlimit_nofile,
global.maxsock, global.maxconn, global.hardmaxconn,
actconn, totalconn, global.req_count,
diff --git a/src/memory.c b/src/memory.c
index 691e1e3..036f786 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -103,6 +103,7 @@
ptr = MALLOC(pool->size + POOL_EXTRA);
if (!ptr) {
+ pool->failed++;
if (failed)
return NULL;
failed++;
@@ -206,9 +207,9 @@
allocated = used = nbpools = 0;
chunk_printf(&trash, "Dumping pools usage. Use SIGQUIT to flush them.\n");
list_for_each_entry(entry, &pools, list) {
- chunk_appendf(&trash, " - Pool %s (%d bytes) : %d allocated (%u bytes), %d used, %d users%s\n",
+ chunk_appendf(&trash, " - Pool %s (%d bytes) : %d allocated (%u bytes), %d used, %d failures, %d users%s\n",
entry->name, entry->size, entry->allocated,
- entry->size * entry->allocated, entry->used,
+ entry->size * entry->allocated, entry->used, entry->failed,
entry->users, (entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
allocated += entry->allocated * entry->size;
@@ -226,6 +227,39 @@
qfprintf(stderr, "%s", trash.str);
}
+/* This function returns the total number of failed pool allocations */
+int pool_total_failures()
+{
+ struct pool_head *entry;
+ int failed = 0;
+
+ list_for_each_entry(entry, &pools, list)
+ failed += entry->failed;
+ return failed;
+}
+
+/* This function returns the total amount of memory allocated in pools (in bytes) */
+unsigned long pool_total_allocated()
+{
+ struct pool_head *entry;
+ unsigned long allocated = 0;
+
+ list_for_each_entry(entry, &pools, list)
+ allocated += entry->allocated * entry->size;
+ return allocated;
+}
+
+/* This function returns the total amount of memory used in pools (in bytes) */
+unsigned long pool_total_used()
+{
+ struct pool_head *entry;
+ unsigned long used = 0;
+
+ list_for_each_entry(entry, &pools, list)
+ used += entry->used * entry->size;
+ return used;
+}
+
/*
* Local variables:
* c-indent-level: 8