1#define JEMALLOC_TSD_C_ 2#include "jemalloc/internal/jemalloc_internal.h" 3 4/******************************************************************************/ 5/* Data. */ 6 7static unsigned ncleanups; 8static malloc_tsd_cleanup_t cleanups[MALLOC_TSD_CLEANUPS_MAX]; 9 10/******************************************************************************/ 11 12void * 13malloc_tsd_malloc(size_t size) 14{ 15 16 /* Avoid choose_arena() in order to dodge bootstrapping issues. */ 17 return (arena_malloc(arenas[0], size, false, false)); 18} 19 20void 21malloc_tsd_dalloc(void *wrapper) 22{ 23 24 idalloct(wrapper, false); 25} 26 27void 28malloc_tsd_no_cleanup(void *arg) 29{ 30 31 not_reached(); 32} 33 34#if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32) 35#ifndef _WIN32 36JEMALLOC_EXPORT 37#endif 38void 39_malloc_thread_cleanup(void) 40{ 41 bool pending[MALLOC_TSD_CLEANUPS_MAX], again; 42 unsigned i; 43 44 for (i = 0; i < ncleanups; i++) 45 pending[i] = true; 46 47 do { 48 again = false; 49 for (i = 0; i < ncleanups; i++) { 50 if (pending[i]) { 51 pending[i] = cleanups[i](); 52 if (pending[i]) 53 again = true; 54 } 55 } 56 } while (again); 57} 58#endif 59 60void 61malloc_tsd_cleanup_register(bool (*f)(void)) 62{ 63 64 assert(ncleanups < MALLOC_TSD_CLEANUPS_MAX); 65 cleanups[ncleanups] = f; 66 ncleanups++; 67} 68 69void 70malloc_tsd_boot(void) 71{ 72 73 ncleanups = 0; 74} 75 76#ifdef _WIN32 77static BOOL WINAPI 78_tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 79{ 80 81 switch (fdwReason) { 82#ifdef JEMALLOC_LAZY_LOCK 83 case DLL_THREAD_ATTACH: 84 isthreaded = true; 85 break; 86#endif 87 case DLL_THREAD_DETACH: 88 _malloc_thread_cleanup(); 89 break; 90 default: 91 break; 92 } 93 return (true); 94} 95 96#ifdef _MSC_VER 97# ifdef _M_IX86 98# pragma comment(linker, "/INCLUDE:__tls_used") 99# else 100# pragma comment(linker, "/INCLUDE:_tls_used") 101# endif 102# pragma section(".CRT$XLY",long,read) 103#endif 104JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used) 105static const BOOL (WINAPI *tls_callback)(HINSTANCE hinstDLL, 106 DWORD fdwReason, LPVOID lpvReserved) = _tls_callback; 107#endif 108 109#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ 110 !defined(_WIN32)) 111void * 112tsd_init_check_recursion(tsd_init_head_t *head, tsd_init_block_t *block) 113{ 114 pthread_t self = pthread_self(); 115 tsd_init_block_t *iter; 116 117 /* Check whether this thread has already inserted into the list. */ 118 malloc_mutex_lock(&head->lock); 119 ql_foreach(iter, &head->blocks, link) { 120 if (iter->thread == self) { 121 malloc_mutex_unlock(&head->lock); 122 return (iter->data); 123 } 124 } 125 /* Insert block into list. */ 126 ql_elm_new(block, link); 127 block->thread = self; 128 ql_tail_insert(&head->blocks, block, link); 129 malloc_mutex_unlock(&head->lock); 130 return (NULL); 131} 132 133void 134tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block) 135{ 136 137 malloc_mutex_lock(&head->lock); 138 ql_remove(&head->blocks, block, link); 139 malloc_mutex_unlock(&head->lock); 140} 141#endif 142