static void pthread_exited(pid_t pid) { pthread_descr th; int detached; /* Find thread with that pid */ for (th = __pthread_main_thread->p_nextlive; th != __pthread_main_thread; th = th->p_nextlive) { if (th->p_pid == pid) { /* Remove thread from list of active threads */ th->p_nextlive->p_prevlive = th->p_prevlive; th->p_prevlive->p_nextlive = th->p_nextlive; /* Mark thread as exited, and if detached, free its resources */ acquire(th->p_spinlock); th->p_exited = 1; detached = th->p_detached; release(th->p_spinlock); if (detached) pthread_free(th); break; } } /* If all threads have exited and the main thread is pending on a pthread_exit, wake up the main thread and terminate ourselves. */ if (main_thread_exiting && __pthread_main_thread->p_nextlive == __pthread_main_thread) { restart(__pthread_main_thread); _exit(0); } }
static void pthread_handle_free(pthread_descr th) { acquire(th->p_spinlock); if (th->p_exited) { release(th->p_spinlock); pthread_free(th); } else { /* The Unix process of the thread is still running. Mark the thread as detached so that the thread manager will deallocate its resources when the Unix process exits. */ th->p_detached = 1; release(th->p_spinlock); } }
static void pthread_exited(pid_t pid) { pthread_descr th; int detached; /* Find thread with that pid */ for (th = __pthread_main_thread->p_nextlive; th != __pthread_main_thread; th = th->p_nextlive) { if (th->p_pid == pid) { /* Remove thread from list of active threads */ th->p_nextlive->p_prevlive = th->p_prevlive; th->p_prevlive->p_nextlive = th->p_nextlive; /* Mark thread as exited, and if detached, free its resources */ __pthread_lock(th->p_lock, NULL); th->p_exited = 1; /* If we have to signal this event do it now. */ if (th->p_report_events) { /* See whether TD_REAP is in any of the mask. */ int idx = __td_eventword (TD_REAP); uint32_t mask = __td_eventmask (TD_REAP); if ((mask & (__pthread_threads_events.event_bits[idx] | th->p_eventbuf.eventmask.event_bits[idx])) != 0) { /* Yep, we have to signal the reapage. */ th->p_eventbuf.eventnum = TD_REAP; th->p_eventbuf.eventdata = th; __pthread_last_event = th; /* Now call the function to signal the event. */ __linuxthreads_reap_event(); } } detached = th->p_detached; __pthread_unlock(th->p_lock); if (detached) pthread_free(th); break; } } /* If all threads have exited and the main thread is pending on a pthread_exit, wake up the main thread and terminate ourselves. */ if (main_thread_exiting && __pthread_main_thread->p_nextlive == __pthread_main_thread) { restart(__pthread_main_thread); /* Same logic as REQ_MAIN_THREAD_EXIT. */ } }
static void pthread_handle_free(pthread_t th_id) { pthread_handle handle = thread_handle(th_id); pthread_descr th; __pthread_lock(&handle->h_lock, NULL); if (invalid_handle(handle, th_id)) { /* pthread_reap_children has deallocated the thread already, nothing needs to be done */ __pthread_unlock(&handle->h_lock); return; } th = handle->h_descr; if (th->p_exited) { __pthread_unlock(&handle->h_lock); pthread_free(th); } else { /* The Unix process of the thread is still running. Mark the thread as detached so that the thread manager will deallocate its resources when the Unix process exits. */ th->p_detached = 1; __pthread_unlock(&handle->h_lock); } }