]>
Commit | Line | Data |
---|---|---|
a78e148b | 1 | #define JEMALLOC_MUTEX_C_ |
2 | #include "jemalloc/internal/jemalloc_internal.h" | |
3 | ||
4934f93d | 4 | #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) |
5 | #include <dlfcn.h> | |
6 | #endif | |
7 | ||
8 | #ifndef _CRT_SPINCOUNT | |
9 | #define _CRT_SPINCOUNT 4000 | |
10 | #endif | |
11 | ||
a78e148b | 12 | /******************************************************************************/ |
13 | /* Data. */ | |
14 | ||
15 | #ifdef JEMALLOC_LAZY_LOCK | |
16 | bool isthreaded = false; | |
17 | #endif | |
4934f93d | 18 | #ifdef JEMALLOC_MUTEX_INIT_CB |
19 | static bool postpone_init = true; | |
20 | static malloc_mutex_t *postponed_mutexes = NULL; | |
21 | #endif | |
a78e148b | 22 | |
4934f93d | 23 | #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) |
a78e148b | 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 | ||
4934f93d | 33 | #if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) |
a78e148b | 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 | ||
4934f93d | 51 | JEMALLOC_EXPORT int |
a78e148b | 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 | ||
4934f93d | 66 | #ifdef JEMALLOC_MUTEX_INIT_CB |
67 | int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, | |
68 | void *(calloc_cb)(size_t, size_t)); | |
69 | #endif | |
70 | ||
a78e148b | 71 | bool |
72 | malloc_mutex_init(malloc_mutex_t *mutex) | |
73 | { | |
4934f93d | 74 | |
75 | #ifdef _WIN32 | |
76 | if (!InitializeCriticalSectionAndSpinCount(&mutex->lock, | |
77 | _CRT_SPINCOUNT)) | |
78 | return (true); | |
79 | #elif (defined(JEMALLOC_OSSPIN)) | |
80 | mutex->lock = 0; | |
81 | #elif (defined(JEMALLOC_MUTEX_INIT_CB)) | |
82 | if (postpone_init) { | |
83 | mutex->postponed_next = postponed_mutexes; | |
84 | postponed_mutexes = mutex; | |
85 | } else { | |
86 | if (_pthread_mutex_init_calloc_cb(&mutex->lock, base_calloc) != | |
87 | 0) | |
88 | return (true); | |
89 | } | |
a78e148b | 90 | #else |
91 | pthread_mutexattr_t attr; | |
92 | ||
93 | if (pthread_mutexattr_init(&attr) != 0) | |
94 | return (true); | |
4934f93d | 95 | pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE); |
96 | if (pthread_mutex_init(&mutex->lock, &attr) != 0) { | |
a78e148b | 97 | pthread_mutexattr_destroy(&attr); |
98 | return (true); | |
99 | } | |
100 | pthread_mutexattr_destroy(&attr); | |
a78e148b | 101 | #endif |
102 | return (false); | |
103 | } | |
104 | ||
105 | void | |
4934f93d | 106 | malloc_mutex_prefork(malloc_mutex_t *mutex) |
a78e148b | 107 | { |
108 | ||
4934f93d | 109 | malloc_mutex_lock(mutex); |
110 | } | |
111 | ||
112 | void | |
113 | malloc_mutex_postfork_parent(malloc_mutex_t *mutex) | |
114 | { | |
115 | ||
116 | malloc_mutex_unlock(mutex); | |
117 | } | |
118 | ||
119 | void | |
120 | malloc_mutex_postfork_child(malloc_mutex_t *mutex) | |
121 | { | |
122 | ||
123 | #ifdef JEMALLOC_MUTEX_INIT_CB | |
124 | malloc_mutex_unlock(mutex); | |
125 | #else | |
126 | if (malloc_mutex_init(mutex)) { | |
127 | malloc_printf("<jemalloc>: Error re-initializing mutex in " | |
128 | "child\n"); | |
129 | if (opt_abort) | |
130 | abort(); | |
a78e148b | 131 | } |
132 | #endif | |
133 | } | |
4934f93d | 134 | |
135 | bool | |
136 | mutex_boot(void) | |
137 | { | |
138 | ||
139 | #ifdef JEMALLOC_MUTEX_INIT_CB | |
140 | postpone_init = false; | |
141 | while (postponed_mutexes != NULL) { | |
142 | if (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock, | |
143 | base_calloc) != 0) | |
144 | return (true); | |
145 | postponed_mutexes = postponed_mutexes->postponed_next; | |
146 | } | |
147 | #endif | |
148 | return (false); | |
149 | } |