aboutsummaryrefslogtreecommitdiff
path: root/lib/libkse/thread/thr_find_thread.c
diff options
context:
space:
mode:
authorJohn Birrell <jb@FreeBSD.org>1998-09-30 06:36:56 +0000
committerJohn Birrell <jb@FreeBSD.org>1998-09-30 06:36:56 +0000
commitdc3a8b52c0f870cb23ddea843431bacca03fc629 (patch)
treeae55e7dc9f14a22b4e9e0ff67c28ff7d6541727d /lib/libkse/thread/thr_find_thread.c
parent05f3e91279c3769a892dd11d1c779bdbf58aee6d (diff)
downloadsrc-dc3a8b52c0f870cb23ddea843431bacca03fc629.tar.gz
src-dc3a8b52c0f870cb23ddea843431bacca03fc629.zip
Move the cleanup code that frees memory allocated for a dead thread from
the thread kernel into a garbage collector thread which is started when the fisrt thread is created (other than the initial thread). This removes the window of opportunity where a context switch will cause a thread that has locked the malloc spinlock, to enter the thread kernel, find there is a dead thread and try to free memory, therefore trying to lock the malloc spinlock against itself. The garbage collector thread acts just like any other thread, so instead of having a spinlock to control accesses to the dead thread list, it uses a mutex and a condition variable so that it can happily wait to be signalled when a thread exists.
Notes
Notes: svn path=/head/; revision=39807
Diffstat (limited to 'lib/libkse/thread/thr_find_thread.c')
-rw-r--r--lib/libkse/thread/thr_find_thread.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/libkse/thread/thr_find_thread.c b/lib/libkse/thread/thr_find_thread.c
index 99e302306d2a..e4a59a0d83f6 100644
--- a/lib/libkse/thread/thr_find_thread.c
+++ b/lib/libkse/thread/thr_find_thread.c
@@ -76,8 +76,12 @@ _find_dead_thread(pthread_t pthread)
/* Invalid thread: */
return(EINVAL);
- /* Lock the dead thread list: */
- _lock_dead_thread_list();
+ /*
+ * Lock the garbage collector mutex to ensure that the garbage
+ * collector is not using the dead thread list.
+ */
+ if (pthread_mutex_lock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
/* Point to the first thread in the list: */
pthread1 = _thread_dead;
@@ -85,11 +89,12 @@ _find_dead_thread(pthread_t pthread)
/* Search for the thread to join to: */
while (pthread1 != NULL && pthread1 != pthread) {
/* Point to the next thread: */
- pthread1 = pthread1->nxt;
+ pthread1 = pthread1->nxt_dead;
}
- /* Unlock the dead thread list: */
- _unlock_dead_thread_list();
+ /* Unlock the garbage collector mutex: */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot lock gc mutex");
/* Return zero if the thread exists: */
return ((pthread1 != NULL) ? 0:ESRCH);