summaryrefslogtreecommitdiff
path: root/libpthread/pthread/pt-dealloc.c
diff options
context:
space:
mode:
authorneal <neal>2008-08-16 09:37:22 +0000
committerneal <neal>2008-08-16 09:37:22 +0000
commit54e51f1330ed2f31fd5b7a7260478880c54d33b7 (patch)
tree02c39cbc99be44bb7da8e44513c143801ebed729 /libpthread/pthread/pt-dealloc.c
parenta64c5f68c2e5915ac63e3e70216a970bda327c41 (diff)
2008-08-16 Neal H. Walfield <neal@gnu.org>
* pthread/pt-alloc.c: Don't include <atomic.h>. (__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 <atomic.h>. (__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-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/l4/hurd/pt-thread-halt.c (__pthread_thread_halt): Remove argument need_dealloc. Move the deallocation code from this file... * sysdeps/l4/hurd/pt-thread-dealloc.c: ... to this new file. * sysdeps/l4/hurd/pt-sysdep.h (PTHREAD_SYSDEP_MEMBERS): Add field have_kernel_resources. * sysdeps/l4/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.
Diffstat (limited to 'libpthread/pthread/pt-dealloc.c')
-rw-r--r--libpthread/pthread/pt-dealloc.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/libpthread/pthread/pt-dealloc.c b/libpthread/pthread/pt-dealloc.c
index 879608b..92fe1fd 100644
--- a/libpthread/pthread/pt-dealloc.c
+++ b/libpthread/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 <pt-internal.h>
-#include <atomic.h>
-
/* 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,22 +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 (atomic_compare_and_exchange_val_acq (&__pthread_free_threads,
- (uintptr_t) pthread,
- (uintptr_t) pthread->next)
- == (uintptr_t) pthread->next)
- break;
- }
+ pthread_mutex_lock (&__pthread_free_threads_lock);
+ __pthread_enqueue (&__pthread_free_threads, pthread);
+ pthread_mutex_unlock (&__pthread_free_threads_lock);
- /* NOTREACHED */
+ /* 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;
}