CLEANUP: activity: better use a mask to tests freeing methods
authorWilly Tarreau <w@1wt.eu>
Thu, 21 Nov 2024 09:08:03 +0000 (10:08 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 21 Nov 2024 18:58:06 +0000 (19:58 +0100)
In "show profiling memory", we need to distinguish methods which really
free memory from those which do not so that we don't account for the
free value twice. However for now it's done using multiple tests, which
are going to complicate the addition of new methods. Let's switch to a
bit field defined as a mask in a single place instead, as we don't
intend to use more than 32/64 methods!

include/haproxy/activity-t.h
src/activity.c

index 82666d3..b396dc0 100644 (file)
@@ -48,6 +48,15 @@ enum memprof_method {
        MEMPROF_METH_METHODS /* count, must be last */
 };
 
+/* mask of 1 << method to match those which free. Note that we don't count
+ * p_alloc among them since p_alloc only has an optionally valid free counter
+ * but which is reported by another call in any case since p_alloc itself does
+ * not free.
+ */
+#define MEMPROF_FREE_MASK   ((1UL << MEMPROF_METH_REALLOC) | \
+                             (1UL << MEMPROF_METH_FREE)    | \
+                             (1UL << MEMPROF_METH_P_FREE))
+
 /* stats:
  *   - malloc increases alloc
  *   - free increases free (if non null)
index 203e3e2..5a058f3 100644 (file)
@@ -825,9 +825,7 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
                else
                        chunk_appendf(&trash, "[other]");
 
-               if ((tmp_memstats[i].method != MEMPROF_METH_P_ALLOC) &&
-                   (tmp_memstats[i].method != MEMPROF_METH_MALLOC) &&
-                   (tmp_memstats[i].method != MEMPROF_METH_CALLOC)) {
+               if (((1UL << tmp_memstats[i].method) & MEMPROF_FREE_MASK) || !entry->alloc_calls) {
                        chunk_appendf(&trash," %s(%lld)", memprof_methods[entry->method],
                                (long long)(entry->alloc_tot - entry->free_tot) / (long long)(entry->alloc_calls + entry->free_calls));
                } else
@@ -858,9 +856,7 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
        for (i = 0; i < max_lines; i++) {
                tot_alloc_calls += tmp_memstats[i].alloc_calls;
                tot_alloc_bytes += tmp_memstats[i].alloc_tot;
-               if ((tmp_memstats[i].method != MEMPROF_METH_P_ALLOC) &&
-                   (tmp_memstats[i].method != MEMPROF_METH_MALLOC) &&
-                   (tmp_memstats[i].method != MEMPROF_METH_CALLOC)) {
+               if ((1UL << tmp_memstats[i].method) & MEMPROF_FREE_MASK) {
                        tot_free_calls  += tmp_memstats[i].free_calls;
                        tot_free_bytes  += tmp_memstats[i].free_tot;
                }
@@ -912,9 +908,7 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
                        tmp_memstats[j].info = strdup(p);   // may fail, but checked when used
                        tmp_memstats[j].alloc_calls = entry->alloc_calls;
                        tmp_memstats[j].alloc_tot   = entry->alloc_tot;
-                       if ((entry->method != MEMPROF_METH_P_ALLOC) &&
-                           (entry->method != MEMPROF_METH_MALLOC) &&
-                           (entry->method != MEMPROF_METH_CALLOC)) {
+                       if ((1UL << entry->method) & MEMPROF_FREE_MASK) {
                                tmp_memstats[j].free_calls  = entry->free_calls;
                                tmp_memstats[j].free_tot    = entry->free_tot;
                        } else {
@@ -924,9 +918,7 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
                } else {
                        tmp_memstats[j].alloc_calls += entry->alloc_calls;
                        tmp_memstats[j].alloc_tot += entry->alloc_tot;
-                       if ((entry->method != MEMPROF_METH_P_ALLOC) &&
-                           (entry->method != MEMPROF_METH_MALLOC) &&
-                           (entry->method != MEMPROF_METH_CALLOC)) {
+                       if ((1UL << entry->method) & MEMPROF_FREE_MASK) {
                                tmp_memstats[j].free_calls  += entry->free_calls;
                                tmp_memstats[j].free_tot  += entry->free_tot;
                        }