summaryrefslogtreecommitdiff
path: root/pthread/pt-internal.h
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-12-26 21:19:58 +0100
committerRichard Braun <rbraun@sceen.net>2013-12-26 21:19:58 +0100
commitd8569a7a43651ca1c1149540619254e224ed7c9e (patch)
tree165328a64d7c0ef77bedf108e91724b74ec1d810 /pthread/pt-internal.h
parent01f8736f297da40f0ee327d73794579be2ec3ecf (diff)
Implement thread destruction
This change makes libpthread release almost every resource allocated for a thread, including the kernel thread, its send right, its reply port and its stack. This improves resource usage after peaks of activity during which servers can create hundreds or even thousands of threads. To achieve this, the library relies on the recently added thread_terminate_release one-way GNU Mach RPC, which allows threads to release their last resources along with terminating in a single operation. The pthread_exit function unconditionally releases all the resources it can, including other kernel objects (namely the port used for blocking and waking up) and signal states. When releasing the pthread structure, a reference counter is used so that joinable threads remain available. Once the reference counter drops to 0, the pthread structure can be recycled. Thread local storage (TLS) is also recycled since it needs to remain allocated while terminating the thread, as it is there that the reply port is stored. TLS could be released too, after grabbing the reply port name, but it is difficult to make sure no RPC involving a reply port is used afterwards, so the simpler solution of recycling TLS was chosen. * Makefile (libpthread-routines): Replace pt-thread-halt with pt-thread-terminate. * pthread/pt-alloc.c (initialize_pthread): Set reference counter and unconditionally initialize new threads completely. (__pthread_alloc): Remove call to __pthread_thread_halt, update calls to initialize_pthread. * pthread/pt-create.c (__pthread_create_internal): Don't attempt to reuse stacks, handle reference counter, update failure handling. * pthread/pt-dealloc.c: Include bits/pt-atomic.h. (__pthread_dealloc): Make pthread structure available for reuse when reference counter reaches 0. * pthread/pt-detach.c (pthread_detach): Assume the target thread takes care of its own resources and, as a result, simply unreference its pthread struct. * pthread/pt-exit.c (__pthread_exit): Release resources and terminate. * pthread/pt-internal.h (struct __pthread): New `nr_refs' member. (__pthread_alloc): Update description. (__pthread_dealloc): Likewise. (__pthread_thread_dealloc): Likewise. (__pthread_thread_terminate): New declaration. * pthread/pt-join.c (pthread_join): Assume the target thread takes care of its own resources and, as a result, simply unreference its pthread struct. * sysdeps/mach/hurd/pt-sigstate-destroy.c (__pthread_sigstate_destroy): Call _hurd_sigstate_delete. * sysdeps/mach/hurd/pt-sigstate-init.c (__pthread_sigstate_init): Call _hurd_thread_sigstate and _hurd_sigstate_set_global_rcv when appropriate. * sysdeps/mach/hurd/pt-sysdep.c (__pthread_create_internal): Prevent the library from releasing the stack of the main thread. * sysdeps/mach/hurd/pt-sysdep.h (PTHREAD_SYSDEP_MEMBERS): Remove `have_kernel_resources' from the list of sysdep members. * sysdeps/mach/pt-thread-alloc.c (__pthread_thread_alloc): Update thread allocation. * sysdeps/mach/pt-thread-dealloc.c (__pthread_thread_dealloc): Update description. * sysdeps/mach/pt-thread-halt.c: Remove file. * sysdeps/mach/pt-thread-start.c (__pthread_thread_start): Fix the conditions under which a thread should actually be started. * sysdeps/mach/pt-thread-terminate.c: New file.
Diffstat (limited to 'pthread/pt-internal.h')
-rw-r--r--pthread/pt-internal.h36
1 files changed, 22 insertions, 14 deletions
diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h
index aeac009..9e0bbe9 100644
--- a/pthread/pt-internal.h
+++ b/pthread/pt-internal.h
@@ -72,6 +72,12 @@ struct __pthread
/* Thread ID. */
pthread_t thread;
+ __atomic_t nr_refs; /* Detached threads have a self reference only,
+ while joinable threads have two references.
+ These are used to keep the structure valid at
+ thread destruction. Detaching/joining a thread
+ drops a reference. */
+
/* Cancellation. */
pthread_mutex_t cancel_lock; /* Protect cancel_xxx members. */
void (*cancel_hook)(void *); /* Called to unblock a thread blocking
@@ -208,12 +214,13 @@ extern int __pthread_create_internal (struct __pthread **__restrict pthread,
void *__restrict arg);
/* Allocate a new thread structure and a pthread thread ID (but not a
- kernel thread or a stack). */
+ kernel thread or a stack). THREAD has one reference. */
extern int __pthread_alloc (struct __pthread **thread);
/* Deallocate the thread structure. This is the dual of
- __pthread_alloc (N.B. it does not call __pthread_stack_alloc nor
- __pthread_thread_halt). */
+ __pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor
+ __pthread_thread_terminate). THREAD loses one reference and is
+ released if the reference counter drops to 0. */
extern void __pthread_dealloc (struct __pthread *thread);
@@ -238,22 +245,23 @@ extern int __pthread_setup (struct __pthread *__restrict thread,
resources) for THREAD; it must not be placed on the run queue. */
extern int __pthread_thread_alloc (struct __pthread *thread);
-/* Deallocate any kernel resources associated with THREAD. The thread
- must not be running (that is, if __pthread_thread_start was called,
- __pthread_thread_halt must first be called). This function will
- never be called by a thread on itself. In the case that a thread
- exits, its thread structure will be cached and cleaned up
- later. */
+/* Deallocate any kernel resources associated with THREAD. */
extern void __pthread_thread_dealloc (struct __pthread *thread);
/* Start THREAD making it eligible to run. */
extern int __pthread_thread_start (struct __pthread *thread);
-/* Stop the kernel thread associated with THREAD. This function may
- be called by two threads in parallel. In particular, by the thread
- itself and another thread trying to join it. This function must be
- implemented such that this is safe. */
-extern void __pthread_thread_halt (struct __pthread *thread);
+/* Terminate the kernel thread associated with THREAD, and deallocate its
+ stack. In addition, THREAD loses one reference.
+
+ This function can be called by any thread, including the target thread.
+ Since some resources that are destroyed along the kernel thread are
+ stored in thread-local variables, the conditions required for this
+ function to behave correctly are a bit unusual : as long as the target
+ thread hasn't been started, any thread can terminate it, but once it
+ has started, no other thread can terminate it, so that thread-local
+ variables created by that thread are correctly released. */
+extern void __pthread_thread_terminate (struct __pthread *thread);
/* Called by a thread just before it calls the provided start