summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_create.c
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>1998-09-30 06:36:56 +0000
committerjb <jb@FreeBSD.org>1998-09-30 06:36:56 +0000
commitdf42f1ac5f49d30528909286a925e0d7492bc337 (patch)
treef3bf279acabc8ce90e6bbf65e33a722b578cebfb /lib/libpthread/thread/thr_create.c
parentd76ace8cb5de85bc8d0e7bcd29ff688098b1de96 (diff)
downloadFreeBSD-src-df42f1ac5f49d30528909286a925e0d7492bc337.zip
FreeBSD-src-df42f1ac5f49d30528909286a925e0d7492bc337.tar.gz
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.
Diffstat (limited to 'lib/libpthread/thread/thr_create.c')
-rw-r--r--lib/libpthread/thread/thr_create.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c
index 7603dd3..c7ddeb2 100644
--- a/lib/libpthread/thread/thr_create.c
+++ b/lib/libpthread/thread/thr_create.c
@@ -46,9 +46,11 @@ int
pthread_create(pthread_t * thread, const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg)
{
+ int f_gc = 0;
int i;
int ret = 0;
int status;
+ pthread_t gc_thread;
pthread_t new_thread;
pthread_attr_t pattr;
void *stack;
@@ -185,6 +187,12 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
/* Lock the thread list: */
_lock_thread_list();
+ /*
+ * Check if the garbage collector thread
+ * needs to be started.
+ */
+ f_gc = (_thread_link_list == _thread_initial);
+
/* Add the thread to the linked list of all threads: */
new_thread->nxt = _thread_link_list;
_thread_link_list = new_thread;
@@ -197,6 +205,14 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
/* Schedule the new user thread: */
_thread_kern_sched(NULL);
+
+ /*
+ * Start a garbage collector thread
+ * if necessary.
+ */
+ if (f_gc && pthread_create(&gc_thread,NULL,
+ _thread_gc,NULL) != 0)
+ PANIC("Can't create gc thread");
}
}
OpenPOWER on IntegriCloud