#include <kern/spl.h>
#include <kern/syscall_subr.h>
#include <kern/sync_lock.h>
-#include <kern/sf.h>
#include <kern/mk_sp.h> /*** ??? fix so this can be removed ***/
+#include <kern/processor.h>
#include <mach_prof.h>
#include <mach/rpc.h>
* 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);
}
{
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);
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);
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);
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);
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.
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);
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