1.\" $NetBSD: condvar.9,v 1.13 2008/08/06 07:08:31 skrll 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 June 4, 2008 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_signal , 43.Nm cv_broadcast , 44.Nm cv_has_waiters 45.Nd condition variables 46.Sh SYNOPSIS 47.In sys/condvar.h 48.Ft void 49.Fn cv_init "kcondvar_t *cv" "const char *wmesg" 50.Ft void 51.Fn cv_destroy "kcondvar_t *cv" 52.Ft void 53.Fn cv_wait "kcondvar_t *cv" "kmutex_t *mtx" 54.Ft int 55.Fn cv_wait_sig "kcondvar_t *cv" "kmutex_t *mtx" 56.Ft int 57.Fn cv_timedwait "kcondvar_t *cv" "kmutex_t *mtx" "int ticks" 58.Ft int 59.Fn cv_timedwait_sig "kcondvar_t *cv" "kmutex_t *mtx" "int ticks" 60.Ft void 61.Fn cv_signal "kcondvar_t *cv" 62.Ft void 63.Fn cv_broadcast "kcondvar_t *cv" 64.Ft bool 65.Fn cv_has_waiters "kcondvar_t *cv" 66.Pp 67.Cd "options DIAGNOSTIC" 68.Cd "options LOCKDEBUG" 69.Sh DESCRIPTION 70Condition variables (CVs) are used in the kernel to synchronize access 71to resources that are limited (for example, memory) and to wait for 72pending I/O operations to complete. 73.Pp 74The 75.Vt kcondvar_t 76type provides storage for the CV object. 77This should be treated as an opaque object and not examined directly by 78consumers. 79.Sh OPTIONS 80.Bl -tag -width abcd 81.It Cd "options DIAGNOSTIC" 82.Pp 83Kernels compiled with the 84.Dv DIAGNOSTIC 85option perform basic sanity checks on CV operations. 86.It Cd "options LOCKDEBUG" 87.Pp 88Kernels compiled with the 89.Dv LOCKDEBUG 90option perform potentially CPU intensive sanity checks 91on CV operations. 92.El 93.Sh FUNCTIONS 94.Bl -tag -width abcd 95.It Fn cv_init "cv" "wmesg" 96.Pp 97Initialize a CV for use. 98No other operations can be performed on the CV until it has been initialized. 99.Pp 100The 101.Fa wmesg 102argument specifies a string of no more than 8 characters that describes 103the resource or condition associated with the CV. 104The kernel does not use this argument directly but makes it available for 105utilities such as 106.Xr ps 1 107to display. 108.It Fn cv_destroy "cv" 109.Pp 110Release resources used by a CV. 111The CV must not be in use when it is destroyed, and must not be used afterwards. 112.It Fn cv_wait "cv" "mtx" 113.Pp 114Cause the current LWP to wait non-interruptably for access to a resource, 115or for an I/O operation to complete. 116The LWP will resume execution when awoken by another thread using 117.Fn cv_signal 118or 119.Fn cv_broadcast . 120.Pp 121.Fa mtx 122specifies a kernel mutex to be used as an interlock, and must be held by the 123calling LWP on entry to 124.Fn cv_wait . 125It will be released once the LWP has prepared to sleep, and will be reacquired 126before 127.Fn cv_wait 128returns. 129.Pp 130A small window exists between testing for availability of a resource and 131waiting for the resource with 132.Fn cv_wait , 133in which the resource may become available again. 134The interlock is used to guarantee that the resource will not be signalled 135as available until the calling LWP has begun to wait for it. 136.Pp 137Non-interruptable waits have the potential to deadlock the system, and so must 138be kept short (typically, under one second). 139.It Fn cv_wait_sig "cv" "mtx" 140.Pp 141As per 142.Fn cv_wait , 143but causes the current LWP to wait interruptably. 144If the LWP receives a signal, or is interrupted by another condition such 145as its containing process exiting, the wait is ended early and an error 146code returned. 147.Pp 148If 149.Fn cv_wait_sig 150returns as a result of a signal, the return value is 151.Er ERESTART 152if the signal 153has the 154.Dv SA_RESTART 155property. 156If awoken normally, the value is zero, and 157.Er EINTR 158under all other conditions. 159.It Fn cv_timedwait "cv" "mtx" "ticks" 160.Pp 161As per 162.Fn cv_wait , 163but will return early if a timeout specified by the 164.Fa ticks 165argument expires. 166.Pp 167.Fa ticks 168is an architecture and system dependent value related to the number of 169clock interrupts per second. 170See 171.Xr hz 9 172for details. 173The 174.Xr mstohz 9 175macro can be used to convert a timeout expressed in milliseconds to 176one suitable for 177.Fn cv_timedwait . 178If the 179.Fa ticks 180argument is zero, 181.Fn cv_timedwait 182behaves exactly like 183.Fn cv_wait . 184.Pp 185If the timeout expires before the LWP is awoken, the return value is 186.Er EWOULDBLOCK . 187If awoken normally, the return value is zero. 188.It Fn cv_timedwait_sig "cv" "mtx" "ticks" 189.Pp 190As per 191.Fn cv_wait_sig , 192but also accepts a timeout value and will return 193.Er EWOULDBLOCK 194if the timeout expires. 195.It Fn cv_signal "cv" 196.Pp 197Awaken one LWP (potentially among many) that is waiting on the specified 198condition variable. 199The mutex passed to the wait function 200.Po Fa mtx Pc 201must also be held when calling 202.Fn cv_signal . 203.Pp 204(Note that 205.Fn cv_signal 206is erroneously named in that it does not send a signal in the traditional 207sense to LWPs waiting on a CV.) 208.It Fn cv_broadcast "cv" 209.Pp 210Awaken all LWPs waiting on the specified condition variable. 211The mutex passed to the wait function 212.Po Fa mtx Pc 213must also be held when calling 214.Fn cv_broadcast . 215.It Fn cv_has_waiters "cv" 216.Pp 217Return 218.Dv true 219if one or more LWPs are waiting on the specified condition variable. 220.Pp 221.Fn cv_has_waiters 222cannot test reliably for interruptable waits. 223It should only be used to test for non-interruptable waits 224made using 225.Fn cv_wait . 226.Pp 227.Fn cv_has_waiters 228should only be used when making diagnostic assertions, and must 229be called while holding the interlocking mutex passed to 230.Fn cv_wait . 231.El 232.Sh EXAMPLES 233.Bd -literal 234Consuming a resource: 235 236 /* 237 * Lock the resource. Its mutex will also serve as the 238 * interlock. 239 */ 240 mutex_enter(\*[Am]res-\*[Gt]mutex); 241 242 /* 243 * Wait for the resource to become available. 244 */ 245 while (res-\*[Gt]state == BUSY) 246 cv_wait(\*[Am]res-\*[Gt]condvar, \*[Am]res-\*[Gt]mutex); 247 248 /* 249 * It's now available to us. Take ownership of the 250 * resource, and consume it. 251 */ 252 res-\*[Gt]state = BUSY; 253 mutex_exit(\*[Am]res-\*[Gt]mutex); 254 consume(res); 255 256Releasing a resource for the next consumer to use: 257 258 mutex_enter(\*[Am]res-\*[Gt]mutex); 259 res-\*[Gt]state = IDLE; 260 cv_signal(\*[Am]res-\*[Gt]condvar); 261 mutex_exit(\*[Am]res-\*[Gt]mutex); 262.Ed 263.Sh CODE REFERENCES 264This section describes places within the 265.Nx 266source tree where code implementing condition variables can be found. 267All pathnames are relative to 268.Pa /usr/src . 269.Pp 270The core of the CV implementation is in 271.Pa sys/kern/kern_condvar.c . 272.Pp 273The header file 274.Pa sys/sys/condvar.h 275describes the public interface. 276.Sh SEE ALSO 277.Xr sigaction 2 , 278.Xr errno 9 , 279.Xr mb 9 , 280.Xr mstohz 9 , 281.Xr mutex 9 , 282.Xr rwlock 9 283.Pp 284.Rs 285.%A Jim Mauro 286.%A Richard McDougall 287.%T Solaris Internals: Core Kernel Architecture 288.%I Prentice Hall 289.%D 2001 290.%O ISBN 0-13-022496-0 291.Re 292.Sh HISTORY 293The CV primitives first appeared in 294.Nx 5.0 . 295