示例#1
0
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();
}
示例#2
0
int __pthread_shutdown() {
  /* No shutdown is required when pthread library is not used */
  __newlib_thread_exit();
  return 0;
}