summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2017-11-13 23:52:50 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2017-11-13 23:52:50 +0000
commit6c5f54722f550753f917210df006a811ceb4ea04 (patch)
treef3db16e28c25f134a7ce5d3736e6d508c89fe935
parent0731ebd7182102756256999a6ec042c57581d190 (diff)
add taskq_barrier
taskq_barrier guarantees that any task that was running on the taskq has finished by the time taskq_barrier returns. it is similar to intr_barrier. this is needed for use in ifq_barrier as part of an upcoming change.
-rw-r--r--share/man/man9/task_add.918
-rw-r--r--sys/kern/kern_task.c28
-rw-r--r--sys/sys/task.h3
3 files changed, 45 insertions, 4 deletions
diff --git a/share/man/man9/task_add.9 b/share/man/man9/task_add.9
index 2c50292d4a5..64a68738952 100644
--- a/share/man/man9/task_add.9
+++ b/share/man/man9/task_add.9
@@ -1,4 +1,4 @@
-.\" $OpenBSD: task_add.9,v 1.16 2015/09/14 15:14:55 schwarze Exp $
+.\" $OpenBSD: task_add.9,v 1.17 2017/11/13 23:52:49 dlg Exp $
.\"
.\" Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
.\"
@@ -14,12 +14,13 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 14 2015 $
+.Dd $Mdocdate: November 13 2017 $
.Dt TASK_ADD 9
.Os
.Sh NAME
.Nm taskq_create ,
.Nm taskq_destroy ,
+.Nm taskq_barrier ,
.Nm task_set ,
.Nm task_add ,
.Nm task_del ,
@@ -37,6 +38,8 @@
.Ft void
.Fn taskq_destroy "struct taskq *tq"
.Ft void
+.Fn taskq_barrier "struct taskq *tq"
+.Ft void
.Fn task_set "struct task *t" "void (*fn)(void *)" "void *arg"
.Ft int
.Fn task_add "struct taskq *tq" "struct task *t"
@@ -88,6 +91,15 @@ Calling
against the system taskq is an error and will lead to undefined
behaviour or a system fault.
.Pp
+.Fn taskq_barrier
+guarantees that any task that was running on the
+.Fa tq
+taskq when the barrier was called has finished by the time the barrier
+returns.
+.Fn taskq_barrier
+is only supported on taskqs serviced by 1 thread,
+and may not be called by a task running in the specified taskq.
+.Pp
It is the responsibility of the caller to provide the
.Fn task_set ,
.Fn task_add ,
@@ -163,6 +175,8 @@ argument given in
and
.Fn taskq_destroy
can be called during autoconf, or from process context.
+.Fn taskq_barrier
+can be called from process context.
.Fn task_set ,
.Fn task_add ,
and
diff --git a/sys/kern/kern_task.c b/sys/kern/kern_task.c
index cd7e2a436f4..feaa7bed5cd 100644
--- a/sys/kern/kern_task.c
+++ b/sys/kern/kern_task.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_task.c,v 1.20 2017/10/30 14:01:42 visa Exp $ */
+/* $OpenBSD: kern_task.c,v 1.21 2017/11/13 23:52:49 dlg Exp $ */
/*
* Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
@@ -22,6 +22,7 @@
#include <sys/mutex.h>
#include <sys/kthread.h>
#include <sys/task.h>
+#include <sys/proc.h>
#define TASK_ONQUEUE 1
@@ -68,6 +69,7 @@ struct taskq *const systqmp = &taskq_sys_mp;
void taskq_init(void); /* called in init_main.c */
void taskq_create_thread(void *);
+void taskq_barrier_task(void *);
int taskq_sleep(const volatile void *, struct mutex *, int,
const char *, int);
int taskq_next_work(struct taskq *, struct task *, sleepfn);
@@ -179,6 +181,30 @@ taskq_create_thread(void *arg)
}
void
+taskq_barrier(struct taskq *tq)
+{
+ struct sleep_state sls;
+ unsigned int notdone = 1;
+ struct task t = TASK_INITIALIZER(taskq_barrier_task, &notdone);
+
+ task_add(tq, &t);
+
+ while (notdone) {
+ sleep_setup(&sls, &notdone, PWAIT, "tqbar");
+ sleep_finish(&sls, notdone);
+ }
+}
+
+void
+taskq_barrier_task(void *p)
+{
+ unsigned int *notdone = p;
+
+ *notdone = 0;
+ wakeup_one(notdone);
+}
+
+void
task_set(struct task *t, void (*fn)(void *), void *arg)
{
t->t_func = fn;
diff --git a/sys/sys/task.h b/sys/sys/task.h
index 1db033a0f0c..f7385ca0cfd 100644
--- a/sys/sys/task.h
+++ b/sys/sys/task.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: task.h,v 1.11 2016/06/07 07:53:33 mpi Exp $ */
+/* $OpenBSD: task.h,v 1.12 2017/11/13 23:52:49 dlg Exp $ */
/*
* Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
@@ -43,6 +43,7 @@ extern struct taskq *const systqmp;
struct taskq *taskq_create(const char *, unsigned int, int, unsigned int);
void taskq_destroy(struct taskq *);
+void taskq_barrier(struct taskq *);
void task_set(struct task *, void (*)(void *), void *);
int task_add(struct taskq *, struct task *);