X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/e7c99d92bf4e4d1189c904195ed317951f9a35ad..0b4e3aa066abc0728aacb4bbeb86f53f9737156e:/osfmk/kern/thread_act.c?ds=sidebyside diff --git a/osfmk/kern/thread_act.c b/osfmk/kern/thread_act.c index 9a97f50a6..4320b05dd 100644 --- a/osfmk/kern/thread_act.c +++ b/osfmk/kern/thread_act.c @@ -68,8 +68,8 @@ #include #include #include -#include #include /*** ??? fix so this can be removed ***/ +#include #include #include @@ -194,9 +194,10 @@ thread_terminate( * code - and all threads finish their own termination in the * special handler APC. */ - if (((thr_act->task == kernel_task) || (thr_act->kernel_loaded == TRUE)) - && (current_act() == thr_act)) { - ast_taken(FALSE, AST_APC, 0); + if ( ( thr_act->task == kernel_task || + thr_act->kernel_loaded == TRUE ) && + current_act() == thr_act ) { + ast_taken(AST_APC, FALSE); panic("thread_terminate(): returning from ast_taken() for %x kernel activation\n", thr_act); } @@ -347,8 +348,6 @@ thread_depress_abort( { register thread_t thread; kern_return_t result; - sched_policy_t *policy; - spl_t s; if (thr_act == THR_ACT_NULL) return (KERN_INVALID_ARGUMENT); @@ -361,13 +360,7 @@ thread_depress_abort( return (KERN_TERMINATED); } - s = splsched(); - thread_lock(thread); - policy = &sched_policy[thread->policy]; - thread_unlock(thread); - splx(s); - - result = policy->sp_ops.sp_thread_depress_abort(policy, thread); + result = _mk_sp_thread_depress_abort(thread, FALSE); act_unlock_thread(thr_act); @@ -732,11 +725,7 @@ thread_get_state( kern_return_t ret; thread_t thread, nthread; -#if 0 /* Grenoble - why?? */ if (thr_act == THR_ACT_NULL || thr_act == current_act()) -#else - if (thr_act == THR_ACT_NULL) -#endif return (KERN_INVALID_ARGUMENT); thread = act_lock_thread(thr_act); @@ -747,7 +736,7 @@ thread_get_state( thread_hold(thr_act); while (1) { - if (!thread || thr_act != thread->top_act) + if (!thread || thr_act != thread->top_act) break; act_unlock_thread(thr_act); (void)thread_stop_wait(thread); @@ -781,11 +770,7 @@ thread_set_state( kern_return_t ret; thread_t thread, nthread; -#if 0 /* Grenoble - why?? */ if (thr_act == THR_ACT_NULL || thr_act == current_act()) -#else - if (thr_act == THR_ACT_NULL) -#endif return (KERN_INVALID_ARGUMENT); /* * We have no kernel activations, so Utah's MO fails for signals etc. @@ -802,7 +787,7 @@ thread_set_state( thread_hold(thr_act); while (1) { - if (!thread || thr_act != thread->top_act) + if (!thread || thr_act != thread->top_act) break; act_unlock_thread(thr_act); (void)thread_stop_wait(thread); @@ -2225,12 +2210,34 @@ act_get_state(thread_act_t thr_act, int flavor, thread_state_t state, void act_set_apc(thread_act_t thr_act) { + + processor_t prssr; + thread_t thread; + + mp_disable_preemption(); + thread_ast_set(thr_act, AST_APC); if (thr_act == current_act()) { - mp_disable_preemption(); ast_propagate(thr_act->ast); mp_enable_preemption(); + return; /* If we are current act, we can't be on the other processor so leave now */ } + +/* + * Here we want to make sure that the apc is taken quickly. Therefore, we check + * if, and where, the activation is running. If it is not running, we don't need to do + * anything. If it is, we need to signal the other processor to trigger it to + * check the asts. Note that there is a race here and we may end up sending a signal + * after the thread has been switched off. Hopefully this is no big deal. + */ + + thread = thr_act->thread; /* Get the thread for the signaled activation */ + prssr = thread->last_processor; /* get the processor it was last on */ + if(prssr && (cpu_data[prssr->slot_num].active_thread == thread)) { /* Is the thread active on its processor? */ + cause_ast_check(prssr); /* Yes, kick it */ + } + + mp_enable_preemption(); } void