summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_sched.c47
-rw-r--r--sys/sys/sched.h5
2 files changed, 50 insertions, 2 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
/*
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index 695780ae70a..c7dfaadfd30 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched.h,v 1.38 2015/01/11 19:34:52 guenther Exp $ */
+/* $OpenBSD: sched.h,v 1.39 2015/09/13 11:15:11 kettenis Exp $ */
/* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */
/*-
@@ -114,6 +114,8 @@ struct schedstate_percpu {
struct proc *spc_reaper; /* dead proc reaper */
#endif
LIST_HEAD(,proc) spc_deadproc;
+
+ volatile int spc_barrier; /* for sched_barrier() */
};
#ifdef _KERNEL
@@ -152,6 +154,7 @@ void cpu_idle_enter(void);
void cpu_idle_cycle(void);
void cpu_idle_leave(void);
void sched_peg_curproc(struct cpu_info *ci);
+void sched_barrier(struct cpu_info *ci);
int sysctl_hwsetperf(void *, size_t *, void *, size_t);
int sysctl_hwperfpolicy(void *, size_t *, void *, size_t);