1 #define JEMALLOC_TSD_C_
2 #include "jemalloc/internal/jemalloc_internal.h"
4 /******************************************************************************/
7 static unsigned ncleanups
;
8 static malloc_tsd_cleanup_t cleanups
[MALLOC_TSD_CLEANUPS_MAX
];
10 malloc_tsd_data(, , tsd_t
, TSD_INITIALIZER
)
12 /******************************************************************************/
15 malloc_tsd_malloc(size_t size
)
18 /* Avoid choose_arena() in order to dodge bootstrapping issues. */
19 return (arena_malloc(NULL
, arenas
[0], CACHELINE_CEILING(size
), false,
24 malloc_tsd_dalloc(void *wrapper
)
27 idalloct(NULL
, wrapper
, false);
31 malloc_tsd_no_cleanup(void *arg
)
37 #if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32)
42 _malloc_thread_cleanup(void)
44 bool pending
[MALLOC_TSD_CLEANUPS_MAX
], again
;
47 for (i
= 0; i
< ncleanups
; i
++)
52 for (i
= 0; i
< ncleanups
; i
++) {
54 pending
[i
] = cleanups
[i
]();
64 malloc_tsd_cleanup_register(bool (*f
)(void))
67 assert(ncleanups
< MALLOC_TSD_CLEANUPS_MAX
);
68 cleanups
[ncleanups
] = f
;
73 tsd_cleanup(void *arg
)
75 tsd_t
*tsd
= (tsd_t
*)arg
;
78 case tsd_state_nominal
:
83 tsd
->state
= tsd_state_purgatory
;
86 case tsd_state_purgatory
:
88 * The previous time this destructor was called, we set the
89 * state to tsd_state_purgatory so that other destructors
90 * wouldn't cause re-creation of the tsd. This time, do
91 * nothing, and do not request another callback.
94 case tsd_state_reincarnated
:
96 * Another destructor deallocated memory after this destructor
97 * was called. Reset state to tsd_state_purgatory and request
100 tsd
->state
= tsd_state_purgatory
;
109 malloc_tsd_boot(void)
120 _tls_callback(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
124 #ifdef JEMALLOC_LAZY_LOCK
125 case DLL_THREAD_ATTACH
:
129 case DLL_THREAD_DETACH
:
130 _malloc_thread_cleanup();
140 # pragma comment(linker, "/INCLUDE:__tls_used")
142 # pragma comment(linker, "/INCLUDE:_tls_used")
144 # pragma section(".CRT$XLY",long,read)
146 JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used
)
147 static const BOOL (WINAPI
*tls_callback
)(HINSTANCE hinstDLL
,
148 DWORD fdwReason
, LPVOID lpvReserved
) = _tls_callback
;
151 #if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
154 tsd_init_check_recursion(tsd_init_head_t
*head
, tsd_init_block_t
*block
)
156 pthread_t self
= pthread_self();
157 tsd_init_block_t
*iter
;
159 /* Check whether this thread has already inserted into the list. */
160 malloc_mutex_lock(&head
->lock
);
161 ql_foreach(iter
, &head
->blocks
, link
) {
162 if (iter
->thread
== self
) {
163 malloc_mutex_unlock(&head
->lock
);
167 /* Insert block into list. */
168 ql_elm_new(block
, link
);
169 block
->thread
= self
;
170 ql_tail_insert(&head
->blocks
, block
, link
);
171 malloc_mutex_unlock(&head
->lock
);
176 tsd_init_finish(tsd_init_head_t
*head
, tsd_init_block_t
*block
)
179 malloc_mutex_lock(&head
->lock
);
180 ql_remove(&head
->blocks
, block
, link
);
181 malloc_mutex_unlock(&head
->lock
);