summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLeonard Crestez <lcrestez@ixiacom.com>2013-10-21 21:12:16 (GMT)
committerJason Evans <je@fb.com>2013-10-25 01:25:19 (GMT)
commitcb17fc6a8f1ce29be18de7af6d03e66056751fb2 (patch)
treeb102ae0685f01d59eaed2c1e764b0754a50e97ab /src
parentac4403cacb225c0cf2c926179af39c21bd7bfc3a (diff)
downloadjemalloc-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.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/tsd.c b/src/tsd.c
index 961a546..59e8da3 100644
--- a/src/tsd.c
+++ b/src/tsd.c
@@ -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