diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2017-11-13 23:52:50 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2017-11-13 23:52:50 +0000 |
commit | 6c5f54722f550753f917210df006a811ceb4ea04 (patch) | |
tree | f3db16e28c25f134a7ce5d3736e6d508c89fe935 | |
parent | 0731ebd7182102756256999a6ec042c57581d190 (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.9 | 18 | ||||
-rw-r--r-- | sys/kern/kern_task.c | 28 | ||||
-rw-r--r-- | sys/sys/task.h | 3 |
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, ¬done); + + task_add(tq, &t); + + while (notdone) { + sleep_setup(&sls, ¬done, 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 *); |