Module Name: src
Committed By: riastradh
Date: Fri Dec 31 14:22:11 UTC 2021
Modified Files:
src/share/man/man9: sysmon_taskq.9
src/sys/dev/sysmon: sysmon_taskq.c sysmon_taskq.h
Log Message:
sysmon(9): New sysmon_task_queue_barrier(pri) function.
This waits for the completion of all tasks at priority pri or lower
that are currently queued at the time of the call.
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/share/man/man9/sysmon_taskq.9
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/sysmon/sysmon_taskq.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/sysmon/sysmon_taskq.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man9/sysmon_taskq.9
diff -u src/share/man/man9/sysmon_taskq.9:1.8 src/share/man/man9/sysmon_taskq.9:1.9
--- src/share/man/man9/sysmon_taskq.9:1.8 Tue Mar 18 18:20:40 2014
+++ src/share/man/man9/sysmon_taskq.9 Fri Dec 31 14:22:10 2021
@@ -1,4 +1,4 @@
-.\" $NetBSD: sysmon_taskq.9,v 1.8 2014/03/18 18:20:40 riastradh Exp $
+.\" $NetBSD: sysmon_taskq.9,v 1.9 2021/12/31 14:22:10 riastradh Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -43,6 +43,8 @@
.Fn sysmon_task_queue_fini "void"
.Ft int
.Fn sysmon_task_queue_sched "u_int pri" "void (*func)(void *)" "void *arg"
+.Ft void
+.Fn sysmon_task_queue_barrier "u_int pri"
.Sh DESCRIPTION
The machine-independent
.Nm
@@ -67,7 +69,7 @@ All scheduled tasks are executed before
.Pp
The
.Fn sysmon_task_queue_sched
-enqueues
+function enqueues
.Fa func
to be executed at the priority
.Fa pri .
@@ -78,6 +80,12 @@ The single argument passed to
.Fa func
is specified by
.Fa arg .
+.Pp
+The
+.Fn sysmon_task_queue_barrier
+function waits for the completion of all tasks at
+.Fa pri
+or lower currently queued at the time of the call.
.Sh RETURN VALUES
Upon successful completion,
.Fn sysmon_task_queue_sched
Index: src/sys/dev/sysmon/sysmon_taskq.c
diff -u src/sys/dev/sysmon/sysmon_taskq.c:1.21 src/sys/dev/sysmon/sysmon_taskq.c:1.22
--- src/sys/dev/sysmon/sysmon_taskq.c:1.21 Fri Dec 31 11:05:41 2021
+++ src/sys/dev/sysmon/sysmon_taskq.c Fri Dec 31 14:22:11 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_taskq.c,v 1.21 2021/12/31 11:05:41 riastradh Exp $ */
+/* $NetBSD: sysmon_taskq.c,v 1.22 2021/12/31 14:22:11 riastradh Exp $ */
/*
* Copyright (c) 2001, 2003 Wasabi Systems, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.21 2021/12/31 11:05:41 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.22 2021/12/31 14:22:11 riastradh Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@@ -202,6 +202,26 @@ sysmon_task_queue_thread(void *arg)
kthread_exit(0);
}
+static void
+sysmon_task_queue_sched_task(struct sysmon_task *st)
+{
+ struct sysmon_task *lst;
+
+ mutex_enter(&sysmon_task_queue_mtx);
+ TAILQ_FOREACH(lst, &sysmon_task_queue, st_list) {
+ if (st->st_pri > lst->st_pri) {
+ TAILQ_INSERT_BEFORE(lst, st, st_list);
+ break;
+ }
+ }
+
+ if (lst == NULL)
+ TAILQ_INSERT_TAIL(&sysmon_task_queue, st, st_list);
+
+ cv_broadcast(&sysmon_task_queue_cv);
+ mutex_exit(&sysmon_task_queue_mtx);
+}
+
/*
* sysmon_task_queue_sched:
*
@@ -210,7 +230,7 @@ sysmon_task_queue_thread(void *arg)
int
sysmon_task_queue_sched(u_int pri, void (*func)(void *), void *arg)
{
- struct sysmon_task *st, *lst;
+ struct sysmon_task *st;
(void)RUN_ONCE(&once_tq, tq_preinit);
@@ -229,21 +249,62 @@ sysmon_task_queue_sched(u_int pri, void
st->st_arg = arg;
st->st_pri = pri;
- mutex_enter(&sysmon_task_queue_mtx);
- TAILQ_FOREACH(lst, &sysmon_task_queue, st_list) {
- if (st->st_pri > lst->st_pri) {
- TAILQ_INSERT_BEFORE(lst, st, st_list);
- break;
- }
- }
+ sysmon_task_queue_sched_task(st);
- if (lst == NULL)
- TAILQ_INSERT_TAIL(&sysmon_task_queue, st, st_list);
+ return 0;
+}
- cv_broadcast(&sysmon_task_queue_cv);
- mutex_exit(&sysmon_task_queue_mtx);
+struct tqbarrier {
+ kmutex_t lock;
+ kcondvar_t cv;
+ bool done;
+};
- return 0;
+static void
+tqbarrier_task(void *cookie)
+{
+ struct tqbarrier *bar = cookie;
+
+ mutex_enter(&bar->lock);
+ bar->done = true;
+ cv_broadcast(&bar->cv);
+ mutex_exit(&bar->lock);
+}
+
+/*
+ * sysmon_task_queue_barrier:
+ *
+ * Wait for the completion of all tasks at priority pri or lower
+ * currently queued at the time of the call.
+ */
+void
+sysmon_task_queue_barrier(u_int pri)
+{
+ struct sysmon_task st;
+ struct tqbarrier bar;
+
+ (void)RUN_ONCE(&once_tq, tq_preinit);
+
+ KASSERT(sysmon_task_queue_lwp);
+ KASSERT(curlwp != sysmon_task_queue_lwp);
+
+ mutex_init(&bar.lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&bar.cv, "sysmontq");
+ bar.done = false;
+
+ st.st_func = &tqbarrier_task;
+ st.st_arg = &bar;
+ st.st_pri = pri;
+
+ sysmon_task_queue_sched_task(&st);
+
+ mutex_enter(&bar.lock);
+ while (!bar.done)
+ cv_wait(&bar.cv, &bar.lock);
+ mutex_exit(&bar.lock);
+
+ cv_destroy(&bar.cv);
+ mutex_destroy(&bar.lock);
}
static int
Index: src/sys/dev/sysmon/sysmon_taskq.h
diff -u src/sys/dev/sysmon/sysmon_taskq.h:1.4 src/sys/dev/sysmon/sysmon_taskq.h:1.5
--- src/sys/dev/sysmon/sysmon_taskq.h:1.4 Mon Apr 27 07:51:28 2015
+++ src/sys/dev/sysmon/sysmon_taskq.h Fri Dec 31 14:22:11 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_taskq.h,v 1.4 2015/04/27 07:51:28 pgoyette Exp $ */
+/* $NetBSD: sysmon_taskq.h,v 1.5 2021/12/31 14:22:11 riastradh Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -41,5 +41,6 @@
void sysmon_task_queue_init(void);
int sysmon_task_queue_fini(void);
int sysmon_task_queue_sched(u_int, void (*)(void *), void *);
+void sysmon_task_queue_barrier(u_int);
#endif /* _DEV_SYSMON_SYSMON_TASKQ_H_ */