/* * special_handler - handles suspension, termination. Called * with nothing locked. Returns (if it returns) the same way. */ void special_handler( thread_t thread) { spl_t s; thread_mtx_lock(thread); s = splsched(); thread_lock(thread); thread->sched_flags &= ~TH_SFLAG_ABORTED_MASK; thread_unlock(thread); splx(s); /* * If we're suspended, go to sleep and wait for someone to wake us up. */ if (thread->active) { if (thread->suspend_count > 0) { assert_wait(&thread->suspend_count, THREAD_ABORTSAFE); thread_mtx_unlock(thread); thread_block((thread_continue_t)special_handler_continue); /*NOTREACHED*/ } } else { thread_mtx_unlock(thread); thread_terminate_self(); /*NOTREACHED*/ } thread_mtx_unlock(thread); }
/* * thread_apc_ast - handles AST_APC and drives thread suspension and termination. * Called with nothing locked. Returns (if it returns) the same way. */ void thread_apc_ast(thread_t thread) { thread_mtx_lock(thread); assert(thread->suspend_parked == FALSE); spl_t s = splsched(); thread_lock(thread); /* TH_SFLAG_POLLDEPRESS is OK to have here */ assert((thread->sched_flags & TH_SFLAG_DEPRESS) == 0); thread->sched_flags &= ~TH_SFLAG_ABORTED_MASK; thread_unlock(thread); splx(s); if (!thread->active) { /* Thread is ready to terminate, time to tear it down */ thread_mtx_unlock(thread); thread_terminate_self(); /*NOTREACHED*/ } /* If we're suspended, go to sleep and wait for someone to wake us up. */ if (thread->suspend_count > 0) { thread->suspend_parked = TRUE; assert_wait(&thread->suspend_count, THREAD_ABORTSAFE); thread_mtx_unlock(thread); thread_block(thread_suspended); /*NOTREACHED*/ } thread_mtx_unlock(thread); }