1 COND_INIT(3C) Standard C Library Functions COND_INIT(3C) 2 3 4 5 NAME 6 cond_init, cond_wait, cond_timedwait, cond_reltimedwait, cond_signal, 7 cond_broadcast, cond_destroy - condition variables 8 9 SYNOPSIS 10 cc -mt [ flag... ] file... [ library... ] 11 #include <thread.h> 12 #include <synch.h> 13 14 int cond_init(cond_t *cvp, int type, void *arg); 15 16 17 int cond_wait(cond_t *cvp, mutex_t *mp); 18 19 20 int cond_timedwait(cond_t *cvp, mutex_t *mp, 21 timestruc_t *abstime); 22 23 24 int cond_reltimedwait(cond_t *cvp, mutex_t *mp, 25 timestruc_t *reltime); 26 27 28 int cond_signal(cond_t *cvp); 29 30 31 int cond_broadcast(cond_t *cvp); 32 33 34 int cond_destroy(cond_t *cvp); 35 36 37 DESCRIPTION 38 Initialize 39 Condition variables and mutexes should be global. Condition variables 40 that are allocated in writable memory can synchronize threads among 41 processes if they are shared by the cooperating processes (see mmap(2)) 42 and are initialized for this purpose. 43 44 45 The scope of a condition variable is either intra-process or inter- 46 process. This is dependent upon whether the argument is passed 47 implicitly or explicitly to the initialization of that condition 48 variable. A condition variable does not need to be explicitly 49 initialized. A condition variable is initialized with all zeros, by 50 default, and its scope is set to within the calling process. For inter- 51 process synchronization, a condition variable must be initialized once, 52 and only once, before use. 53 54 55 A condition variable must not be simultaneously initialized by multiple 56 threads or re-initialized while in use by other threads. 57 58 59 Attributes of condition variables can be set to the default or 60 customized at initialization. 61 62 63 The cond_init() function initializes the condition variable pointed to 64 by cvp. A condition variable can have several different types of 65 behavior, specified by type. No current type uses arg although a future 66 type may specify additional behavior parameters with arg. The type 67 argument c take one of the following values: 68 69 USYNC_THREAD 70 The condition variable can synchronize threads only in 71 this process. This is the default. 72 73 74 USYNC_PROCESS 75 The condition variable can synchronize threads in this 76 process and other processes. Only one process should 77 initialize the condition variable. The object 78 initialized with this attribute must be allocated in 79 memory shared between processes, either in System V 80 shared memory (see shmop(2)) or in memory mapped to a 81 file (see mmap(2)). It is illegal to initialize the 82 object this way and to not allocate it in such shared 83 memory. 84 85 86 87 Initializing condition variables can also be accomplished by allocating 88 in zeroed memory, in which case, a type of USYNC_THREAD is assumed. 89 90 91 If default condition variable attributes are used, statically allocated 92 condition variables can be initialized by the macro DEFAULTCV. 93 94 95 Default condition variable initialization (intra-process): 96 97 cond_t cvp; 98 99 cond_init(&cvp, NULL, NULL); /*initialize condition variable 100 with default*/ 101 102 103 104 or 105 106 cond_init(&cvp, USYNC_THREAD, NULL); 107 108 109 110 or 111 112 cond_t cond = DEFAULTCV; 113 114 115 116 Customized condition variable initialization (inter-process): 117 118 cond_init(&cvp, USYNC_PROCESS, NULL); /* initialize cv with 119 inter-process scope */ 120 121 122 Condition Wait 123 The condition wait interface allows a thread to wait for a condition 124 and atomically release the associated mutex that it needs to hold to 125 check the condition. The thread waits for another thread to make the 126 condition true and that thread's resulting call to signal and wakeup 127 the waiting thread. 128 129 130 The cond_wait() function atomically releases the mutex pointed to by mp 131 and causes the calling thread to block on the condition variable 132 pointed to by cvp. The blocked thread may be awakened by cond_signal(), 133 cond_broadcast(), or when interrupted by delivery of a UNIX signal or a 134 fork(). 135 136 137 The cond_wait(), cond_timedwait(), and cond_reltimedwait() functions 138 always return with the mutex locked and owned by the calling thread 139 even when returning an error, except when the mutex has the LOCK_ROBUST 140 attribute and has been left irrecoverable by the mutex's last owner. 141 The cond_wait(), cond_timedwait(), and cond_reltimedwait() functions 142 return the appropriate error value if they fail to internally reacquire 143 the mutex. 144 145 Condition Signaling 146 A condition signal allows a thread to unblock a single thread waiting 147 on the condition variable, whereas a condition broadcast allows a 148 thread to unblock all threads waiting on the condition variable. 149 150 151 The cond_signal() function unblocks one thread that is blocked on the 152 condition variable pointed to by cvp. 153 154 155 The cond_broadcast() function unblocks all threads that are blocked on 156 the condition variable pointed to by cvp. 157 158 159 If no threads are blocked on the condition variable, then cond_signal() 160 and cond_broadcast() have no effect. 161 162 163 The cond_signal() or cond_broadcast() functions can be called by a 164 thread whether or not it currently owns the mutex that threads calling 165 cond_wait(), cond_timedwait(), or cond_reltimedwait() have associated 166 with the condition variable during their waits. If, however, 167 predictable scheduling behavior is required, then that mutex should be 168 locked by the thread prior to calling cond_signal() or 169 cond_broadcast(). 170 171 Destroy 172 The condition destroy functions destroy any state, but not the space, 173 associated with the condition variable. 174 175 176 The cond_destroy() function destroys any state associated with the 177 condition variable pointed to by cvp. The space for storing the 178 condition variable is not freed. 179 180 RETURN VALUES 181 Upon successful completion, these functions return 0. Otherwise, a non- 182 zero value is returned to indicate the error. 183 184 ERRORS 185 The cond_timedwait() and cond_reltimedwait() functions will fail if: 186 187 ETIME 188 The time specified by abstime or reltime has passed. 189 190 191 192 The cond_wait(), cond_timedwait(), and cond_reltimedwait() functions 193 will fail if: 194 195 EINTR 196 Interrupted. The calling thread was awakened by the delivery 197 of a UNIX signal. 198 199 200 201 If the mutex pointed to by mp is a robust mutex (initialized with the 202 LOCK_ROBUST attribute), the cond_wait(), cond_timedwait() and 203 cond_reltimedwait() functions will, under the specified conditions, 204 return the following error values. For complete information, see the 205 description of the mutex_lock() function on the mutex_init(3C) manual 206 page. 207 208 ENOTRECOVERABLE 209 The mutex was protecting the state that has now been 210 left irrecoverable. The mutex has not been acquired. 211 212 213 EOWNERDEAD 214 The last owner of the mutex died while holding the 215 mutex, possibly leaving the state it was protecting 216 inconsistent. The mutex is now owned by the caller. 217 218 219 220 These functions may fail if: 221 222 EFAULT 223 The cond, attr, cvp, arg, abstime, or mutex argument points 224 to an illegal address. 225 226 227 EINVAL 228 Invalid argument. For cond_init(), type is not a recognized 229 type. For cond_timedwait(), the number of nanoseconds is 230 greater than or equal to 1,000,000,000. 231 232 233 EXAMPLES 234 Example 1 Use cond_wait() in a loop to test some condition. 235 236 237 The cond_wait() function is normally used in a loop testing some 238 condition, as follows: 239 240 241 (void) mutex_lock(mp); 242 while (cond == FALSE) { 243 (void) cond_wait(cvp, mp); 244 } 245 (void) mutex_unlock(mp); 246 247 248 Example 2 Use cond_timedwait() in a loop to test some condition. 249 250 251 The cond_timedwait() function is normally used in a loop testing some 252 condition. It uses an absolute timeout value as follows: 253 254 255 timestruc_t to; 256 ... 257 (void) mutex_lock(mp); 258 to.tv_sec = time(NULL) + TIMEOUT; 259 to.tv_nsec = 0; 260 while (cond == FALSE) { 261 err = cond_timedwait(cvp, mp, &to); 262 if (err == ETIME) { 263 /* timeout, do something */ 264 break; 265 } 266 } 267 (void) mutex_unlock(mp); 268 269 270 Example 3 Use cond_reltimedwait() in a loop to test some condition. 271 272 273 The cond_reltimedwait() function is normally used in a loop testing in 274 some condition. It uses a relative timeout value as follows: 275 276 277 timestruc_t to; 278 ... 279 (void) mutex_lock(mp); 280 while (cond == FALSE) { 281 to.tv_sec = TIMEOUT; 282 to.tv_nsec = 0; 283 err = cond_reltimedwait(cvp, mp, &to); 284 if (err == ETIME) { 285 /* timeout, do something */ 286 break; 287 } 288 } 289 (void) mutex_unlock(mp); 290 291 292 ATTRIBUTES 293 See attributes(5) for descriptions of the following attributes: 294 295 296 297 298 +---------------+-----------------+ 299 |ATTRIBUTE TYPE | ATTRIBUTE VALUE | 300 +---------------+-----------------+ 301 |MT-Level | MT-Safe | 302 +---------------+-----------------+ 303 304 SEE ALSO 305 fork(2), mmap(2), setitimer(2), shmop(2), mutex_init(3C), signal(3C), 306 attributes(5), condition(5), mutex(5), standards(5) 307 308 NOTES 309 If more than one thread is blocked on a condition variable, the order 310 in which threads are unblocked is determined by the scheduling policy. 311 When each thread, unblocked as a result of a cond_signal() or 312 cond_broadcast(), returns from its call to cond_wait() or 313 cond_timedwait() , the thread owns the mutex with which it called 314 cond_wait(), cond_timedwait(), or cond_reltimedwait(). The thread(s) 315 that are unblocked compete for the mutex according to the scheduling 316 policy and as if each had called mutex_lock(3C). 317 318 319 When cond_wait() returns the value of the condition is indeterminate 320 and must be reevaluated. 321 322 323 The cond_timedwait() and cond_reltimedwait() functions are similar to 324 cond_wait(), except that the calling thread will not wait for the 325 condition to become true past the absolute time specified by abstime or 326 the relative time specified by reltime. Note that cond_timedwait() or 327 cond_reltimedwait() might continue to block as it trys to reacquire the 328 mutex pointed to by mp, which may be locked by another thread. If 329 either cond_timedwait() or cond_reltimedwait() returns because of a 330 timeout, it returns the error value ETIME. 331 332 333 334 February 15, 2020 COND_INIT(3C)