diff --git a/lib/memory.c b/lib/memory.c index 87cba69fc515..695bbfe11572 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -36,9 +36,19 @@ DEFINE_MTYPE(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec") static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr) { + size_t current; size_t oldsize; - atomic_fetch_add_explicit(&mt->n_alloc, 1, memory_order_relaxed); + current = 1 + atomic_fetch_add_explicit(&mt->n_alloc, 1, + memory_order_relaxed); + + oldsize = atomic_load_explicit(&mt->n_max, memory_order_relaxed); + if (current > oldsize) + /* note that this may fail, but approximation is sufficient */ + atomic_compare_exchange_weak_explicit(&mt->n_max, &oldsize, + current, + memory_order_relaxed, + memory_order_relaxed); oldsize = atomic_load_explicit(&mt->size, memory_order_relaxed); if (oldsize == 0) @@ -51,7 +61,15 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr) #ifdef HAVE_MALLOC_USABLE_SIZE size_t mallocsz = malloc_usable_size(ptr); - atomic_fetch_add_explicit(&mt->total, mallocsz, memory_order_relaxed); + current = mallocsz + atomic_fetch_add_explicit(&mt->total, mallocsz, + memory_order_relaxed); + oldsize = atomic_load_explicit(&mt->max_size, memory_order_relaxed); + if (current > oldsize) + /* note that this may fail, but approximation is sufficient */ + atomic_compare_exchange_weak_explicit(&mt->max_size, &oldsize, + current, + memory_order_relaxed, + memory_order_relaxed); #endif } diff --git a/lib/memory.h b/lib/memory.h index c39f34e3a7f8..2d6c1447786a 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -34,9 +34,11 @@ struct memtype { struct memtype *next, **ref; const char *name; _Atomic size_t n_alloc; + _Atomic size_t n_max; _Atomic size_t size; #ifdef HAVE_MALLOC_USABLE_SIZE _Atomic size_t total; + _Atomic size_t max_size; #endif }; diff --git a/lib/memory_vty.c b/lib/memory_vty.c index 9ee2e52ec751..73a18529a2a8 100644 --- a/lib/memory_vty.c +++ b/lib/memory_vty.c @@ -73,27 +73,45 @@ static int show_memory_mallinfo(struct vty *vty) static int qmem_walker(void *arg, struct memgroup *mg, struct memtype *mt) { struct vty *vty = arg; - if (!mt) + if (!mt) { vty_out(vty, "--- qmem %s ---\n", mg->name); - else { + vty_out(vty, "%-30s: %8s %-8s%s %8s %9s\n", + "Type", "Current#", " Size", +#ifdef HAVE_MALLOC_USABLE_SIZE + " Total", +#else + "", +#endif + "Max#", +#ifdef HAVE_MALLOC_USABLE_SIZE + "MaxBytes" +#else + "" +#endif + ); + } else { if (mt->n_alloc != 0) { char size[32]; snprintf(size, sizeof(size), "%6zu", mt->size); - #ifdef HAVE_MALLOC_USABLE_SIZE #define TSTR " %9zu" #define TARG , mt->total +#define TARG2 , mt->max_size #else #define TSTR "" #define TARG +#define TARG2 #endif - vty_out(vty, "%-30s: %10zu %-16s"TSTR"\n", mt->name, + vty_out(vty, "%-30s: %8zu %-8s"TSTR" %8zu"TSTR"\n", + mt->name, mt->n_alloc, mt->size == 0 ? "" : mt->size == SIZE_VAR - ? "(variably sized)" + ? "variable" : size - TARG); + TARG, + mt->n_max + TARG2); } } return 0;