1*64d14765Svisa.\" $OpenBSD: cond_init.9,v 1.3 2022/03/11 14:42:08 visa Exp $ */ 20d158b2bSdlg.\" 30d158b2bSdlg.\" Copyright (c) 2017 David Gwynne <dlg@openbsd.org> 40d158b2bSdlg.\" 50d158b2bSdlg.\" Permission to use, copy, modify, and distribute this software for any 60d158b2bSdlg.\" purpose with or without fee is hereby granted, provided that the above 70d158b2bSdlg.\" copyright notice and this permission notice appear in all copies. 80d158b2bSdlg.\" 90d158b2bSdlg.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 100d158b2bSdlg.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 110d158b2bSdlg.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 120d158b2bSdlg.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 130d158b2bSdlg.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 140d158b2bSdlg.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 150d158b2bSdlg.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 160d158b2bSdlg.\" 17*64d14765Svisa.Dd $Mdocdate: March 11 2022 $ 180d158b2bSdlg.Dt COND_INIT 9 190d158b2bSdlg.Os 200d158b2bSdlg.Sh NAME 210d158b2bSdlg.Nm cond_init , 220d158b2bSdlg.Nm cond_wait , 230d158b2bSdlg.Nm cond_signal , 240d158b2bSdlg.Nm COND_INITIALIZER 250d158b2bSdlg.Nd wait condition API 260d158b2bSdlg.Sh SYNOPSIS 270d158b2bSdlg.In sys/systm.h 280d158b2bSdlg.Ft void 290d158b2bSdlg.Fn "cond_init" "struct cond *c" 300d158b2bSdlg.Ft void 310d158b2bSdlg.Fn "cond_wait" "struct cond *c" "const char *wmesg" 320d158b2bSdlg.Ft void 330d158b2bSdlg.Fn "cond_signal" "struct cond *c" 340d158b2bSdlg.Fn "COND_INITIALIZER" 350d158b2bSdlg.Sh DESCRIPTION 360d158b2bSdlgThe wait condition API allows a thread to sleep while it waits for 370d158b2bSdlga notification, aka signal, that pending work has completed. 380d158b2bSdlg.Pp 390d158b2bSdlg.Fn cond_init 400d158b2bSdlginitialises the wait condition 410d158b2bSdlg.Fa c 420d158b2bSdlgfor use. 430d158b2bSdlg.Pp 440d158b2bSdlg.Fn cond_wait 450d158b2bSdlgis used to sleep on the wait condition 460d158b2bSdlg.Fa c 470d158b2bSdlguntil whatever the thread is waiting on calls 48*64d14765Svisa.Fn cond_signal . 490d158b2bSdlg.Fa wmesg 500d158b2bSdlgis a pointer to a character string indicating the reason the thread 510d158b2bSdlgis sleeping. 520d158b2bSdlg.Pp 53*64d14765Svisa.Fn cond_signal 540d158b2bSdlgis used to notify the thread waiting on 550d158b2bSdlg.Fa c 560d158b2bSdlgthat the work has finished and it may proceed. 570d158b2bSdlg.Pp 580d158b2bSdlg.Fn COND_INITIALIZER 590d158b2bSdlginitialises a declaration of a cond for use. 600d158b2bSdlg.Sh CONTEXT 610d158b2bSdlg.Fn cond_init , 620d158b2bSdlgand 630d158b2bSdlg.Fn cond_signal 640d158b2bSdlgcan be called during autoconf, from process context, or from interrupt 650d158b2bSdlgcontext. 660d158b2bSdlg.Pp 670d158b2bSdlg.Fn cond_wait 680d158b2bSdlgcan be called from process context. 690d158b2bSdlg.Sh EXAMPLES 700d158b2bSdlg.Xr taskq_barrier 9 710d158b2bSdlgis implemented using the wait condition API. 720d158b2bSdlgThe following is a commented copy of the implementation: 730d158b2bSdlg.Bd -literal 740d158b2bSdlgstatic void taskq_barrier_task(void *); 750d158b2bSdlg 760d158b2bSdlgvoid 770d158b2bSdlgtaskq_barrier(struct taskq *tq) 780d158b2bSdlg{ 790d158b2bSdlg struct cond c; 800d158b2bSdlg struct task t; 810d158b2bSdlg 820d158b2bSdlg /* 830d158b2bSdlg * any currently running work has to have finished 840d158b2bSdlg * before this new task can be run. 850d158b2bSdlg */ 860d158b2bSdlg 870d158b2bSdlg cond_init(&c); 880d158b2bSdlg task_init(&t, taskq_barrier_task, &c); 890d158b2bSdlg 900d158b2bSdlg task_add(tq, &t); 910d158b2bSdlg 920d158b2bSdlg /* wait until the task runs and signals completion */ 930d158b2bSdlg cond_wait(&c, "tqbar"); 940d158b2bSdlg} 950d158b2bSdlg 960d158b2bSdlgstatic void 970d158b2bSdlgtaskq_barrier_task(void *p) 980d158b2bSdlg{ 990d158b2bSdlg struct cond *c = p; 1000d158b2bSdlg 1010d158b2bSdlg /* 1020d158b2bSdlg * all previous tasks have run, signal the thread waiting 1030d158b2bSdlg * in taskq_barrier 1040d158b2bSdlg */ 1050d158b2bSdlg 1060d158b2bSdlg cond_signal(c); 1070d158b2bSdlg} 1080d158b2bSdlg.Ed 109