1.\" $NetBSD: condvar.9,v 1.10 2008/01/26 14:16:27 wiz 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.\" 3. All advertising materials mentioning features or use of this software 18.\" must display the following acknowledgement: 19.\" This product includes software developed by the NetBSD 20.\" Foundation, Inc. and its contributors. 21.\" 4. Neither the name of The NetBSD Foundation nor the names of its 22.\" contributors may be used to endorse or promote products derived 23.\" from this software without specific prior written permission. 24.\" 25.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35.\" POSSIBILITY OF SUCH DAMAGE. 36.\" 37.Dd January 26, 2008 38.Dt CONDVAR 9 39.Os 40.Sh NAME 41.Nm cv , 42.Nm condvar , 43.Nm cv_init , 44.Nm cv_destroy , 45.Nm cv_wait , 46.Nm cv_wait_sig , 47.Nm cv_timedwait , 48.Nm cv_timedwait_sig , 49.Nm cv_signal , 50.Nm cv_broadcast , 51.Nm cv_has_waiters 52.Nd condition variables 53.Sh SYNOPSIS 54.In sys/condvar.h 55.Ft void 56.Fn cv_init "kcondvar_t *cv" "const char *wmesg" 57.Ft void 58.Fn cv_destroy "kcondvar_t *cv" 59.Ft void 60.Fn cv_wait "kcondvar_t *cv" "kmutex_t *mtx" 61.Ft int 62.Fn cv_wait_sig "kcondvar_t *cv" "kmutex_t *mtx" 63.Ft int 64.Fn cv_timedwait "kcondvar_t *cv" "kmutex_t *mtx" "int ticks" 65.Ft int 66.Fn cv_timedwait_sig "kcondvar_t *cv" "kmutex_t *mtx" "int ticks" 67.Ft void 68.Fn cv_signal "kcondvar_t *cv" 69.Ft void 70.Fn cv_broadcast "kcondvar_t *cv" 71.Ft bool 72.Fn cv_has_waiters "kcondvar_t *cv" 73.Sh DESCRIPTION 74Condition variables (CVs) are used in the kernel to synchronize access 75to resources that are limited (for example, memory) and to wait for 76pending I/O operations to complete. 77.Pp 78The 79.Vt kcondvar_t 80type provides storage for the CV object. 81This should be treated as an opaque object and not examined directly by 82consumers. 83.Sh FUNCTIONS 84.Bl -tag -width abcd 85.It Fn cv_init "cv" "wmesg" 86.Pp 87Initialize a CV for use. 88No other operations can be performed on the CV until it has been initialized. 89.Pp 90The 91.Fa wmesg 92argument specifies a string of no more than 8 characters that describes 93the resource or condition associated with the CV. 94The kernel does not use this argument directly but makes it available for 95utilities such as 96.Xr ps 1 97to display. 98.It Fn cv_destroy "cv" 99.Pp 100Release resources used by a CV. 101The CV must not be in use when it is destroyed, and must not be used afterwards. 102.It Fn cv_wait "cv" "mtx" 103.Pp 104Cause the current LWP to wait non-interruptably for access to a resource, 105or for an I/O operation to complete. 106The LWP will resume execution when awoken by another thread using 107.Fn cv_signal 108or 109.Fn cv_broadcast . 110.Pp 111.Fa mtx 112specifies a kernel mutex to be used as an interlock, and must be held by the 113calling LWP on entry to 114.Fn cv_wait . 115It will be released once the LWP has prepared to sleep, and will be reacquired 116before 117.Fn cv_wait 118returns. 119.Pp 120A small window exists between testing for availability of a resource and 121waiting for the resource with 122.Fn cv_wait , 123in which the resource may become available again. 124The interlock is used to guarentee that the resource will not be signalled 125as available until the calling LWP has begun to wait for it. 126.Pp 127Non-interruptable waits have the potential to deadlock the system, and so must 128be kept short (typically, under one second). 129.It Fn cv_wait_sig "cv" "mtx" 130.Pp 131As per 132.Fn cv_wait , 133but causes the current LWP to wait interruptably. 134If the LWP recieves a signal, or is interrupted by another condition such 135as its containing process exiting, the wait is ended early and an error 136code returned. 137.Pp 138If 139.Fn cv_wait_sig 140returns as a result of a signal, the return value is 141.Er ERESTART 142if the signal 143has the 144.Dv SA_RESTART 145property. 146If awoken normally, the value is zero, and 147.Er EINTR 148under all other conditions. 149.It Fn cv_timedwait "cv" "mtx" "ticks" 150.Pp 151As per 152.Fn cv_wait , 153but will return early if a timeout specified by the 154.Fa ticks 155argument expires. 156.Pp 157.Fa ticks 158is an architecture and system dependent value related to the number of 159clock interrupts per second. 160See 161.Xr hz 9 162for details. 163The 164.Xr mstohz 9 165macro can be used to convert a timeout expressed in milliseconds to 166one suitable for 167.Fn cv_timedwait . 168If the 169.Fa ticks 170argument is zero, 171.Fn cv_timedwait 172behaves exactly like 173.Fn cv_wait . 174.Pp 175If the timeout expires before the LWP is awoken, the return value is 176.Er EWOULDBLOCK . 177If awoken normally, the return value is zero. 178.It Fn cv_timedwait_sig "cv" "mtx" "ticks" 179.Pp 180As per 181.Fn cv_wait_sig , 182but also accepts a timeout value and will return 183.Er EWOULDBLOCK 184if the timeout expires. 185.It Fn cv_signal "cv" 186.Pp 187Awaken one LWP (potentially among many) that is waiting on the specified 188condition variable. 189The mutex passed to the wait function 190.Po Fa mtx Pc 191must also be held when calling 192.Fn cv_signal . 193.Pp 194(Note that 195.Fn cv_signal 196is erroneously named in that it does not send a signal in the traditional 197sense to LWPs waiting on a CV.) 198.It Fn cv_broadcast "cv" 199.Pp 200Awaken all LWPs waiting on the specified condition variable. 201The mutex passed to the wait function 202.Po Fa mtx Pc 203must also be held when calling 204.Fn cv_broadcast . 205.It Fn cv_has_waiters "cv" 206.Pp 207Return 208.Dv true 209if one or more LWPs are waiting on the specified condition variable. 210.Pp 211.Fn cv_has_waiters 212cannot test reliably for interruptable waits. 213It should only be used to test for non-interruptable waits 214made using 215.Fn cv_wait . 216.Pp 217.Fn cv_has_waiters 218should only be used when making diagnostic assertions, and must 219be called while holding the interlocking mutex passed to 220.Fn cv_wait . 221.El 222.Sh EXAMPLES 223.Bd -literal 224Consuming a resource: 225 226 /* 227 * Lock the resource. Its mutex will also serve as the 228 * interlock. 229 */ 230 mutex_enter(\*[Am]res-\*[Gt]mutex); 231 232 /* 233 * Wait for the resource to become available. 234 */ 235 while (res-\*[Gt]state == BUSY) 236 cv_wait(\*[Am]res-\*[Gt]condvar, \*[Am]res-\*[Gt]mutex); 237 238 /* 239 * It's now available to us. Take ownership of the 240 * resource, and consume it. 241 */ 242 res-\*[Gt]state = BUSY; 243 mutex_exit(\*[Am]res-\*[Gt]mutex); 244 consume(res); 245 246Releasing a resource for the next consumer to use: 247 248 mutex_enter(\*[Am]res-\*[Gt]mutex); 249 res-\*[Gt]state = IDLE; 250 cv_signal(\*[Am]res-\*[Gt]condvar); 251 mutex_exit(\*[Am]res-\*[Gt]mutex); 252.Ed 253.Sh CODE REFERENCES 254This section describes places within the 255.Nx 256source tree where code implementing condition variables can be found. 257All pathnames are relative to 258.Pa /usr/src . 259.Pp 260The core of the CV implementation is in 261.Pa sys/kern/kern_condvar.c . 262.Pp 263The header file 264.Pa sys/sys/condvar.h 265describes the public interface. 266.Sh SEE ALSO 267.Xr sigaction 2 , 268.Xr errno 9 , 269.Xr mb 9 , 270.Xr mstohz 9 , 271.Xr mutex 9 , 272.Xr rwlock 9 273.Pp 274.Rs 275.%A Jim Mauro 276.%A Richard McDougall 277.%T Solaris Internals: Core Kernel Architecture 278.%I Prentice Hall 279.%D 2001 280.%O ISBN 0-13-022496-0 281.Re 282.Sh HISTORY 283The CV primitives first appeared in 284.Nx 5.0 . 285