- * Kernel-internal thread_activation interfaces used outside this file:
- */
-
-void
-act_reference(
- thread_act_t act)
-{
- if (act == NULL)
- return;
-
- act_lock(act);
- act_reference_locked(act);
- act_unlock(act);
-}
-
-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 *ut = act->uthread;
-
- act->uthread = NULL;
- uthread_free(task, ut, task_proc);
- }
-#endif /* MACH_BSD */
-
- task_deallocate(task);
-
- thread_deallocate(thread);
-}
-
-
-/*
- * act_attach - Attach an thr_act to the top of a thread ("push the stack").
- *
- * The thread_shuttle must be either the current one or a brand-new one.
- * Assumes the thr_act is active but not in use.
- *
- * Already locked: thr_act plus "appropriate" thread-related locks
- * (see act_lock_thread()).
- */
-void
-act_attach(
- thread_act_t act,
- thread_t thread)
-{
- thread_act_t lower;
-
- /*
- * Chain the act onto the thread's act stack.
- */
- act->act_ref_count++;
- act->thread = thread;
- act->higher = THR_ACT_NULL;
- lower = act->lower = thread->top_act;
- if (lower != THR_ACT_NULL)
- lower->higher = act;
-
- thread->top_act = act;
-}
-
-/*
- * act_detach
- *
- * Remove the current thr_act from the top of the current thread, i.e.
- * "pop the stack". Assumes already locked: thr_act plus "appropriate"
- * thread-related locks (see act_lock_thread).
- */
-void
-act_detach(
- thread_act_t cur_act)
-{
- thread_t cur_thread = cur_act->thread;
-
- /* Unlink the thr_act from the thread's thr_act stack */
- cur_thread->top_act = cur_act->lower;
- cur_act->thread = 0;
- cur_act->act_ref_count--;
- assert(cur_act->act_ref_count > 0);
-
-#if MACH_ASSERT
- cur_act->lower = cur_act->higher = THR_ACT_NULL;
- if (cur_thread->top_act)
- cur_thread->top_act->higher = THR_ACT_NULL;
-#endif /* MACH_ASSERT */
-
- return;
-}
-
-
-/*
- * Synchronize a thread operation with migration.
- * Called with nothing locked.
- * Returns with thr_act locked.
- */
-thread_t
-act_lock_thread(
- thread_act_t thr_act)
-{
-
- /*
- * JMM - We have moved away from explicit RPC locks
- * and towards a generic migration approach. The wait
- * queue lock will be the point of synchronization for
- * the shuttle linkage when this is rolled out. Until
- * then, just lock the act.
- */
- act_lock(thr_act);
- return (thr_act->thread);
-}
-
-/*
- * Unsynchronize with migration (i.e., undo an act_lock_thread() call).
- * Called with thr_act locked, plus thread locks held that are
- * "correct" for thr_act's state. Returns with nothing locked.
- */
-void
-act_unlock_thread(thread_act_t thr_act)
-{
- act_unlock(thr_act);
-}
-
-/*
- * Synchronize with migration given a pointer to a shuttle (instead of an
- * activation). Called with nothing locked; returns with all
- * "appropriate" thread-related locks held (see act_lock_thread()).
- */
-thread_act_t
-thread_lock_act(
- thread_t thread)
-{
- thread_act_t thr_act;
-
- while (1) {
- thr_act = thread->top_act;
- if (!thr_act)
- break;
- if (!act_lock_try(thr_act)) {
- mutex_pause();
- continue;
- }
- break;
- }
- return (thr_act);
-}
-
-/*
- * Unsynchronize with an activation starting from a pointer to
- * a shuttle.
- */
-void
-thread_unlock_act(
- thread_t thread)
-{
- thread_act_t thr_act;
-
- if (thr_act = thread->top_act) {
- act_unlock(thr_act);
- }
-}
-
-/*
- * switch_act