summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2016-10-28 20:51:52 (GMT)
committerJason Evans <jasone@canonware.com>2016-10-28 22:08:19 (GMT)
commit830938840865fe236ae2bdc0abdb0d5778146859 (patch)
tree3c16a30b9f4aa96717e345206f23ca6365a924bf
parentbde815dc40c636523382912ecba443cc50b0eccd (diff)
downloadjemalloc-830938840865fe236ae2bdc0abdb0d5778146859.zip
jemalloc-830938840865fe236ae2bdc0abdb0d5778146859.tar.gz
jemalloc-830938840865fe236ae2bdc0abdb0d5778146859.tar.bz2
Support static linking of jemalloc with glibc
glibc defines its malloc implementation with several weak and strong symbols: strong_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc) strong_alias (__libc_free, __cfree) weak_alias (__libc_free, cfree) strong_alias (__libc_free, __free) strong_alias (__libc_free, free) strong_alias (__libc_malloc, __malloc) strong_alias (__libc_malloc, malloc) The issue is not with the weak symbols, but that other parts of glibc depend on __libc_malloc explicitly. Defining them in terms of jemalloc API's allows the linker to drop glibc's malloc.o completely from the link, and static linking no longer results in symbol collisions. Another wrinkle: jemalloc during initialization calls sysconf to get the number of CPU's. GLIBC allocates for the first time before setting up isspace (and other related) tables, which are used by sysconf. Instead, use the pthread API to get the number of CPUs with GLIBC, which seems to work. This resolves #442.
-rw-r--r--include/jemalloc/internal/jemalloc_internal_decls.h3
-rw-r--r--src/jemalloc.c31
2 files changed, 34 insertions, 0 deletions
diff --git a/include/jemalloc/internal/jemalloc_internal_decls.h b/include/jemalloc/internal/jemalloc_internal_decls.h
index 910b2fc..1d7f207 100644
--- a/include/jemalloc/internal/jemalloc_internal_decls.h
+++ b/include/jemalloc/internal/jemalloc_internal_decls.h
@@ -17,6 +17,9 @@
# include <sys/uio.h>
# endif
# include <pthread.h>
+# ifdef JEMALLOC_GLIBC_MALLOC_HOOK
+# include <sched.h>
+# endif
# include <errno.h>
# include <sys/time.h>
# include <time.h>
diff --git a/src/jemalloc.c b/src/jemalloc.c
index 1f951e2..816cc73 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -749,6 +749,18 @@ malloc_ncpus(void)
SYSTEM_INFO si;
GetSystemInfo(&si);
result = si.dwNumberOfProcessors;
+#elif defined(JEMALLOC_GLIBC_MALLOC_HOOK)
+ /*
+ * glibc's sysconf() uses isspace(). glibc allocates for the first time
+ * *before* setting up the isspace tables. Therefore we need a
+ * different method to get the number of CPUs.
+ */
+ {
+ cpu_set_t set;
+
+ pthread_getaffinity_np(pthread_self(), sizeof(set), &set);
+ result = CPU_COUNT(&set);
+ }
#else
result = sysconf(_SC_NPROCESSORS_ONLN);
#endif
@@ -1882,6 +1894,25 @@ JEMALLOC_EXPORT void *(*__realloc_hook)(void *ptr, size_t size) = je_realloc;
JEMALLOC_EXPORT void *(*__memalign_hook)(size_t alignment, size_t size) =
je_memalign;
# endif
+
+/*
+ * To enable static linking with glibc, the libc specific malloc interface must
+ * be implemented also, so none of glibc's malloc.o functions are added to the
+ * link.
+ */
+#define ALIAS(je_fn) __attribute__((alias (#je_fn), used))
+/* To force macro expansion of je_ prefix before stringification. */
+#define PREALIAS(je_fn) ALIAS(je_fn)
+void *__libc_malloc(size_t size) PREALIAS(je_malloc);
+void __libc_free(void* ptr) PREALIAS(je_free);
+void *__libc_realloc(void* ptr, size_t size) PREALIAS(je_realloc);
+void *__libc_calloc(size_t n, size_t size) PREALIAS(je_calloc);
+void *__libc_memalign(size_t align, size_t s) PREALIAS(je_memalign);
+void *__libc_valloc(size_t size) PREALIAS(je_valloc);
+int __posix_memalign(void** r, size_t a, size_t s)
+ PREALIAS(je_posix_memalign);
+#undef PREALIAS
+#undef ALIAS
#endif
/*