From 7865d569de7b29dd90b94b5680ec7a2a86ed27af Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 22 Feb 2019 02:29:21 -0500 Subject: [PATCH] make thread list lock a recursive lock this is a prerequisite for factoring the membarrier fallback code into a function that can be called from a context with the thread list already locked or independently. --- src/thread/pthread_create.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 0142b347..54c03554 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -17,28 +17,38 @@ weak_alias(dummy_0, __do_orphaned_stdio_locks); weak_alias(dummy_0, __dl_thread_cleanup); weak_alias(dummy_0, __dl_prepare_for_threads); +static int tl_lock_count; +static int tl_lock_waiters; + void __tl_lock(void) { - if (!a_cas(&__thread_list_lock, 0, 1)) return; - do { - a_cas(&__thread_list_lock, 1, 2); - __futexwait(&__thread_list_lock, 2, 0); - } while (a_cas(&__thread_list_lock, 0, 2)); + int tid = __pthread_self()->tid; + int val = __thread_list_lock; + if (val == tid) { + tl_lock_count++; + return; + } + while ((val = a_cas(&__thread_list_lock, 0, tid))) + __wait(&__thread_list_lock, &tl_lock_waiters, val, 0); } void __tl_unlock(void) { - if (a_swap(&__thread_list_lock, 0)==2) - __wake(&__thread_list_lock, 1, 0); + if (tl_lock_count) { + tl_lock_count--; + return; + } + a_store(&__thread_list_lock, 0); + if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); } void __tl_sync(pthread_t td) { a_barrier(); - if (!__thread_list_lock) return; - a_cas(&__thread_list_lock, 1, 2); - __wait(&__thread_list_lock, 0, 2, 0); - __wake(&__thread_list_lock, 1, 0); + int val = __thread_list_lock; + if (!val) return; + __wait(&__thread_list_lock, &tl_lock_waiters, val, 0); + if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); } _Noreturn void __pthread_exit(void *result) -- 2.25.1