diff options
author | jb <jb@FreeBSD.org> | 1998-09-30 06:36:56 +0000 |
---|---|---|
committer | jb <jb@FreeBSD.org> | 1998-09-30 06:36:56 +0000 |
commit | df42f1ac5f49d30528909286a925e0d7492bc337 (patch) | |
tree | f3bf279acabc8ce90e6bbf65e33a722b578cebfb /lib/libpthread/thread/thr_create.c | |
parent | d76ace8cb5de85bc8d0e7bcd29ff688098b1de96 (diff) | |
download | FreeBSD-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.c | 16 |
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"); } } |