diff options
Diffstat (limited to 'lib/libpthread/thread/thr_gc.c')
| -rw-r--r-- | lib/libpthread/thread/thr_gc.c | 111 |
1 files changed, 24 insertions, 87 deletions
diff --git a/lib/libpthread/thread/thr_gc.c b/lib/libpthread/thread/thr_gc.c index 510c51fc5b7f..e29e29bddf47 100644 --- a/lib/libpthread/thread/thr_gc.c +++ b/lib/libpthread/thread/thr_gc.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: uthread_gc.c,v 1.2 1998/09/30 19:17:51 dt Exp $ + * $Id: uthread_gc.c,v 1.3 1999/03/23 05:07:55 jb Exp $ * * Garbage collector thread. Frees memory allocated for dead threads. * @@ -74,20 +74,26 @@ _thread_gc(pthread_addr_t arg) /* Dump thread info to file. */ _thread_dump_info(); - /* Lock the thread list: */ - _lock_thread_list(); + /* + * Defer signals to protect the scheduling queues from + * access by the signal handler: + */ + _thread_kern_sig_defer(); /* Check if this is the last running thread: */ - if (_thread_link_list == _thread_run && - _thread_link_list->nxt == NULL) + if (TAILQ_FIRST(&_thread_list) == _thread_run && + TAILQ_NEXT(_thread_run, tle) == NULL) /* * This is the last thread, so it can exit * now. */ f_done = 1; - /* Unlock the thread list: */ - _unlock_thread_list(); + /* + * Undefer and handle pending signals, yielding if + * necessary: + */ + _thread_kern_sig_undefer(); /* * Lock the garbage collector mutex which ensures that @@ -100,48 +106,24 @@ _thread_gc(pthread_addr_t arg) p_stack = NULL; pthread_cln = NULL; - /* 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 search for the first dead thread that * has memory to free. */ - while (p_stack == NULL && pthread_cln == NULL && - pthread != NULL) { - /* Save a pointer to the next thread: */ - pthread_nxt = pthread->nxt_dead; - + for (pthread = TAILQ_FIRST(&_dead_list); + p_stack == NULL && pthread_cln == NULL && pthread != NULL; + pthread = TAILQ_NEXT(pthread, dle)) { /* Check if the initial thread: */ - if (pthread == _thread_initial) + if (pthread == _thread_initial) { /* Don't destroy 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_dead = - pthread->nxt_dead; + /* Remove this thread from the dead list: */ + TAILQ_REMOVE(&_dead_list, pthread, dle); /* * Check if the stack was not specified by @@ -162,14 +144,12 @@ _thread_gc(pthread_addr_t arg) * be freed outside the locks: */ pthread_cln = pthread; + } else { /* * This thread has not detached, so do - * not destroy it: - */ - pthread_prv = pthread; - - /* + * not destroy it. + * * Check if the stack was not specified by * the caller to pthread_create and has not * been destroyed yet: @@ -189,9 +169,6 @@ _thread_gc(pthread_addr_t arg) pthread->stack = NULL; } } - - /* Point to the next thread: */ - pthread = pthread_nxt; } /* @@ -229,52 +206,12 @@ _thread_gc(pthread_addr_t arg) */ if (p_stack != NULL) free(p_stack); - if (pthread_cln != NULL) { - /* Lock the thread list: */ - _lock_thread_list(); - - /* - * Check if the thread is at the head of the - * linked list. - */ - if (_thread_link_list == pthread_cln) - /* There is no previous thread: */ - _thread_link_list = pthread_cln->nxt; - else { - /* Point to the first thread in the list: */ - pthread = _thread_link_list; - - /* - * Enter a loop to find the thread in the - * linked list before the thread that is - * about to be freed. - */ - while (pthread != NULL && - pthread->nxt != pthread_cln) - /* Point to the next thread: */ - pthread = pthread->nxt; - - /* Check that a previous thread was found: */ - if (pthread != NULL) { - /* - * Point the previous thread to - * the one after the thread being - * freed: - */ - pthread->nxt = pthread_cln->nxt; - } - } - - /* Unlock the thread list: */ - _unlock_thread_list(); - + if (pthread_cln != NULL) /* * Free the memory allocated for the thread * structure. */ free(pthread_cln); - } - } return (NULL); } |
