MEDIUM: pool: refactor malloc_trim/glibc and jemalloc api addition detections.

Attempt to detect jemalloc at runtime before hand whether linked or via
symbols overrides, and fall back to malloc_trim/glibc for Linux otherwise.
This commit is contained in:
David Carlier 2021-11-25 16:09:45 +00:00 committed by Willy Tarreau
parent 5bae85d0d2
commit ed232148a7

View File

@ -42,66 +42,68 @@ int mem_poison_byte = -1;
static int mem_fail_rate = 0; static int mem_fail_rate = 0;
#endif #endif
#if defined(HA_HAVE_MALLOC_TRIM) static int using_default_allocator = 1;
static int using_libc_allocator = 0; static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL;
/* ask the allocator to trim memory pools */ /* ask the allocator to trim memory pools */
static void trim_all_pools(void) static void trim_all_pools(void)
{ {
if (using_libc_allocator) #if defined(HA_HAVE_MALLOC_TRIM)
if (using_default_allocator)
malloc_trim(0); malloc_trim(0);
#endif
} }
/* check if we're using the same allocator as the one that provides /* check if we're using the same allocator as the one that provides
* malloc_trim() and mallinfo(). The principle is that on glibc, both * malloc_trim() and mallinfo(). The principle is that on glibc, both
* malloc_trim() and mallinfo() are provided, and using mallinfo() we * malloc_trim() and mallinfo() are provided, and using mallinfo() we
* can check if malloc() is performed through glibc or any other one * can check if malloc() is performed through glibc or any other one
* the executable was linked against (e.g. jemalloc). * the executable was linked against (e.g. jemalloc). Prior to this we
* have to check whether we're running on jemalloc by verifying if the
* mallctl() function is provided. Its pointer will be used later.
*/ */
static void detect_allocator(void) static void detect_allocator(void)
{ {
extern int mallctl(const char *, void *, size_t *, void *, size_t) __attribute__((weak));
my_mallctl = mallctl;
if (!my_mallctl) {
my_mallctl = get_sym_curr_addr("mallctl");
using_default_allocator = (my_mallctl == NULL);
}
if (!my_mallctl) {
#if defined(HA_HAVE_MALLOC_TRIM)
#ifdef HA_HAVE_MALLINFO2 #ifdef HA_HAVE_MALLINFO2
struct mallinfo2 mi1, mi2; struct mallinfo2 mi1, mi2;
#else #else
struct mallinfo mi1, mi2; struct mallinfo mi1, mi2;
#endif #endif
void *ptr; void *ptr;
#ifdef HA_HAVE_MALLINFO2 #ifdef HA_HAVE_MALLINFO2
mi1 = mallinfo2(); mi1 = mallinfo2();
#else #else
mi1 = mallinfo(); mi1 = mallinfo();
#endif #endif
ptr = DISGUISE(malloc(1)); ptr = DISGUISE(malloc(1));
#ifdef HA_HAVE_MALLINFO2 #ifdef HA_HAVE_MALLINFO2
mi2 = mallinfo2(); mi2 = mallinfo2();
#else #else
mi2 = mallinfo(); mi2 = mallinfo();
#endif #endif
free(DISGUISE(ptr)); free(DISGUISE(ptr));
using_libc_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1)); using_default_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1));
#endif
}
} }
static int is_trim_enabled(void) static int is_trim_enabled(void)
{ {
return using_libc_allocator; return using_default_allocator;
} }
#else
static void trim_all_pools(void)
{
}
static void detect_allocator(void)
{
}
static int is_trim_enabled(void)
{
return 0;
}
#endif
/* Try to find an existing shared pool with the same characteristics and /* Try to find an existing shared pool with the same characteristics and
* returns it, otherwise creates this one. NULL is returned if no memory * returns it, otherwise creates this one. NULL is returned if no memory