]>
Commit | Line | Data |
---|---|---|
970d7e83 LB |
1 | #define JEMALLOC_MUTEX_C_ |
2 | #include "jemalloc/internal/jemalloc_internal.h" | |
3 | ||
4 | #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) | |
5 | #include <dlfcn.h> | |
6 | #endif | |
7 | ||
8 | #ifndef _CRT_SPINCOUNT | |
1a4d82fc | 9 | #define _CRT_SPINCOUNT 4000 |
970d7e83 LB |
10 | #endif |
11 | ||
12 | /******************************************************************************/ | |
13 | /* Data. */ | |
14 | ||
15 | #ifdef JEMALLOC_LAZY_LOCK | |
16 | bool isthreaded = false; | |
17 | #endif | |
18 | #ifdef JEMALLOC_MUTEX_INIT_CB | |
19 | static bool postpone_init = true; | |
20 | static malloc_mutex_t *postponed_mutexes = NULL; | |
21 | #endif | |
22 | ||
23 | #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) | |
24 | static void pthread_create_once(void); | |
25 | #endif | |
26 | ||
27 | /******************************************************************************/ | |
28 | /* | |
29 | * We intercept pthread_create() calls in order to toggle isthreaded if the | |
30 | * process goes multi-threaded. | |
31 | */ | |
32 | ||
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); | |
36 | ||
37 | static void | |
38 | pthread_create_once(void) | |
39 | { | |
40 | ||
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"); | |
45 | abort(); | |
46 | } | |
47 | ||
48 | isthreaded = true; | |
49 | } | |
50 | ||
51 | JEMALLOC_EXPORT int | |
52 | pthread_create(pthread_t *__restrict thread, | |
53 | const pthread_attr_t *__restrict attr, void *(*start_routine)(void *), | |
54 | void *__restrict arg) | |
55 | { | |
56 | static pthread_once_t once_control = PTHREAD_ONCE_INIT; | |
57 | ||
58 | pthread_once(&once_control, pthread_create_once); | |
59 | ||
60 | return (pthread_create_fptr(thread, attr, start_routine, arg)); | |
61 | } | |
62 | #endif | |
63 | ||
64 | /******************************************************************************/ | |
65 | ||
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)); | |
69 | #endif | |
70 | ||
71 | bool | |
72 | malloc_mutex_init(malloc_mutex_t *mutex) | |
73 | { | |
74 | ||
75 | #ifdef _WIN32 | |
54a0048b SL |
76 | # if _WIN32_WINNT >= 0x0600 |
77 | InitializeSRWLock(&mutex->lock); | |
78 | # else | |
970d7e83 LB |
79 | if (!InitializeCriticalSectionAndSpinCount(&mutex->lock, |
80 | _CRT_SPINCOUNT)) | |
81 | return (true); | |
54a0048b | 82 | # endif |
970d7e83 LB |
83 | #elif (defined(JEMALLOC_OSSPIN)) |
84 | mutex->lock = 0; | |
85 | #elif (defined(JEMALLOC_MUTEX_INIT_CB)) | |
86 | if (postpone_init) { | |
87 | mutex->postponed_next = postponed_mutexes; | |
88 | postponed_mutexes = mutex; | |
89 | } else { | |
54a0048b SL |
90 | if (_pthread_mutex_init_calloc_cb(&mutex->lock, |
91 | bootstrap_calloc) != 0) | |
970d7e83 LB |
92 | return (true); |
93 | } | |
94 | #else | |
95 | pthread_mutexattr_t attr; | |
96 | ||
97 | if (pthread_mutexattr_init(&attr) != 0) | |
98 | return (true); | |
99 | pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE); | |
100 | if (pthread_mutex_init(&mutex->lock, &attr) != 0) { | |
101 | pthread_mutexattr_destroy(&attr); | |
102 | return (true); | |
103 | } | |
104 | pthread_mutexattr_destroy(&attr); | |
105 | #endif | |
106 | return (false); | |
107 | } | |
108 | ||
109 | void | |
110 | malloc_mutex_prefork(malloc_mutex_t *mutex) | |
111 | { | |
112 | ||
113 | malloc_mutex_lock(mutex); | |
114 | } | |
115 | ||
116 | void | |
117 | malloc_mutex_postfork_parent(malloc_mutex_t *mutex) | |
118 | { | |
119 | ||
120 | malloc_mutex_unlock(mutex); | |
121 | } | |
122 | ||
123 | void | |
124 | malloc_mutex_postfork_child(malloc_mutex_t *mutex) | |
125 | { | |
126 | ||
127 | #ifdef JEMALLOC_MUTEX_INIT_CB | |
128 | malloc_mutex_unlock(mutex); | |
129 | #else | |
130 | if (malloc_mutex_init(mutex)) { | |
131 | malloc_printf("<jemalloc>: Error re-initializing mutex in " | |
132 | "child\n"); | |
133 | if (opt_abort) | |
134 | abort(); | |
135 | } | |
136 | #endif | |
137 | } | |
138 | ||
139 | bool | |
140 | mutex_boot(void) | |
141 | { | |
142 | ||
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, | |
54a0048b | 147 | bootstrap_calloc) != 0) |
970d7e83 LB |
148 | return (true); |
149 | postponed_mutexes = postponed_mutexes->postponed_next; | |
150 | } | |
151 | #endif | |
152 | return (false); | |
153 | } |