1 #define JEMALLOC_TSD_C_ 2 #include "jemalloc/internal/jemalloc_internal.h" 3 4 /******************************************************************************/ 5 /* Data. */ 6 7 static unsigned ncleanups; 8 static malloc_tsd_cleanup_t cleanups[MALLOC_TSD_CLEANUPS_MAX]; 9 10 /******************************************************************************/ 11 12 void * 13 malloc_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 20 void 21 malloc_tsd_dalloc(void *wrapper) 22 { 23 24 idalloct(wrapper, false); 25 } 26 27 void 28 malloc_tsd_no_cleanup(void *arg) 29 { 30 31 not_reached(); 32 } 33 34 #if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32) 35 #ifndef _WIN32 36 JEMALLOC_EXPORT 37 #endif 38 void 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 60 void 61 malloc_tsd_cleanup_register(bool (*f)(void)) 62 { 63 64 assert(ncleanups < MALLOC_TSD_CLEANUPS_MAX); 65 cleanups[ncleanups] = f; 66 ncleanups++; 67 } 68 69 void 70 malloc_tsd_boot(void) 71 { 72 73 ncleanups = 0; 74 } 75 76 #ifdef _WIN32 77 static 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 104 JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used) 105 static 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)) 111 void * 112 tsd_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 133 void 134 tsd_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