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_ */

Reply via email to