diff options
author | Leonard Crestez <lcrestez@ixiacom.com> | 2013-10-21 21:12:16 (GMT) |
---|---|---|
committer | Jason Evans <je@fb.com> | 2013-10-25 01:25:19 (GMT) |
commit | cb17fc6a8f1ce29be18de7af6d03e66056751fb2 (patch) | |
tree | b102ae0685f01d59eaed2c1e764b0754a50e97ab /src | |
parent | ac4403cacb225c0cf2c926179af39c21bd7bfc3a (diff) | |
download | jemalloc-cb17fc6a8f1ce29be18de7af6d03e66056751fb2.zip jemalloc-cb17fc6a8f1ce29be18de7af6d03e66056751fb2.tar.gz jemalloc-cb17fc6a8f1ce29be18de7af6d03e66056751fb2.tar.bz2 |
Add support for LinuxThreads.
When using LinuxThreads pthread_setspecific triggers recursive
allocation on all threads. Work around this by creating a global linked
list of in-progress tsd initializations.
This modifies the _tsd_get_wrapper macro-generated function. When it has
to initialize an TSD object it will push the item to the linked list
first. If this causes a recursive allocation then the _get_wrapper
request is satisfied from the list. When pthread_setspecific returns the
item is removed from the list.
This effectively adds a very poor substitute for real TLS used only
during pthread_setspecific allocation recursion.
Signed-off-by: Crestez Dan Leonard <lcrestez@ixiacom.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/tsd.c | 34 |
1 files changed, 34 insertions, 0 deletions
@@ -105,3 +105,37 @@ JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used) static const BOOL (WINAPI *tls_callback)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) = _tls_callback; #endif + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +void * +tsd_init_check_recursion(tsd_init_head_t *head, tsd_init_block_t *block) +{ + pthread_t self = pthread_self(); + tsd_init_block_t *iter; + + /* Check whether this thread has already inserted into the list. */ + malloc_mutex_lock(&head->lock); + ql_foreach(iter, &head->blocks, link) { + if (iter->thread == self) { + malloc_mutex_unlock(&head->lock); + return (iter->data); + } + } + /* Insert block into list. */ + ql_elm_new(block, link); + block->thread = self; + ql_tail_insert(&head->blocks, block, link); + malloc_mutex_unlock(&head->lock); + return (NULL); +} + +void +tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block) +{ + + malloc_mutex_lock(&head->lock); + ql_remove(&head->blocks, block, link); + malloc_mutex_unlock(&head->lock); +} +#endif |