diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_sched.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 1382840d3f8..089e9bf7e67 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.36 2015/03/14 03:38:50 jsg Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.37 2015/09/13 11:15:11 kettenis Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org> * @@ -24,6 +24,7 @@ #include <sys/resourcevar.h> #include <sys/signalvar.h> #include <sys/mutex.h> +#include <sys/task.h> #include <uvm/uvm_extern.h> @@ -634,6 +635,50 @@ sched_stop_secondary_cpus(void) } } +void +sched_barrier_task(void *arg) +{ + struct cpu_info *ci = arg; + + sched_peg_curproc(ci); + ci->ci_schedstate.spc_barrier = 1; + wakeup(&ci->ci_schedstate.spc_barrier); + atomic_clearbits_int(&curproc->p_flag, P_CPUPEG); +} + +void +sched_barrier(struct cpu_info *ci) +{ + struct sleep_state sls; + struct task task; + CPU_INFO_ITERATOR cii; + struct schedstate_percpu *spc; + + if (ci == NULL) { + CPU_INFO_FOREACH(cii, ci) { + if (CPU_IS_PRIMARY(ci)) + break; + } + } + KASSERT(ci != NULL); + spc = &ci->ci_schedstate; + + task_set(&task, sched_barrier_task, ci); + spc->spc_barrier = 0; + task_add(systq, &task); + while (!spc->spc_barrier) { + sleep_setup(&sls, &spc->spc_barrier, PWAIT, "sbar"); + sleep_finish(&sls, !spc->spc_barrier); + } +} + +#else + +void +sched_barrier(struct cpu_info *ci) +{ +} + #endif /* |