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