void uthread_exit(int retval) { thread_t *thread; uthread_disable(); thread = current; uthread_notify_exit(thread, retval); if(thread->state != THREAD_ZOMBIE) uthread_free(thread); uthread_alarm_handler(SIGALRM); }
/** * This function is a wrapper to start new threads. It calls start_routine with * arg argument and after the execution finished, update thread_t structure * associated with thread. If no thread called uthread_join before start_routine * finished, then this function makes thread zombie. * * @param thread newly allocated thread_t structure for this thread * @param start_routine main function of new thread * @param arg argument to pass to start_routine when calling it */ void uthread_spawn(thread_t *thread) { int retval; retval = thread->func(thread->arg); uthread_disable(); uthread_notify_exit(thread,retval); if(thread->state != THREAD_ZOMBIE) uthread_free(thread); uthread_alarm_handler(SIGALRM); return; }
int uthread_cancel(thread_id th) { thread_t *thread; uthread_disable(); if(current->id == th) { uthread_exit(UTHREAD_CANCELLED); } thread = uthread_find(th); if(thread == NULL) return UTHREAD_INVALID; uthread_notify_exit(thread, UTHREAD_CANCELLED); if(thread->state != THREAD_ZOMBIE) uthread_free(thread); return UTHREAD_SUCCESS; }
int uthread_join(thread_id th, int* thread_return) { thread_t *thread; uthread_disable(); thread = uthread_find(th); if(thread == NULL) { uthread_enable(); return UTHREAD_INVALID; } if(thread->state == THREAD_ZOMBIE) { *thread_return = thread->retval; uthread_free(thread); uthread_enable(); return UTHREAD_SUCCESS; } thread->waiting_flag = 1; thread->waiting_retval_ptr = thread_return; thread->waiting_thread = current; current->state = THREAD_SUSPENDED; uthread_alarm_handler(SIGALRM); return UTHREAD_SUCCESS; }
void act_deallocate( thread_act_t act) { task_t task; thread_t thread; void *task_proc; if (act == NULL) return; act_lock(act); if (--act->act_ref_count > 0) { act_unlock(act); return; } assert(!act->active); thread = act->thread; assert(thread != NULL); thread->top_act = NULL; act_unlock(act); task = act->task; task_lock(task); task_proc = task->bsd_info; { time_value_t user_time, system_time; thread_read_times(thread, &user_time, &system_time); time_value_add(&task->total_user_time, &user_time); time_value_add(&task->total_system_time, &system_time); queue_remove(&task->threads, act, thread_act_t, task_threads); act->task_threads.next = NULL; task->thread_count--; task->res_thread_count--; } task_unlock(task); act_prof_deallocate(act); ipc_thr_act_terminate(act); #ifdef MACH_BSD { extern void uthread_free(task_t, void *, void *, void *); void *ut = act->uthread; uthread_free(task, act, ut, task_proc); act->uthread = NULL; } #endif /* MACH_BSD */ task_deallocate(task); thread_deallocate(thread); }