1.\" $NetBSD: condvar.9,v 1.21 2019/12/12 02:34:55 pgoyette Exp $ 2.\" 3.\" Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Andrew Doran. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd December 12, 2019 31.Dt CONDVAR 9 32.Os 33.Sh NAME 34.Nm cv , 35.Nm condvar , 36.Nm cv_init , 37.Nm cv_destroy , 38.Nm cv_wait , 39.Nm cv_wait_sig , 40.Nm cv_timedwait , 41.Nm cv_timedwait_sig , 42.Nm cv_timedwaitbt , 43.Nm cv_timedwaitbt_sig , 44.Nm cv_signal , 45.Nm cv_broadcast , 46.Nm cv_has_waiters 47.Nd condition variables 48.Sh SYNOPSIS 49.In sys/condvar.h 50.Ft void 51.Fn cv_init "kcondvar_t *cv" "const char *wmesg" 52.Ft void 53.Fn cv_destroy "kcondvar_t *cv" 54.Ft void 55.Fn cv_wait "kcondvar_t *cv" "kmutex_t *mtx" 56.Ft int 57.Fn cv_wait_sig "kcondvar_t *cv" "kmutex_t *mtx" 58.Ft int 59.Fn cv_timedwait "kcondvar_t *cv" "kmutex_t *mtx" "int ticks" 60.Ft int 61.Fn cv_timedwait_sig "kcondvar_t *cv" "kmutex_t *mtx" "int ticks" 62.Ft int 63.Fn cv_timedwaitbt "kcondvar_t *cv" "kmutex_t *mtx" "struct bintime *bt" \ 64"const struct bintime *epsilon" 65.Ft int 66.Fn cv_timedwaitbt_sig "kcondvar_t *cv" "kmutex_t *mtx" "struct bintime *bt" \ 67"const struct bintime *epsilon" 68.Ft void 69.Fn cv_signal "kcondvar_t *cv" 70.Ft void 71.Fn cv_broadcast "kcondvar_t *cv" 72.Ft bool 73.Fn cv_has_waiters "kcondvar_t *cv" 74.Pp 75.Cd "options DIAGNOSTIC" 76.Cd "options LOCKDEBUG" 77.Sh DESCRIPTION 78Condition variables (CVs) are used in the kernel to synchronize access 79to resources that are limited (for example, memory) and to wait for 80pending I/O operations to complete. 81.Pp 82The 83.Vt kcondvar_t 84type provides storage for the CV object. 85This should be treated as an opaque object and not examined directly by 86consumers. 87.Sh OPTIONS 88.Bl -tag -width abcd 89.It Cd "options DIAGNOSTIC" 90.Pp 91Kernels compiled with the 92.Dv DIAGNOSTIC 93option perform basic sanity checks on CV operations. 94.It Cd "options LOCKDEBUG" 95.Pp 96Kernels compiled with the 97.Dv LOCKDEBUG 98option perform potentially CPU intensive sanity checks 99on CV operations. 100.El 101.Sh FUNCTIONS 102.Bl -tag -width abcd 103.It Fn cv_init "cv" "wmesg" 104.Pp 105Initialize a CV for use. 106No other operations can be performed on the CV until it has been initialized. 107.Pp 108The 109.Fa wmesg 110argument specifies a string of no more than 8 characters that describes 111the resource or condition associated with the CV. 112The kernel does not use this argument directly but makes it available for 113utilities such as 114.Xr ps 1 115to display. 116.It Fn cv_destroy "cv" 117.Pp 118Release resources used by a CV. 119The CV must not be in use when it is destroyed, and must not be used afterwards. 120.It Fn cv_wait "cv" "mtx" 121.Pp 122Cause the current LWP to wait non-interruptably for access to a resource, 123or for an I/O operation to complete. 124The LWP will resume execution when awoken by another thread using 125.Fn cv_signal 126or 127.Fn cv_broadcast . 128.Pp 129.Fa mtx 130specifies a kernel mutex to be used as an interlock, and must be held by the 131calling LWP on entry to 132.Fn cv_wait . 133It will be released once the LWP has prepared to sleep, and will be reacquired 134before 135.Fn cv_wait 136returns. 137.Pp 138A small window exists between testing for availability of a resource and 139waiting for the resource with 140.Fn cv_wait , 141in which the resource may become available again. 142The interlock is used to guarantee that the resource will not be signalled 143as available until the calling LWP has begun to wait for it. 144.Pp 145Non-interruptable waits have the potential to deadlock the system, and so must 146be kept short (typically, under one second). 147.Pp 148Upon being awakened, the calling LWP should verify the availability 149of the resource (or other condition). 150It should not blindly assume that the resource is now available. 151If the resource is still not available, the calling LWP may call 152.Fn cv_wait 153again to continue waiting. 154.It Fn cv_wait_sig "cv" "mtx" 155.Pp 156As per 157.Fn cv_wait , 158but causes the current LWP to wait interruptably. 159If the LWP receives a signal, or is interrupted by another condition such 160as its containing process exiting, the wait is ended early and an error 161code returned. 162.Pp 163If 164.Fn cv_wait_sig 165returns as a result of a signal, the return value is 166.Er ERESTART 167if the signal 168has the 169.Dv SA_RESTART 170property. 171If awoken normally, the value is zero, and 172.Er EINTR 173under all other conditions. 174.It Fn cv_timedwait "cv" "mtx" "ticks" 175.Pp 176As per 177.Fn cv_wait , 178but will return early if a timeout specified by the 179.Fa ticks 180argument expires. 181.Pp 182.Fa ticks 183is an architecture and system dependent value related to the number of 184clock interrupts per second. 185See 186.Xr hz 9 187for details. 188The 189.Xr mstohz 9 190macro can be used to convert a timeout expressed in milliseconds to 191one suitable for 192.Fn cv_timedwait . 193If the 194.Fa ticks 195argument is zero, 196.Fn cv_timedwait 197behaves exactly like 198.Fn cv_wait . 199.Pp 200If the timeout expires before the LWP is awoken, the return value is 201.Er EWOULDBLOCK . 202If awoken normally, the return value is zero. 203.It Fn cv_timedwait_sig "cv" "mtx" "ticks" 204.Pp 205As per 206.Fn cv_wait_sig , 207but also accepts a timeout value and will return 208.Er EWOULDBLOCK 209if the timeout expires. 210.It Fn cv_timedwaitbt "cv" "mtx" "bt" "epsilon" 211.It Fn cv_timedwaitbt_sig "cv" "mtx" "bt" "epsilon" 212.Pp 213Similar to 214.Fn cv_timedwait 215and 216.Fn cv_timedwait_sig , 217but 218.Fa bt 219is decremented in place with the amount of time actually waited, and on 220return contains the amount of time remaining, possibly negative if the 221timeout expired. 222.Pp 223The hint 224.Fa epsilon 225requests that the wakeup not be delayed more than 226.Fa bt Li "+" Fa epsilon , 227so that the system can coalesce multiple wakeups within their 228respective epsilons into a single high-resolution clock interrupt or 229choose to use cheaper low-resolution clock interrupts instead. 230.Pp 231However, the system is still limited by its best clock interrupt 232resolution and by scheduling competition, which may delay the wakeup by 233more than 234.Fa bt Li "+" Fa epsilon . 235.It Fn cv_signal "cv" 236.Pp 237Awaken one LWP (potentially among many) that is waiting on the specified 238condition variable. 239The mutex passed to the wait function 240.Po Fa mtx Pc 241must also be held when calling 242.Fn cv_signal . 243.Pp 244(Note that 245.Fn cv_signal 246is erroneously named in that it does not send a signal in the traditional 247sense to LWPs waiting on a CV.) 248.It Fn cv_broadcast "cv" 249.Pp 250Awaken all LWPs waiting on the specified condition variable. 251The mutex passed to the wait function 252.Po Fa mtx Pc 253must also be held when calling 254.Fn cv_broadcast . 255.It Fn cv_has_waiters "cv" 256.Pp 257Return 258.Dv true 259if one or more LWPs are waiting on the specified condition variable. 260.Pp 261.Fn cv_has_waiters 262cannot test reliably for interruptable waits. 263It should only be used to test for non-interruptable waits 264made using 265.Fn cv_wait . 266.Pp 267.Fn cv_has_waiters 268should only be used when making diagnostic assertions, and must 269be called while holding the interlocking mutex passed to 270.Fn cv_wait . 271.El 272.Sh EXAMPLES 273Consuming a resource: 274.Bd -literal 275 /* 276 * Lock the resource. Its mutex will also serve as the 277 * interlock. 278 */ 279 mutex_enter(&res->mutex); 280 281 /* 282 * Wait for the resource to become available. Timeout after 283 * five seconds. If the resource is not available within the 284 * alloted time, return an error. 285 */ 286 struct bintime timeout = { .sec = 5, .frac = 0 }; 287 const struct bintime epsilon = { .sec = 1, .frac = 0 }; 288 while (res->state == BUSY) { 289 error = cv_timedwaitbt(&res->condvar, \\ 290 &res->mutex, &timeout, &epsilon); 291 if (error) { 292 KASSERT(error == EWOULDBLOCK); 293 if (res->state != BUSY) 294 break; 295 mutex_exit(&res->mutex); 296 return ETIMEDOUT; 297 } 298 } 299 300 /* 301 * It's now available to us. Take ownership of the 302 * resource, and consume it. 303 */ 304 res->state = BUSY; 305 mutex_exit(&res->mutex); 306 consume(res); 307.Ed 308.Pp 309Releasing a resource for the next consumer to use: 310.Bd -literal 311 mutex_enter(&res->mutex); 312 res->state = IDLE; 313 cv_signal(&res->condvar); 314 mutex_exit(&res->mutex); 315.Ed 316.Sh CODE REFERENCES 317The core of the CV implementation is in 318.Pa sys/kern/kern_condvar.c . 319.Pp 320The header file 321.Pa sys/sys/condvar.h 322describes the public interface. 323.Sh SEE ALSO 324.Xr sigaction 2 , 325.Xr membar_ops 3 , 326.Xr errno 9 , 327.Xr mstohz 9 , 328.Xr mutex 9 , 329.Xr rwlock 9 330.Pp 331.Rs 332.%A Jim Mauro 333.%A Richard McDougall 334.%T Solaris Internals: Core Kernel Architecture 335.%I Prentice Hall 336.%D 2001 337.%O ISBN 0-13-022496-0 338.Re 339.Sh HISTORY 340The CV primitives first appeared in 341.Nx 5.0 . 342The 343.Fn cv_timedwaitbt 344and 345.Fn cv_timedwaitbt_sig 346primitives first appeared in 347.Nx 9.0 . 348