From 2e166e1a00928d5a31f00c185c2464b2146d6f6a Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Sat, 16 Aug 2008 13:13:07 +0000 Subject: 2008-08-16 Neal H. Walfield * pthread/pt-alloc.c: Don't include . (__pthread_free_threads): Change to a struct __pthread *. (__pthread_free_threads_lock): New variable. (__pthread_alloc): When looking for a TCB to reuse, iterate over __pthread_free_threads taking the first for which the STATE field is PTHREAD_TERMINATED. When reusing a TCB, first call __pthread_thread_halt on it. * pthread/pt-dealloc.c: Don't include . (__pthread_free_threads): Change to a struct __pthread *. (__pthread_free_threads_lock): New declaration. (__pthread_dealloc): Enqueue PTHREAD on __PTHREAD_FREE_THREADS. Set PTHREAD->STATE to PTHREAD_TERMINATED after everything else. * pthread/pt-join.c (pthread_join): Call __pthread_thread_halt before destroying the thread. When destroying the thread, call __pthread_thread_dealloc on it. * pthread/pt-detach.c (pthread_detach): If destroying the thread, call __pthread_thread_halt before deallocating the stack. In this case, also call __pthread_thread_dealloc on the tcb. * pthread/pt-exit.c (pthread_exit): Call __pthread_dealloc only if the thread is detached and then as the last thing we do before calling __pthread_thread_halt. * pthread/pt-internal.h (__pthread_thread_halt): Remove argument NEED_DEALLOC. Update users. * sysdeps/mach/pt-thread-halt.c (__pthread_thread_halt): Remove argument need_dealloc. * sysdeps/mach/hurd/pt-sysdep.h (PTHREAD_SYSDEP_MEMBERS): Add field have_kernel_resources. * sysdeps/mach/hurd/pt-thread-alloc.c (__pthread_thread_alloc): If THREAD->HAVE_KERNEL_RESOURCES is true, just return. After allocating the resources, set THREAD->HAVE_KERNEL_RESOURCES to true. --- pthread/pt-dealloc.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'pthread/pt-dealloc.c') diff --git a/pthread/pt-dealloc.c b/pthread/pt-dealloc.c index 1fc7a7b..92fe1fd 100644 --- a/pthread/pt-dealloc.c +++ b/pthread/pt-dealloc.c @@ -1,5 +1,5 @@ /* Deallocate a thread structure. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -23,13 +23,12 @@ #include -#include - /* List of thread structures corresponding to free thread IDs. */ -extern __atomicptr_t __pthread_free_threads; +extern struct __pthread *__pthread_free_threads; +extern pthread_mutex_t __pthread_free_threads_lock; + -/* Deallocate the thread structure for PTHREAD and the resources - associated with it. */ +/* Deallocate the thread structure for PTHREAD. */ void __pthread_dealloc (struct __pthread *pthread) { @@ -44,20 +43,22 @@ __pthread_dealloc (struct __pthread *pthread) pthread_join is completely bogus, but unfortunately allowed by the standards. */ __pthread_mutex_lock (&pthread->state_lock); - pthread->state = PTHREAD_TERMINATED; if (pthread->state != PTHREAD_EXITED) pthread_cond_broadcast (&pthread->state_cond); __pthread_mutex_unlock (&pthread->state_lock); /* We do not actually deallocate the thread structure, but add it to a list of re-usable thread structures. */ - while (1) - { - pthread->next = (struct __pthread *)__pthread_free_threads; - if (__atomicptr_compare_and_swap (&__pthread_free_threads, - pthread->next, pthread)) - return; - } - - /* NOTREACHED */ + pthread_mutex_lock (&__pthread_free_threads_lock); + __pthread_enqueue (&__pthread_free_threads, pthread); + pthread_mutex_unlock (&__pthread_free_threads_lock); + + /* Setting PTHREAD->STATE to PTHREAD_TERMINATED makes this TCB + available for reuse. After that point, we can no longer assume + that PTHREAD is valid. + + Note that it is safe to not lock this update to PTHREAD->STATE: + the only way that it can now be accessed is in __pthread_alloc, + which reads this variable. */ + pthread->state = PTHREAD_TERMINATED; } -- cgit v1.2.3