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_kern.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_kern.c')
-rw-r--r-- | lib/libpthread/thread/thr_kern.c | 82 |
1 files changed, 2 insertions, 80 deletions
diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index ce17cf8..da125cd 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: uthread_kern.c,v 1.11 1998/04/30 21:50:29 jb Exp $ + * $Id: uthread_kern.c,v 1.12 1998/09/07 21:55:01 alex Exp $ * */ #include <errno.h> @@ -62,8 +62,6 @@ _thread_kern_sched(struct sigcontext * scp) int prio = -1; pthread_t pthread; pthread_t pthread_h = NULL; - pthread_t pthread_nxt = NULL; - pthread_t pthread_prv = NULL; pthread_t pthread_s = NULL; struct itimerval itimer; struct timespec ts; @@ -113,85 +111,9 @@ __asm__("fnsave %0": :"m"(*fdata)); */ _dispatch_signals(); return; - } else { + } else /* Flag the jump buffer was the last state saved: */ _thread_run->sig_saved = 0; - } - - /* Point to the first dead thread (if there are any): */ - pthread = _thread_dead; - - /* There is no previous dead thread: */ - pthread_prv = NULL; - - /* Enter a loop to cleanup after dead threads: */ - while (pthread != NULL) { - /* Save a pointer to the next thread: */ - pthread_nxt = pthread->nxt; - - /* Check if this thread is one which is running: */ - if (pthread == _thread_run || pthread == _thread_initial) { - /* - * Don't destroy the running thread or the initial - * thread. - */ - pthread_prv = pthread; - } - /* - * Check if this thread has detached: - */ - else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) { - /* Check if there is no previous dead thread: */ - if (pthread_prv == NULL) { - /* - * The dead thread is at the head of the - * list: - */ - _thread_dead = pthread_nxt; - } else { - /* - * The dead thread is not at the head of the - * list: - */ - pthread_prv->nxt = pthread->nxt; - } - - /* - * Check if the stack was not specified by the caller - * to pthread_create and has not been destroyed yet: - */ - if (pthread->attr.stackaddr_attr == NULL && pthread->stack != NULL) { - /* Free the stack of the dead thread: */ - free(pthread->stack); - } - /* Free the memory allocated to the thread structure: */ - free(pthread); - } else { - /* - * This thread has not detached, so do not destroy - * it: - */ - pthread_prv = pthread; - - /* - * Check if the stack was not specified by the caller - * to pthread_create and has not been destroyed yet: - */ - if (pthread->attr.stackaddr_attr == NULL && pthread->stack != NULL) { - /* Free the stack of the dead thread: */ - free(pthread->stack); - - /* - * NULL the stack pointer now that the memory - * has been freed: - */ - pthread->stack = NULL; - } - } - - /* Point to the next thread: */ - pthread = pthread_nxt; - } /* * Enter a the scheduling loop that finds the next thread that is |