| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- /* Deallocate a thread structure.
- Copyright (C) 2000-2026 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
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
- #include <assert.h>
- #include <pthread.h>
- #include <stdlib.h>
- #include <pt-internal.h>
- #include <atomic.h>
- #include <ldsodefs.h>
- /* List of thread structures corresponding to free thread IDs. */
- extern struct __pthread *__pthread_free_threads;
- extern pthread_mutex_t __pthread_free_threads_lock;
- /* Deallocate the content of the thread structure for PTHREAD. */
- void
- __pthread_dealloc (struct __pthread *pthread)
- {
- if (atomic_fetch_add_relaxed (&pthread->nr_refs, -1) != 1)
- return;
- /* Withdraw this thread from the thread ID lookup table. */
- __pthread_setid (pthread->thread, NULL);
- /* Mark the thread as terminated. We broadcast the condition
- here to prevent pthread_join from waiting for this thread to
- exit where it was never really started. Such a call to
- pthread_join is completely bogus, but unfortunately allowed
- by the standards. */
- __pthread_mutex_lock (&pthread->state_lock);
- 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. */
- __pthread_mutex_lock (&__pthread_free_threads_lock);
- __pthread_enqueue (&__pthread_free_threads, pthread);
- __pthread_mutex_unlock (&__pthread_free_threads_lock);
- }
- libc_hidden_def (__pthread_dealloc)
- /* Confirm deallocation of the thread structure for PTHREAD. */
- void
- __pthread_dealloc_finish (struct __pthread *pthread)
- {
- /* Setting 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->terminated = TRUE;
- }
- libc_hidden_def (__pthread_dealloc_finish)
|