2 #ifdef JEMALLOC_H_TYPES
5 #define MALLOC_TSD_CLEANUPS_MAX 8
7 typedef bool (*malloc_tsd_cleanup_t)(void);
9 #if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
11 typedef struct tsd_init_block_s tsd_init_block_t;
12 typedef struct tsd_init_head_s tsd_init_head_t;
64 #define malloc_tsd_protos(a_attr, a_name, a_type) \
66 a_name##_tsd_boot(void); \
68 a_name##_tsd_get(void); \
70 a_name##_tsd_set(a_type *val);
73 #ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
74 #define malloc_tsd_externs(a_name, a_type) \
75 extern __thread a_type a_name##_tls; \
76 extern __thread bool a_name##_initialized; \
77 extern bool a_name##_booted;
78 #elif (defined(JEMALLOC_TLS))
79 #define malloc_tsd_externs(a_name, a_type) \
80 extern __thread a_type a_name##_tls; \
81 extern pthread_key_t a_name##_tsd; \
82 extern bool a_name##_booted;
83 #elif (defined(_WIN32))
84 #define malloc_tsd_externs(a_name, a_type) \
85 extern DWORD a_name##_tsd; \
86 extern bool a_name##_booted;
88 #define malloc_tsd_externs(a_name, a_type) \
89 extern pthread_key_t a_name##_tsd; \
90 extern tsd_init_head_t a_name##_tsd_init_head; \
91 extern bool a_name##_booted;
95 #ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
96 #define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
97 a_attr __thread a_type JEMALLOC_TLS_MODEL \
98 a_name##_tls = a_initializer; \
99 a_attr __thread bool JEMALLOC_TLS_MODEL \
100 a_name##_initialized = false; \
101 a_attr bool a_name##_booted = false;
102 #elif (defined(JEMALLOC_TLS))
103 #define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
104 a_attr __thread a_type JEMALLOC_TLS_MODEL \
105 a_name##_tls = a_initializer; \
106 a_attr pthread_key_t a_name##_tsd; \
107 a_attr bool a_name##_booted = false;
108 #elif (defined(_WIN32))
109 #define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
110 a_attr DWORD a_name##_tsd; \
111 a_attr bool a_name##_booted = false;
113 #define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
114 a_attr pthread_key_t a_name##_tsd; \
115 a_attr tsd_init_head_t a_name##_tsd_init_head = { \
116 ql_head_initializer(blocks), \
117 MALLOC_MUTEX_INITIALIZER \
119 a_attr bool a_name##_booted = false;
123 #ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
124 #define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
128 a_name##_tsd_cleanup_wrapper(void) \
131 if (a_name##_initialized) { \
132 a_name##_initialized = false; \
133 a_cleanup(&a_name##_tls); \
135 return (a_name##_initialized); \
138 a_name##_tsd_boot(void) \
141 if (a_cleanup != malloc_tsd_no_cleanup) { \
142 malloc_tsd_cleanup_register( \
143 &a_name##_tsd_cleanup_wrapper); \
145 a_name##_booted = true; \
150 a_name##_tsd_get(void) \
153 assert(a_name##_booted); \
154 return (&a_name##_tls); \
157 a_name##_tsd_set(a_type *val) \
160 assert(a_name##_booted); \
161 a_name##_tls = (*val); \
162 if (a_cleanup != malloc_tsd_no_cleanup) \
163 a_name##_initialized = true; \
165 #elif (defined(JEMALLOC_TLS))
166 #define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
170 a_name##_tsd_boot(void) \
173 if (a_cleanup != malloc_tsd_no_cleanup) { \
174 if (pthread_key_create(&a_name##_tsd, a_cleanup) != 0) \
177 a_name##_booted = true; \
182 a_name##_tsd_get(void) \
185 assert(a_name##_booted); \
186 return (&a_name##_tls); \
189 a_name##_tsd_set(a_type *val) \
192 assert(a_name##_booted); \
193 a_name##_tls = (*val); \
194 if (a_cleanup != malloc_tsd_no_cleanup) { \
195 if (pthread_setspecific(a_name##_tsd, \
196 (void *)(&a_name##_tls))) { \
197 malloc_write("<jemalloc>: Error" \
198 " setting TSD for "#a_name"\n"); \
204 #elif (defined(_WIN32))
205 #define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
211 } a_name##_tsd_wrapper_t; \
214 a_name##_tsd_cleanup_wrapper(void) \
216 a_name##_tsd_wrapper_t *wrapper; \
218 wrapper = (a_name##_tsd_wrapper_t *) TlsGetValue(a_name##_tsd); \
219 if (wrapper == NULL) \
221 if (a_cleanup != malloc_tsd_no_cleanup && \
222 wrapper->initialized) { \
223 a_type val = wrapper->val; \
224 a_type tsd_static_data = a_initializer; \
225 wrapper->initialized = false; \
226 wrapper->val = tsd_static_data; \
228 if (wrapper->initialized) { \
233 malloc_tsd_dalloc(wrapper); \
237 a_name##_tsd_boot(void) \
240 a_name##_tsd = TlsAlloc(); \
241 if (a_name##_tsd == TLS_OUT_OF_INDEXES) \
243 if (a_cleanup != malloc_tsd_no_cleanup) { \
244 malloc_tsd_cleanup_register( \
245 &a_name##_tsd_cleanup_wrapper); \
247 a_name##_booted = true; \
251 a_attr a_name##_tsd_wrapper_t * \
252 a_name##_tsd_get_wrapper(void) \
254 a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *) \
255 TlsGetValue(a_name##_tsd); \
257 if (wrapper == NULL) { \
258 wrapper = (a_name##_tsd_wrapper_t *) \
259 malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \
260 if (wrapper == NULL) { \
261 malloc_write("<jemalloc>: Error allocating" \
262 " TSD for "#a_name"\n"); \
265 static a_type tsd_static_data = a_initializer; \
266 wrapper->initialized = false; \
267 wrapper->val = tsd_static_data; \
269 if (!TlsSetValue(a_name##_tsd, (void *)wrapper)) { \
270 malloc_write("<jemalloc>: Error setting" \
271 " TSD for "#a_name"\n"); \
278 a_name##_tsd_get(void) \
280 a_name##_tsd_wrapper_t *wrapper; \
282 assert(a_name##_booted); \
283 wrapper = a_name##_tsd_get_wrapper(); \
284 return (&wrapper->val); \
287 a_name##_tsd_set(a_type *val) \
289 a_name##_tsd_wrapper_t *wrapper; \
291 assert(a_name##_booted); \
292 wrapper = a_name##_tsd_get_wrapper(); \
293 wrapper->val = *(val); \
294 if (a_cleanup != malloc_tsd_no_cleanup) \
295 wrapper->initialized = true; \
298 #define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
304 } a_name##_tsd_wrapper_t; \
307 a_name##_tsd_cleanup_wrapper(void *arg) \
309 a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *)arg;\
311 if (a_cleanup != malloc_tsd_no_cleanup && \
312 wrapper->initialized) { \
313 wrapper->initialized = false; \
314 a_cleanup(&wrapper->val); \
315 if (wrapper->initialized) { \
317 if (pthread_setspecific(a_name##_tsd, \
318 (void *)wrapper)) { \
319 malloc_write("<jemalloc>: Error" \
320 " setting TSD for "#a_name"\n"); \
327 malloc_tsd_dalloc(wrapper); \
330 a_name##_tsd_boot(void) \
333 if (pthread_key_create(&a_name##_tsd, \
334 a_name##_tsd_cleanup_wrapper) != 0) \
336 a_name##_booted = true; \
340 a_attr a_name##_tsd_wrapper_t * \
341 a_name##_tsd_get_wrapper(void) \
343 a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *) \
344 pthread_getspecific(a_name##_tsd); \
346 if (wrapper == NULL) { \
347 tsd_init_block_t block; \
348 wrapper = tsd_init_check_recursion( \
349 &a_name##_tsd_init_head, &block); \
352 wrapper = (a_name##_tsd_wrapper_t *) \
353 malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \
354 block.data = wrapper; \
355 if (wrapper == NULL) { \
356 malloc_write("<jemalloc>: Error allocating" \
357 " TSD for "#a_name"\n"); \
360 static a_type tsd_static_data = a_initializer; \
361 wrapper->initialized = false; \
362 wrapper->val = tsd_static_data; \
364 if (pthread_setspecific(a_name##_tsd, \
365 (void *)wrapper)) { \
366 malloc_write("<jemalloc>: Error setting" \
367 " TSD for "#a_name"\n"); \
370 tsd_init_finish(&a_name##_tsd_init_head, &block); \
375 a_name##_tsd_get(void) \
377 a_name##_tsd_wrapper_t *wrapper; \
379 assert(a_name##_booted); \
380 wrapper = a_name##_tsd_get_wrapper(); \
381 return (&wrapper->val); \
384 a_name##_tsd_set(a_type *val) \
386 a_name##_tsd_wrapper_t *wrapper; \
388 assert(a_name##_booted); \
389 wrapper = a_name##_tsd_get_wrapper(); \
390 wrapper->val = *(val); \
391 if (a_cleanup != malloc_tsd_no_cleanup) \
392 wrapper->initialized = true; \
398 #ifdef JEMALLOC_H_STRUCTS
400 #if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
402 struct tsd_init_block_s {
403 ql_elm(tsd_init_block_t) link;
407 struct tsd_init_head_s {
408 ql_head(tsd_init_block_t) blocks;
415 #ifdef JEMALLOC_H_EXTERNS
422 #if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
425 tsd_init_block_t *block);
431 #ifdef JEMALLOC_H_INLINES
#define malloc_tsd_no_cleanup
Definition: private_namespace.h:249
#define malloc_tsd_cleanup_register
Definition: private_namespace.h:246
#define ql_head(a_type)
Definition: ql.h:4
#define malloc_tsd_dalloc
Definition: private_namespace.h:247
#define ql_elm(a_type)
Definition: ql.h:11
#define bool
Definition: CascPort.h:16
#define malloc_tsd_malloc
Definition: private_namespace.h:248
#define tsd_init_check_recursion
Definition: private_namespace.h:411
#define malloc_tsd_boot
Definition: private_namespace.h:245
#define tsd_init_finish
Definition: private_namespace.h:412