diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index ce83536ea..6a75177e1 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -233,6 +233,8 @@ enum { MEM_STATS_TYPE_MALLOC, MEM_STATS_TYPE_REALLOC, MEM_STATS_TYPE_STRDUP, + MEM_STATS_TYPE_P_ALLOC, + MEM_STATS_TYPE_P_FREE, }; struct mem_stats { diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index a13d0eb7c..3640ad112 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -224,6 +224,8 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call /****************** Common high-level code ******************/ +#if !defined(DEBUG_MEM_STATS) + /* * Returns a pointer to type taken from the pool or * dynamically allocated. Memory poisonning is performed if enabled. @@ -247,6 +249,55 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call __pool_free(pool, __ptr); \ } while (0) + +#else /* DEBUG_MEM_STATS is set below */ + +#define pool_free(pool, ptr) ({ \ + struct pool_head *__pool = (pool); \ + typeof(ptr) __ptr = (ptr); \ + static struct mem_stats _ __attribute__((used,__section__("mem_stats"))) = { \ + .file = __FILE__, .line = __LINE__, \ + .type = MEM_STATS_TYPE_P_FREE, \ + }; \ + HA_WEAK("__start_mem_stats"); \ + HA_WEAK("__stop_mem_stats"); \ + if (__ptr) { \ + _HA_ATOMIC_INC(&_.calls); \ + _HA_ATOMIC_ADD(&_.size, __pool->size); \ + __pool_free(__pool, __ptr); \ + } \ +}) + +#define pool_alloc(pool) ({ \ + struct pool_head *__pool = (pool); \ + size_t __x = __pool->size; \ + static struct mem_stats _ __attribute__((used,__section__("mem_stats"))) = { \ + .file = __FILE__, .line = __LINE__, \ + .type = MEM_STATS_TYPE_P_ALLOC, \ + }; \ + HA_WEAK("__start_mem_stats"); \ + HA_WEAK("__stop_mem_stats"); \ + _HA_ATOMIC_INC(&_.calls); \ + _HA_ATOMIC_ADD(&_.size, __x); \ + __pool_alloc(__pool, 0); \ +}) + +#define pool_zalloc(pool) ({ \ + struct pool_head *__pool = (pool); \ + size_t __x = __pool->size; \ + static struct mem_stats _ __attribute__((used,__section__("mem_stats"))) = { \ + .file = __FILE__, .line = __LINE__, \ + .type = MEM_STATS_TYPE_P_ALLOC, \ + }; \ + HA_WEAK("__start_mem_stats"); \ + HA_WEAK("__stop_mem_stats"); \ + _HA_ATOMIC_INC(&_.calls); \ + _HA_ATOMIC_ADD(&_.size, __x); \ + __pool_alloc(__pool, POOL_F_MUST_ZERO); \ +}) + +#endif /* DEBUG_MEM_STATS */ + #endif /* _HAPROXY_POOL_H */ /* diff --git a/src/debug.c b/src/debug.c index 9c23d8a75..308af6710 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1269,6 +1269,8 @@ static int debug_iohandler_memstats(struct appctx *appctx) case MEM_STATS_TYPE_MALLOC: type = "MALLOC"; break; case MEM_STATS_TYPE_REALLOC: type = "REALLOC"; break; case MEM_STATS_TYPE_STRDUP: type = "STRDUP"; break; + case MEM_STATS_TYPE_P_ALLOC: type = "P_ALLOC"; break; + case MEM_STATS_TYPE_P_FREE: type = "P_FREE"; break; default: type = "UNSET"; break; }