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));
72 malloc_mutex_init(malloc_mutex_t
*mutex
)
76 # if _WIN32_WINNT >= 0x0600
77 InitializeSRWLock(&mutex
->lock
);
79 if (!InitializeCriticalSectionAndSpinCount(&mutex
->lock
,
83 #elif (defined(JEMALLOC_OSSPIN))
85 #elif (defined(JEMALLOC_MUTEX_INIT_CB))
87 mutex
->postponed_next
= postponed_mutexes
;
88 postponed_mutexes
= mutex
;
90 if (_pthread_mutex_init_calloc_cb(&mutex
->lock
,
91 bootstrap_calloc
) != 0)
95 pthread_mutexattr_t attr
;
97 if (pthread_mutexattr_init(&attr
) != 0)
99 pthread_mutexattr_settype(&attr
, MALLOC_MUTEX_TYPE
);
100 if (pthread_mutex_init(&mutex
->lock
, &attr
) != 0) {
101 pthread_mutexattr_destroy(&attr
);
104 pthread_mutexattr_destroy(&attr
);
110 malloc_mutex_prefork(malloc_mutex_t
*mutex
)
113 malloc_mutex_lock(mutex
);
117 malloc_mutex_postfork_parent(malloc_mutex_t
*mutex
)
120 malloc_mutex_unlock(mutex
);
124 malloc_mutex_postfork_child(malloc_mutex_t
*mutex
)
127 #ifdef JEMALLOC_MUTEX_INIT_CB
128 malloc_mutex_unlock(mutex
);
130 if (malloc_mutex_init(mutex
)) {
131 malloc_printf("<jemalloc>: Error re-initializing mutex in "
143 #ifdef JEMALLOC_MUTEX_INIT_CB
144 postpone_init
= false;
145 while (postponed_mutexes
!= NULL
) {
146 if (_pthread_mutex_init_calloc_cb(&postponed_mutexes
->lock
,
147 bootstrap_calloc
) != 0)
149 postponed_mutexes
= postponed_mutexes
->postponed_next
;