summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlier <devnexen@gmail.com>2021-11-25 16:09:45 +0000
committerWilly Tarreau <w@1wt.eu>2021-11-25 18:54:50 +0100
commited232148a7dbffbc279cb8efde3fd32c3fa94847 (patch)
treee3817f0eb905bb32cbc4db719b588d37af2e52c6
parent5bae85d0d2727566d0c6997eb80354ec5e7d720c (diff)
downloadhaproxy-ed232148a7dbffbc279cb8efde3fd32c3fa94847.tar.gz
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.
-rw-r--r--src/pool.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/pool.c b/src/pool.c
index af46b4469..514a53e12 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -42,66 +42,68 @@ int mem_poison_byte = -1;
static int mem_fail_rate = 0;
#endif
-#if defined(HA_HAVE_MALLOC_TRIM)
-static int using_libc_allocator = 0;
+static int using_default_allocator = 1;
+static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL;
/* ask the allocator to trim memory pools */
static void trim_all_pools(void)
{
- if (using_libc_allocator)
+#if defined(HA_HAVE_MALLOC_TRIM)
+ if (using_default_allocator)
malloc_trim(0);
+#endif
}
/* 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() are provided, and using mallinfo() we
* 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)
{
+ 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
- struct mallinfo2 mi1, mi2;
+ struct mallinfo2 mi1, mi2;
#else
- struct mallinfo mi1, mi2;
+ struct mallinfo mi1, mi2;
#endif
- void *ptr;
+ void *ptr;
#ifdef HA_HAVE_MALLINFO2
- mi1 = mallinfo2();
+ mi1 = mallinfo2();
#else
- mi1 = mallinfo();
+ mi1 = mallinfo();
#endif
- ptr = DISGUISE(malloc(1));
+ ptr = DISGUISE(malloc(1));
#ifdef HA_HAVE_MALLINFO2
- mi2 = mallinfo2();
+ mi2 = mallinfo2();
#else
- mi2 = mallinfo();
+ mi2 = mallinfo();
#endif
- free(DISGUISE(ptr));
-
- using_libc_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1));
-}
+ free(DISGUISE(ptr));
-static int is_trim_enabled(void)
-{
- return using_libc_allocator;
-}
-#else
-
-static void trim_all_pools(void)
-{
-}
-
-static void detect_allocator(void)
-{
+ using_default_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1));
+#endif
+ }
}
static int is_trim_enabled(void)
{
- return 0;
+ return using_default_allocator;
}
-#endif
/* Try to find an existing shared pool with the same characteristics and
* returns it, otherwise creates this one. NULL is returned if no memory