1 #define JEMALLOC_MUTEX_C_
2 #include "jemalloc/internal/jemalloc_internal.h"
4 #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32)
9 #define _CRT_SPINCOUNT 4000
12 /******************************************************************************/
15 #ifdef JEMALLOC_LAZY_LOCK
16 bool isthreaded = false;
18 #ifdef JEMALLOC_MUTEX_INIT_CB
19 static bool postpone_init = true;
20 static malloc_mutex_t *postponed_mutexes = NULL;
23 #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32)
24 static void pthread_create_once(void);
27 /******************************************************************************/
29 * We intercept pthread_create() calls in order to toggle isthreaded if the
30 * process goes multi-threaded.
33 #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32)
34 static int (*pthread_create_fptr)(pthread_t *__restrict, const pthread_attr_t *,
35 void *(*)(void *), void *__restrict);
38 pthread_create_once(void)
41 pthread_create_fptr = dlsym(RTLD_NEXT, "pthread_create");
42 if (pthread_create_fptr == NULL) {
43 malloc_write("<jemalloc>: Error in dlsym(RTLD_NEXT, "
44 "\"pthread_create\")\n");
52 pthread_create(pthread_t *__restrict thread,
53 const pthread_attr_t *__restrict attr, void *(*start_routine)(void *),
56 static pthread_once_t once_control = PTHREAD_ONCE_INIT;
58 pthread_once(&once_control, pthread_create_once);
60 return (pthread_create_fptr(thread, attr, start_routine, arg));
64 /******************************************************************************/
66 #ifdef JEMALLOC_MUTEX_INIT_CB
67 JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
68 void *(calloc_cb)(size_t, size_t));
70 #pragma weak _pthread_mutex_init_calloc_cb
72 _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
73 void *(calloc_cb)(size_t, size_t))
76 return (((int (*)(pthread_mutex_t *, void *(*)(size_t, size_t)))
77 __libc_interposing[INTERPOS__pthread_mutex_init_calloc_cb])(
83 malloc_mutex_init(malloc_mutex_t *mutex)
87 if (!InitializeCriticalSectionAndSpinCount(&mutex->lock,
90 #elif (defined(JEMALLOC_OSSPIN))
92 #elif (defined(JEMALLOC_MUTEX_INIT_CB))
94 mutex->postponed_next = postponed_mutexes;
95 postponed_mutexes = mutex;
97 if (_pthread_mutex_init_calloc_cb(&mutex->lock, base_calloc) !=
102 pthread_mutexattr_t attr;
104 if (pthread_mutexattr_init(&attr) != 0)
106 pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE);
107 if (pthread_mutex_init(&mutex->lock, &attr) != 0) {
108 pthread_mutexattr_destroy(&attr);
111 pthread_mutexattr_destroy(&attr);
117 malloc_mutex_prefork(malloc_mutex_t *mutex)
120 malloc_mutex_lock(mutex);
124 malloc_mutex_postfork_parent(malloc_mutex_t *mutex)
127 malloc_mutex_unlock(mutex);
131 malloc_mutex_postfork_child(malloc_mutex_t *mutex)
134 #ifdef JEMALLOC_MUTEX_INIT_CB
135 malloc_mutex_unlock(mutex);
137 if (malloc_mutex_init(mutex)) {
138 malloc_printf("<jemalloc>: Error re-initializing mutex in "
147 malloc_mutex_first_thread(void)
150 #ifdef JEMALLOC_MUTEX_INIT_CB
151 postpone_init = false;
152 while (postponed_mutexes != NULL) {
153 if (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock,
156 postponed_mutexes = postponed_mutexes->postponed_next;
166 #ifndef JEMALLOC_MUTEX_INIT_CB
167 return (malloc_mutex_first_thread());