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])(mutex,
83 malloc_mutex_init(malloc_mutex_t *mutex)
87 # if _WIN32_WINNT >= 0x0600
88 InitializeSRWLock(&mutex->lock);
90 if (!InitializeCriticalSectionAndSpinCount(&mutex->lock,
94 #elif (defined(JEMALLOC_OSSPIN))
96 #elif (defined(JEMALLOC_MUTEX_INIT_CB))
98 mutex->postponed_next = postponed_mutexes;
99 postponed_mutexes = mutex;
101 if (_pthread_mutex_init_calloc_cb(&mutex->lock,
102 bootstrap_calloc) != 0)
106 pthread_mutexattr_t attr;
108 if (pthread_mutexattr_init(&attr) != 0)
110 pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE);
111 if (pthread_mutex_init(&mutex->lock, &attr) != 0) {
112 pthread_mutexattr_destroy(&attr);
115 pthread_mutexattr_destroy(&attr);
121 malloc_mutex_prefork(malloc_mutex_t *mutex)
124 malloc_mutex_lock(mutex);
128 malloc_mutex_postfork_parent(malloc_mutex_t *mutex)
131 malloc_mutex_unlock(mutex);
135 malloc_mutex_postfork_child(malloc_mutex_t *mutex)
138 #ifdef JEMALLOC_MUTEX_INIT_CB
139 malloc_mutex_unlock(mutex);
141 if (malloc_mutex_init(mutex)) {
142 malloc_printf("<jemalloc>: Error re-initializing mutex in "
151 malloc_mutex_first_thread(void)
154 #ifdef JEMALLOC_MUTEX_INIT_CB
155 postpone_init = false;
156 while (postponed_mutexes != NULL) {
157 if (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock,
158 bootstrap_calloc) != 0)
160 postponed_mutexes = postponed_mutexes->postponed_next;
170 #ifndef JEMALLOC_MUTEX_INIT_CB
171 return (malloc_mutex_first_thread());