eb65d1b078
Before this commit, in case FreeBSD libc jemalloc was overridden by another jemalloc, proper thread shutdown callback was involved only for the overriding jemalloc. A call to _malloc_thread_cleanup from libthr would be redirected to user jemalloc, leaving data about dead threads hanging in system jemalloc. This change tackles the issue in two ways. First, for current and old system jemallocs, which we can not modify, the overriding jemalloc would locate and invoke system cleanup routine. For upcoming jemalloc integrations, the cleanup registering function will also be redirected to user jemalloc, which means that system jemalloc's cleanup routine will be registered in user's jemalloc and a single call to _malloc_thread_cleanup will be sufficient to invoke both callbacks.
62 lines
1.2 KiB
C
62 lines
1.2 KiB
C
#ifdef JEMALLOC_INTERNAL_TSD_MALLOC_THREAD_CLEANUP_H
|
|
#error This file should be included only once, by tsd.h.
|
|
#endif
|
|
#define JEMALLOC_INTERNAL_TSD_MALLOC_THREAD_CLEANUP_H
|
|
|
|
#define JEMALLOC_TSD_TYPE_ATTR(type) __thread type JEMALLOC_TLS_MODEL
|
|
|
|
extern JEMALLOC_TSD_TYPE_ATTR(tsd_t) tsd_tls;
|
|
extern JEMALLOC_TSD_TYPE_ATTR(bool) tsd_initialized;
|
|
extern bool tsd_booted;
|
|
|
|
/* Initialization/cleanup. */
|
|
JEMALLOC_ALWAYS_INLINE bool
|
|
tsd_cleanup_wrapper(void) {
|
|
if (tsd_initialized) {
|
|
tsd_initialized = false;
|
|
tsd_cleanup(&tsd_tls);
|
|
}
|
|
return tsd_initialized;
|
|
}
|
|
|
|
JEMALLOC_ALWAYS_INLINE bool
|
|
tsd_boot0(void) {
|
|
_malloc_tsd_cleanup_register(&tsd_cleanup_wrapper);
|
|
tsd_booted = true;
|
|
return false;
|
|
}
|
|
|
|
JEMALLOC_ALWAYS_INLINE void
|
|
tsd_boot1(void) {
|
|
/* Do nothing. */
|
|
}
|
|
|
|
JEMALLOC_ALWAYS_INLINE bool
|
|
tsd_boot(void) {
|
|
return tsd_boot0();
|
|
}
|
|
|
|
JEMALLOC_ALWAYS_INLINE bool
|
|
tsd_booted_get(void) {
|
|
return tsd_booted;
|
|
}
|
|
|
|
JEMALLOC_ALWAYS_INLINE bool
|
|
tsd_get_allocates(void) {
|
|
return false;
|
|
}
|
|
|
|
/* Get/set. */
|
|
JEMALLOC_ALWAYS_INLINE tsd_t *
|
|
tsd_get(bool init) {
|
|
return &tsd_tls;
|
|
}
|
|
JEMALLOC_ALWAYS_INLINE void
|
|
tsd_set(tsd_t *val) {
|
|
assert(tsd_booted);
|
|
if (likely(&tsd_tls != val)) {
|
|
tsd_tls = (*val);
|
|
}
|
|
tsd_initialized = true;
|
|
}
|