/*! * End current thread (exit from it) * \param status Exit status number */ int sys__thread_exit ( void *p ) { int status; status = *( (int *) p ); active_thread->state = THR_STATE_PASSIVE; active_thread->ref_cnt--; active_thread->exit_status = status; #ifdef MESSAGES k_msgq_clean ( &active_thread->msg.msgq ); #endif /* release thread stack */ if ( active_thread->stack ) kfree ( active_thread->stack ); k_delete_thread_private_storage ( active_thread, active_thread->private_storage ); if ( !active_thread->ref_cnt ) { k_remove_thread_descriptor ( active_thread ); active_thread = NULL; } else { k_release_all_threads ( &active_thread->join_queue ); } k_schedule_threads (); return 0; }
/*! * Wait for thread termination * \param thread Thread descriptor (user level descriptor) * \param wait Wait if thread not finished (!=0) or not (0)? * \return 0 if thread already gone; -1 if not finished and 'wait' not set; * 'thread exit status' otherwise */ int sys__wait_for_thread ( void *p ) { thread_t *thread; int wait; kthread_t *kthr; int ret_value = 0; thread = U2K_GET_ADR ( *( (void **) p ), active_thread->proc ); p += sizeof (void *); wait = *( (int *) p ); ASSERT_ERRNO_AND_EXIT ( thread && thread->thread, E_INVALID_HANDLE ); kthr = thread->thread; if ( kthr->id != thread->thr_id ) /* at 'kthr' is now something else */ { ret_value = -SUCCESS; SET_ERRNO ( SUCCESS ); } else if ( kthr->state != THR_STATE_PASSIVE && !wait ) { ret_value = -E_NOT_FINISHED; SET_ERRNO ( E_NOT_FINISHED ); } else if ( kthr->state != THR_STATE_PASSIVE ) { kthr->ref_cnt++; ret_value = -E_RETRY; /* retry (collect thread status) */ SET_ERRNO ( E_RETRY ); k_enqueue_thread ( NULL, &kthr->join_queue ); k_schedule_threads (); } else { /* kthr->state == THR_STATE_PASSIVE, but thread descriptor still not freed - some thread still must collect its status */ SET_ERRNO ( SUCCESS ); ret_value = kthr->exit_status; kthr->ref_cnt--; if ( !kthr->ref_cnt ) k_remove_thread_descriptor ( kthr ); } return ret_value; }
/*! * End current thread (exit from it) * \param status Exit status number */ int sys__thread_exit ( void *p ) { int status; status = *( (int *) p ); active_thread->state = THR_STATE_PASSIVE; active_thread->ref_cnt--; active_thread->exit_status = status; active_thread->proc->thr_count--; #ifdef MESSAGES k_msgq_clean ( &active_thread->msg.msgq ); #endif /* release thread stack */ if ( active_thread->stack ) { if ( active_thread->proc->m.start ) /* user level thread */ ffs_free ( active_thread->proc->stack_pool, active_thread->stack ); else /* kernel level thread */ kfree ( active_thread->stack ); } k_delete_thread_private_storage ( active_thread, active_thread->private_storage ); if ( active_thread->proc->thr_count == 0 && active_thread->proc->pi ) { /* last (non-kernel) thread - remove process */ ASSERT ( list_remove ( &procs, FIRST, &active_thread->proc->all ) ); active_thread->proc->prog->started = FALSE; kfree ( active_thread->proc ); } if ( !active_thread->ref_cnt ) { k_remove_thread_descriptor ( active_thread ); active_thread = NULL; } else { k_release_all_threads ( &active_thread->join_queue ); } k_schedule_threads (); return 0; }