void pthread_exit(void *retval) { /* Get all we need from the tdb before releasing it. */ nc_thread_descriptor_t *tdb = nc_get_tdb(); nc_thread_memory_block_t *stack_node = tdb->stack_node; int32_t *is_used = &stack_node->is_used; nc_basic_thread_data_t *basic_data = tdb->basic_data; int joinable = tdb->joinable; /* Call cleanup handlers. */ while (NULL != __nc_cleanup_handlers) { pthread_cleanup_pop(1); } /* Call the destruction functions for TSD. */ __nc_tsd_exit(); __newlib_thread_exit(); __nc_futex_thread_exit(); if (__nc_initial_thread_id != basic_data) { pthread_mutex_lock(&__nc_thread_management_lock); --__nc_running_threads_counter; pthread_mutex_unlock(&__nc_thread_management_lock); } else { /* This is the main thread - wait for other threads to complete. */ wait_for_threads(); exit(0); } pthread_mutex_lock(&__nc_thread_management_lock); basic_data->retval = retval; if (joinable) { /* If somebody is waiting for this thread, signal. */ basic_data->status = THREAD_TERMINATED; pthread_cond_signal(&basic_data->join_condvar); } /* * We can release TLS+TDB - thread id and its return value are still * kept in basic_data. */ nc_release_tls_node(tdb->tls_node, tdb); if (!joinable) { nc_release_basic_data_mu(basic_data); } /* Now add the stack to the list but keep it marked as used. */ nc_free_memory_block_mu(THREAD_STACK_MEMORY, stack_node); if (1 == __nc_running_threads_counter) { pthread_cond_signal(&__nc_last_thread_cond); } pthread_mutex_unlock(&__nc_thread_management_lock); irt_thread.thread_exit(is_used); nc_abort(); }
int __pthread_shutdown() { /* No shutdown is required when pthread library is not used */ __newlib_thread_exit(); return 0; }