1 1.63 martin /* $NetBSD: kern_condvar.c,v 1.63 2023/11/02 10:31:55 martin Exp $ */ 2 1.2 ad 3 1.2 ad /*- 4 1.56 ad * Copyright (c) 2006, 2007, 2008, 2019, 2020, 2023 5 1.56 ad * The NetBSD Foundation, Inc. 6 1.2 ad * All rights reserved. 7 1.2 ad * 8 1.2 ad * This code is derived from software contributed to The NetBSD Foundation 9 1.2 ad * by Andrew Doran. 10 1.2 ad * 11 1.2 ad * Redistribution and use in source and binary forms, with or without 12 1.2 ad * modification, are permitted provided that the following conditions 13 1.2 ad * are met: 14 1.2 ad * 1. Redistributions of source code must retain the above copyright 15 1.2 ad * notice, this list of conditions and the following disclaimer. 16 1.2 ad * 2. Redistributions in binary form must reproduce the above copyright 17 1.2 ad * notice, this list of conditions and the following disclaimer in the 18 1.2 ad * documentation and/or other materials provided with the distribution. 19 1.2 ad * 20 1.2 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.2 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.2 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.2 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.2 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.2 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.2 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.2 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.2 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.2 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.2 ad * POSSIBILITY OF SUCH DAMAGE. 31 1.2 ad */ 32 1.2 ad 33 1.2 ad /* 34 1.24 ad * Kernel condition variable implementation. 35 1.2 ad */ 36 1.2 ad 37 1.2 ad #include <sys/cdefs.h> 38 1.63 martin __KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.63 2023/11/02 10:31:55 martin Exp $"); 39 1.2 ad 40 1.2 ad #include <sys/param.h> 41 1.62 riastrad 42 1.2 ad #include <sys/condvar.h> 43 1.24 ad #include <sys/cpu.h> 44 1.37 riastrad #include <sys/kernel.h> 45 1.62 riastrad #include <sys/lockdebug.h> 46 1.62 riastrad #include <sys/lwp.h> 47 1.62 riastrad #include <sys/sleepq.h> 48 1.61 riastrad #include <sys/syncobj.h> 49 1.62 riastrad #include <sys/systm.h> 50 1.20 ad 51 1.26 thorpej /* 52 1.26 thorpej * Accessors for the private contents of the kcondvar_t data type. 53 1.26 thorpej * 54 1.44 ad * cv_opaque[0] sleepq_t 55 1.44 ad * cv_opaque[1] description for ps(1) 56 1.26 thorpej * 57 1.44 ad * cv_opaque[0] is protected by the interlock passed to cv_wait() (enqueue 58 1.43 ad * only), and the sleep queue lock acquired with sleepq_hashlock() (enqueue 59 1.26 thorpej * and dequeue). 60 1.26 thorpej * 61 1.44 ad * cv_opaque[1] (the wmesg) is static and does not change throughout the life 62 1.26 thorpej * of the CV. 63 1.26 thorpej */ 64 1.26 thorpej #define CV_SLEEPQ(cv) ((sleepq_t *)(cv)->cv_opaque) 65 1.44 ad #define CV_WMESG(cv) ((const char *)(cv)->cv_opaque[1]) 66 1.44 ad #define CV_SET_WMESG(cv, v) (cv)->cv_opaque[1] = __UNCONST(v) 67 1.26 thorpej 68 1.26 thorpej #define CV_DEBUG_P(cv) (CV_WMESG(cv) != nodebug) 69 1.20 ad #define CV_RA ((uintptr_t)__builtin_return_address(0)) 70 1.2 ad 71 1.36 chs static void cv_unsleep(lwp_t *, bool); 72 1.36 chs static inline void cv_wakeup_one(kcondvar_t *); 73 1.36 chs static inline void cv_wakeup_all(kcondvar_t *); 74 1.2 ad 75 1.43 ad syncobj_t cv_syncobj = { 76 1.55 riastrad .sobj_name = "cv", 77 1.41 ozaki .sobj_flag = SOBJ_SLEEPQ_SORTED, 78 1.56 ad .sobj_boostpri = PRI_KERNEL, 79 1.41 ozaki .sobj_unsleep = cv_unsleep, 80 1.41 ozaki .sobj_changepri = sleepq_changepri, 81 1.41 ozaki .sobj_lendpri = sleepq_lendpri, 82 1.41 ozaki .sobj_owner = syncobj_noowner, 83 1.2 ad }; 84 1.2 ad 85 1.10 ad static const char deadcv[] = "deadcv"; 86 1.10 ad 87 1.2 ad /* 88 1.2 ad * cv_init: 89 1.2 ad * 90 1.2 ad * Initialize a condition variable for use. 91 1.2 ad */ 92 1.2 ad void 93 1.2 ad cv_init(kcondvar_t *cv, const char *wmesg) 94 1.2 ad { 95 1.2 ad 96 1.21 ad KASSERT(wmesg != NULL); 97 1.26 thorpej CV_SET_WMESG(cv, wmesg); 98 1.20 ad sleepq_init(CV_SLEEPQ(cv)); 99 1.2 ad } 100 1.2 ad 101 1.2 ad /* 102 1.2 ad * cv_destroy: 103 1.2 ad * 104 1.2 ad * Tear down a condition variable. 105 1.2 ad */ 106 1.2 ad void 107 1.2 ad cv_destroy(kcondvar_t *cv) 108 1.2 ad { 109 1.2 ad 110 1.53 christos sleepq_destroy(CV_SLEEPQ(cv)); 111 1.2 ad #ifdef DIAGNOSTIC 112 1.15 ad KASSERT(cv_is_valid(cv)); 113 1.45 ad KASSERT(!cv_has_waiters(cv)); 114 1.26 thorpej CV_SET_WMESG(cv, deadcv); 115 1.2 ad #endif 116 1.2 ad } 117 1.2 ad 118 1.2 ad /* 119 1.2 ad * cv_enter: 120 1.2 ad * 121 1.2 ad * Look up and lock the sleep queue corresponding to the given 122 1.2 ad * condition variable, and increment the number of waiters. 123 1.2 ad */ 124 1.57 ad static inline int 125 1.47 ad cv_enter(kcondvar_t *cv, kmutex_t *mtx, lwp_t *l, bool catch_p) 126 1.2 ad { 127 1.2 ad sleepq_t *sq; 128 1.18 ad kmutex_t *mp; 129 1.57 ad int nlocks; 130 1.2 ad 131 1.15 ad KASSERT(cv_is_valid(cv)); 132 1.24 ad KASSERT(!cpu_intr_p()); 133 1.14 ad KASSERT((l->l_pflag & LP_INTR) == 0 || panicstr != NULL); 134 1.2 ad 135 1.24 ad mp = sleepq_hashlock(cv); 136 1.20 ad sq = CV_SLEEPQ(cv); 137 1.57 ad nlocks = sleepq_enter(sq, l, mp); 138 1.47 ad sleepq_enqueue(sq, cv, CV_WMESG(cv), &cv_syncobj, catch_p); 139 1.2 ad mutex_exit(mtx); 140 1.24 ad KASSERT(cv_has_waiters(cv)); 141 1.57 ad return nlocks; 142 1.2 ad } 143 1.2 ad 144 1.2 ad /* 145 1.2 ad * cv_unsleep: 146 1.2 ad * 147 1.2 ad * Remove an LWP from the condition variable and sleep queue. This 148 1.2 ad * is called when the LWP has not been awoken normally but instead 149 1.2 ad * interrupted: for example, when a signal is received. Must be 150 1.42 ad * called with the LWP locked. Will unlock if "unlock" is true. 151 1.2 ad */ 152 1.27 rmind static void 153 1.42 ad cv_unsleep(lwp_t *l, bool unlock) 154 1.2 ad { 155 1.34 martin kcondvar_t *cv __diagused; 156 1.2 ad 157 1.15 ad cv = (kcondvar_t *)(uintptr_t)l->l_wchan; 158 1.15 ad 159 1.20 ad KASSERT(l->l_wchan == (wchan_t)cv); 160 1.20 ad KASSERT(l->l_sleepq == CV_SLEEPQ(cv)); 161 1.15 ad KASSERT(cv_is_valid(cv)); 162 1.24 ad KASSERT(cv_has_waiters(cv)); 163 1.2 ad 164 1.42 ad sleepq_unsleep(l, unlock); 165 1.2 ad } 166 1.2 ad 167 1.2 ad /* 168 1.2 ad * cv_wait: 169 1.2 ad * 170 1.2 ad * Wait non-interruptably on a condition variable until awoken. 171 1.2 ad */ 172 1.2 ad void 173 1.2 ad cv_wait(kcondvar_t *cv, kmutex_t *mtx) 174 1.2 ad { 175 1.6 ad lwp_t *l = curlwp; 176 1.57 ad int nlocks; 177 1.2 ad 178 1.8 yamt KASSERT(mutex_owned(mtx)); 179 1.2 ad 180 1.57 ad nlocks = cv_enter(cv, mtx, l, false); 181 1.57 ad (void)sleepq_block(0, false, &cv_syncobj, nlocks); 182 1.36 chs mutex_enter(mtx); 183 1.2 ad } 184 1.2 ad 185 1.2 ad /* 186 1.2 ad * cv_wait_sig: 187 1.2 ad * 188 1.2 ad * Wait on a condition variable until a awoken or a signal is received. 189 1.2 ad * Will also return early if the process is exiting. Returns zero if 190 1.29 jym * awoken normally, ERESTART if a signal was received and the system 191 1.2 ad * call is restartable, or EINTR otherwise. 192 1.2 ad */ 193 1.2 ad int 194 1.2 ad cv_wait_sig(kcondvar_t *cv, kmutex_t *mtx) 195 1.2 ad { 196 1.6 ad lwp_t *l = curlwp; 197 1.57 ad int error, nlocks; 198 1.2 ad 199 1.8 yamt KASSERT(mutex_owned(mtx)); 200 1.2 ad 201 1.57 ad nlocks = cv_enter(cv, mtx, l, true); 202 1.57 ad error = sleepq_block(0, true, &cv_syncobj, nlocks); 203 1.45 ad mutex_enter(mtx); 204 1.45 ad return error; 205 1.2 ad } 206 1.2 ad 207 1.2 ad /* 208 1.2 ad * cv_timedwait: 209 1.2 ad * 210 1.2 ad * Wait on a condition variable until awoken or the specified timeout 211 1.2 ad * expires. Returns zero if awoken normally or EWOULDBLOCK if the 212 1.2 ad * timeout expired. 213 1.31 apb * 214 1.31 apb * timo is a timeout in ticks. timo = 0 specifies an infinite timeout. 215 1.2 ad */ 216 1.2 ad int 217 1.2 ad cv_timedwait(kcondvar_t *cv, kmutex_t *mtx, int timo) 218 1.2 ad { 219 1.6 ad lwp_t *l = curlwp; 220 1.57 ad int error, nlocks; 221 1.2 ad 222 1.8 yamt KASSERT(mutex_owned(mtx)); 223 1.2 ad 224 1.57 ad nlocks = cv_enter(cv, mtx, l, false); 225 1.57 ad error = sleepq_block(timo, false, &cv_syncobj, nlocks); 226 1.45 ad mutex_enter(mtx); 227 1.45 ad return error; 228 1.2 ad } 229 1.2 ad 230 1.2 ad /* 231 1.2 ad * cv_timedwait_sig: 232 1.2 ad * 233 1.2 ad * Wait on a condition variable until a timeout expires, awoken or a 234 1.2 ad * signal is received. Will also return early if the process is 235 1.29 jym * exiting. Returns zero if awoken normally, EWOULDBLOCK if the 236 1.2 ad * timeout expires, ERESTART if a signal was received and the system 237 1.2 ad * call is restartable, or EINTR otherwise. 238 1.32 apb * 239 1.32 apb * timo is a timeout in ticks. timo = 0 specifies an infinite timeout. 240 1.2 ad */ 241 1.2 ad int 242 1.2 ad cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int timo) 243 1.2 ad { 244 1.6 ad lwp_t *l = curlwp; 245 1.57 ad int error, nlocks; 246 1.2 ad 247 1.8 yamt KASSERT(mutex_owned(mtx)); 248 1.2 ad 249 1.57 ad nlocks = cv_enter(cv, mtx, l, true); 250 1.57 ad error = sleepq_block(timo, true, &cv_syncobj, nlocks); 251 1.45 ad mutex_enter(mtx); 252 1.45 ad return error; 253 1.2 ad } 254 1.2 ad 255 1.49 riastrad /* 256 1.37 riastrad * Given a number of seconds, sec, and 2^64ths of a second, frac, we 257 1.37 riastrad * want a number of ticks for a timeout: 258 1.37 riastrad * 259 1.37 riastrad * timo = hz*(sec + frac/2^64) 260 1.37 riastrad * = hz*sec + hz*frac/2^64 261 1.37 riastrad * = hz*sec + hz*(frachi*2^32 + fraclo)/2^64 262 1.37 riastrad * = hz*sec + hz*frachi/2^32 + hz*fraclo/2^64, 263 1.37 riastrad * 264 1.37 riastrad * where frachi is the high 32 bits of frac and fraclo is the 265 1.37 riastrad * low 32 bits. 266 1.37 riastrad * 267 1.37 riastrad * We assume hz < INT_MAX/2 < UINT32_MAX, so 268 1.37 riastrad * 269 1.37 riastrad * hz*fraclo/2^64 < fraclo*2^32/2^64 <= 1, 270 1.37 riastrad * 271 1.37 riastrad * since fraclo < 2^32. 272 1.37 riastrad * 273 1.37 riastrad * We clamp the result at INT_MAX/2 for a timeout in ticks, since we 274 1.37 riastrad * can't represent timeouts higher than INT_MAX in cv_timedwait, and 275 1.37 riastrad * spurious wakeup is OK. Moreover, we don't want to wrap around, 276 1.37 riastrad * because we compute end - start in ticks in order to compute the 277 1.37 riastrad * remaining timeout, and that difference cannot wrap around, so we use 278 1.37 riastrad * a timeout less than INT_MAX. Using INT_MAX/2 provides plenty of 279 1.37 riastrad * margin for paranoia and will exceed most waits in practice by far. 280 1.37 riastrad */ 281 1.37 riastrad static unsigned 282 1.37 riastrad bintime2timo(const struct bintime *bt) 283 1.37 riastrad { 284 1.37 riastrad 285 1.37 riastrad KASSERT(hz < INT_MAX/2); 286 1.37 riastrad CTASSERT(INT_MAX/2 < UINT32_MAX); 287 1.37 riastrad if (bt->sec > ((INT_MAX/2)/hz)) 288 1.37 riastrad return INT_MAX/2; 289 1.37 riastrad if ((hz*(bt->frac >> 32) >> 32) > (INT_MAX/2 - hz*bt->sec)) 290 1.37 riastrad return INT_MAX/2; 291 1.37 riastrad 292 1.37 riastrad return hz*bt->sec + (hz*(bt->frac >> 32) >> 32); 293 1.37 riastrad } 294 1.37 riastrad 295 1.37 riastrad /* 296 1.37 riastrad * timo is in units of ticks. We want units of seconds and 2^64ths of 297 1.37 riastrad * a second. We know hz = 1 sec/tick, and 2^64 = 1 sec/(2^64th of a 298 1.37 riastrad * second), from which we can conclude 2^64 / hz = 1 (2^64th of a 299 1.37 riastrad * second)/tick. So for the fractional part, we compute 300 1.37 riastrad * 301 1.37 riastrad * frac = rem * 2^64 / hz 302 1.37 riastrad * = ((rem * 2^32) / hz) * 2^32 303 1.37 riastrad * 304 1.37 riastrad * Using truncating integer division instead of real division will 305 1.37 riastrad * leave us with only about 32 bits of precision, which means about 306 1.37 riastrad * 1/4-nanosecond resolution, which is good enough for our purposes. 307 1.37 riastrad */ 308 1.37 riastrad static struct bintime 309 1.37 riastrad timo2bintime(unsigned timo) 310 1.37 riastrad { 311 1.37 riastrad 312 1.37 riastrad return (struct bintime) { 313 1.37 riastrad .sec = timo / hz, 314 1.37 riastrad .frac = (((uint64_t)(timo % hz) << 32)/hz << 32), 315 1.37 riastrad }; 316 1.37 riastrad } 317 1.37 riastrad 318 1.37 riastrad /* 319 1.37 riastrad * cv_timedwaitbt: 320 1.37 riastrad * 321 1.37 riastrad * Wait on a condition variable until awoken or the specified 322 1.37 riastrad * timeout expires. Returns zero if awoken normally or 323 1.37 riastrad * EWOULDBLOCK if the timeout expires. 324 1.37 riastrad * 325 1.37 riastrad * On entry, bt is a timeout in bintime. cv_timedwaitbt subtracts 326 1.37 riastrad * the time slept, so on exit, bt is the time remaining after 327 1.38 riastrad * sleeping, possibly negative if the complete time has elapsed. 328 1.38 riastrad * No infinite timeout; use cv_wait_sig instead. 329 1.37 riastrad * 330 1.37 riastrad * epsilon is a requested maximum error in timeout (excluding 331 1.37 riastrad * spurious wakeups). Currently not used, will be used in the 332 1.37 riastrad * future to choose between low- and high-resolution timers. 333 1.38 riastrad * Actual wakeup time will be somewhere in [t, t + max(e, r) + s) 334 1.38 riastrad * where r is the finest resolution of clock available and s is 335 1.38 riastrad * scheduling delays for scheduler overhead and competing threads. 336 1.38 riastrad * Time is measured by the interrupt source implementing the 337 1.38 riastrad * timeout, not by another timecounter. 338 1.37 riastrad */ 339 1.37 riastrad int 340 1.37 riastrad cv_timedwaitbt(kcondvar_t *cv, kmutex_t *mtx, struct bintime *bt, 341 1.38 riastrad const struct bintime *epsilon __diagused) 342 1.37 riastrad { 343 1.37 riastrad struct bintime slept; 344 1.37 riastrad unsigned start, end; 345 1.48 riastrad int timo; 346 1.37 riastrad int error; 347 1.37 riastrad 348 1.38 riastrad KASSERTMSG(bt->sec >= 0, "negative timeout"); 349 1.38 riastrad KASSERTMSG(epsilon != NULL, "specify maximum requested delay"); 350 1.38 riastrad 351 1.48 riastrad /* If there's nothing left to wait, time out. */ 352 1.48 riastrad if (bt->sec == 0 && bt->frac == 0) 353 1.48 riastrad return EWOULDBLOCK; 354 1.48 riastrad 355 1.48 riastrad /* Convert to ticks, but clamp to be >=1. */ 356 1.48 riastrad timo = bintime2timo(bt); 357 1.48 riastrad KASSERTMSG(timo >= 0, "negative ticks: %d", timo); 358 1.48 riastrad if (timo == 0) 359 1.48 riastrad timo = 1; 360 1.48 riastrad 361 1.37 riastrad /* 362 1.46 maxv * getticks() is technically int, but nothing special 363 1.37 riastrad * happens instead of overflow, so we assume two's-complement 364 1.37 riastrad * wraparound and just treat it as unsigned. 365 1.37 riastrad */ 366 1.46 maxv start = getticks(); 367 1.48 riastrad error = cv_timedwait(cv, mtx, timo); 368 1.46 maxv end = getticks(); 369 1.37 riastrad 370 1.48 riastrad /* 371 1.48 riastrad * Set it to the time left, or zero, whichever is larger. We 372 1.48 riastrad * do not fail with EWOULDBLOCK here because this may have been 373 1.48 riastrad * an explicit wakeup, so the caller needs to check before they 374 1.48 riastrad * give up or else cv_signal would be lost. 375 1.48 riastrad */ 376 1.37 riastrad slept = timo2bintime(end - start); 377 1.48 riastrad if (bintimecmp(bt, &slept, <=)) { 378 1.48 riastrad bt->sec = 0; 379 1.48 riastrad bt->frac = 0; 380 1.48 riastrad } else { 381 1.48 riastrad /* bt := bt - slept */ 382 1.48 riastrad bintime_sub(bt, &slept); 383 1.48 riastrad } 384 1.37 riastrad 385 1.37 riastrad return error; 386 1.37 riastrad } 387 1.37 riastrad 388 1.37 riastrad /* 389 1.37 riastrad * cv_timedwaitbt_sig: 390 1.37 riastrad * 391 1.37 riastrad * Wait on a condition variable until awoken, the specified 392 1.37 riastrad * timeout expires, or interrupted by a signal. Returns zero if 393 1.37 riastrad * awoken normally, EWOULDBLOCK if the timeout expires, or 394 1.37 riastrad * EINTR/ERESTART if interrupted by a signal. 395 1.37 riastrad * 396 1.37 riastrad * On entry, bt is a timeout in bintime. cv_timedwaitbt_sig 397 1.37 riastrad * subtracts the time slept, so on exit, bt is the time remaining 398 1.37 riastrad * after sleeping. No infinite timeout; use cv_wait instead. 399 1.37 riastrad * 400 1.37 riastrad * epsilon is a requested maximum error in timeout (excluding 401 1.37 riastrad * spurious wakeups). Currently not used, will be used in the 402 1.37 riastrad * future to choose between low- and high-resolution timers. 403 1.37 riastrad */ 404 1.37 riastrad int 405 1.37 riastrad cv_timedwaitbt_sig(kcondvar_t *cv, kmutex_t *mtx, struct bintime *bt, 406 1.39 riastrad const struct bintime *epsilon __diagused) 407 1.37 riastrad { 408 1.37 riastrad struct bintime slept; 409 1.37 riastrad unsigned start, end; 410 1.48 riastrad int timo; 411 1.37 riastrad int error; 412 1.37 riastrad 413 1.39 riastrad KASSERTMSG(bt->sec >= 0, "negative timeout"); 414 1.39 riastrad KASSERTMSG(epsilon != NULL, "specify maximum requested delay"); 415 1.39 riastrad 416 1.48 riastrad /* If there's nothing left to wait, time out. */ 417 1.48 riastrad if (bt->sec == 0 && bt->frac == 0) 418 1.48 riastrad return EWOULDBLOCK; 419 1.48 riastrad 420 1.48 riastrad /* Convert to ticks, but clamp to be >=1. */ 421 1.48 riastrad timo = bintime2timo(bt); 422 1.48 riastrad KASSERTMSG(timo >= 0, "negative ticks: %d", timo); 423 1.48 riastrad if (timo == 0) 424 1.48 riastrad timo = 1; 425 1.48 riastrad 426 1.37 riastrad /* 427 1.46 maxv * getticks() is technically int, but nothing special 428 1.37 riastrad * happens instead of overflow, so we assume two's-complement 429 1.37 riastrad * wraparound and just treat it as unsigned. 430 1.37 riastrad */ 431 1.46 maxv start = getticks(); 432 1.48 riastrad error = cv_timedwait_sig(cv, mtx, timo); 433 1.46 maxv end = getticks(); 434 1.37 riastrad 435 1.48 riastrad /* 436 1.48 riastrad * Set it to the time left, or zero, whichever is larger. We 437 1.48 riastrad * do not fail with EWOULDBLOCK here because this may have been 438 1.48 riastrad * an explicit wakeup, so the caller needs to check before they 439 1.48 riastrad * give up or else cv_signal would be lost. 440 1.48 riastrad */ 441 1.37 riastrad slept = timo2bintime(end - start); 442 1.48 riastrad if (bintimecmp(bt, &slept, <=)) { 443 1.48 riastrad bt->sec = 0; 444 1.48 riastrad bt->frac = 0; 445 1.48 riastrad } else { 446 1.48 riastrad /* bt := bt - slept */ 447 1.48 riastrad bintime_sub(bt, &slept); 448 1.48 riastrad } 449 1.37 riastrad 450 1.37 riastrad return error; 451 1.37 riastrad } 452 1.37 riastrad 453 1.37 riastrad /* 454 1.2 ad * cv_signal: 455 1.2 ad * 456 1.59 ad * Wake the highest priority LWP waiting on a condition variable. Must 457 1.59 ad * be called with the interlocking mutex held or just after it has been 458 1.59 ad * released (so the awoken LWP will see the changed condition). 459 1.2 ad */ 460 1.2 ad void 461 1.2 ad cv_signal(kcondvar_t *cv) 462 1.2 ad { 463 1.20 ad 464 1.20 ad KASSERT(cv_is_valid(cv)); 465 1.20 ad 466 1.59 ad if (__predict_false(!LIST_EMPTY(CV_SLEEPQ(cv)))) { 467 1.59 ad /* 468 1.59 ad * Compiler turns into a tail call usually, i.e. jmp, 469 1.59 ad * because the arguments are the same and no locals. 470 1.59 ad */ 471 1.24 ad cv_wakeup_one(cv); 472 1.59 ad } 473 1.20 ad } 474 1.20 ad 475 1.42 ad /* 476 1.42 ad * cv_wakeup_one: 477 1.42 ad * 478 1.42 ad * Slow path for cv_signal(). Deliberately marked __noinline to 479 1.42 ad * prevent the compiler pulling it in to cv_signal(), which adds 480 1.42 ad * extra prologue and epilogue code. 481 1.42 ad */ 482 1.42 ad static __noinline void 483 1.20 ad cv_wakeup_one(kcondvar_t *cv) 484 1.20 ad { 485 1.2 ad sleepq_t *sq; 486 1.18 ad kmutex_t *mp; 487 1.20 ad lwp_t *l; 488 1.2 ad 489 1.24 ad mp = sleepq_hashlock(cv); 490 1.20 ad sq = CV_SLEEPQ(cv); 491 1.58 ad if (__predict_true((l = LIST_FIRST(sq)) != NULL)) { 492 1.45 ad KASSERT(l->l_sleepq == sq); 493 1.45 ad KASSERT(l->l_mutex == mp); 494 1.45 ad KASSERT(l->l_wchan == cv); 495 1.58 ad sleepq_remove(sq, l, true); 496 1.20 ad } 497 1.20 ad mutex_spin_exit(mp); 498 1.2 ad } 499 1.2 ad 500 1.2 ad /* 501 1.2 ad * cv_broadcast: 502 1.2 ad * 503 1.59 ad * Wake all LWPs waiting on a condition variable. Must be called with 504 1.59 ad * the interlocking mutex held or just after it has been released (so 505 1.59 ad * the awoken LWP will see the changed condition). 506 1.2 ad */ 507 1.2 ad void 508 1.2 ad cv_broadcast(kcondvar_t *cv) 509 1.2 ad { 510 1.20 ad 511 1.20 ad KASSERT(cv_is_valid(cv)); 512 1.20 ad 513 1.59 ad if (__predict_false(!LIST_EMPTY(CV_SLEEPQ(cv)))) { 514 1.59 ad /* 515 1.59 ad * Compiler turns into a tail call usually, i.e. jmp, 516 1.59 ad * because the arguments are the same and no locals. 517 1.59 ad */ 518 1.24 ad cv_wakeup_all(cv); 519 1.59 ad } 520 1.20 ad } 521 1.20 ad 522 1.42 ad /* 523 1.42 ad * cv_wakeup_all: 524 1.42 ad * 525 1.42 ad * Slow path for cv_broadcast(). Deliberately marked __noinline to 526 1.42 ad * prevent the compiler pulling it in to cv_broadcast(), which adds 527 1.42 ad * extra prologue and epilogue code. 528 1.42 ad */ 529 1.42 ad static __noinline void 530 1.20 ad cv_wakeup_all(kcondvar_t *cv) 531 1.20 ad { 532 1.2 ad sleepq_t *sq; 533 1.18 ad kmutex_t *mp; 534 1.45 ad lwp_t *l; 535 1.15 ad 536 1.24 ad mp = sleepq_hashlock(cv); 537 1.20 ad sq = CV_SLEEPQ(cv); 538 1.45 ad while ((l = LIST_FIRST(sq)) != NULL) { 539 1.20 ad KASSERT(l->l_sleepq == sq); 540 1.20 ad KASSERT(l->l_mutex == mp); 541 1.20 ad KASSERT(l->l_wchan == cv); 542 1.58 ad sleepq_remove(sq, l, true); 543 1.20 ad } 544 1.20 ad mutex_spin_exit(mp); 545 1.2 ad } 546 1.2 ad 547 1.2 ad /* 548 1.2 ad * cv_has_waiters: 549 1.2 ad * 550 1.2 ad * For diagnostic assertions: return non-zero if a condition 551 1.2 ad * variable has waiters. 552 1.2 ad */ 553 1.7 ad bool 554 1.2 ad cv_has_waiters(kcondvar_t *cv) 555 1.2 ad { 556 1.23 chris 557 1.44 ad return !LIST_EMPTY(CV_SLEEPQ(cv)); 558 1.2 ad } 559 1.15 ad 560 1.15 ad /* 561 1.15 ad * cv_is_valid: 562 1.15 ad * 563 1.15 ad * For diagnostic assertions: return non-zero if a condition 564 1.15 ad * variable appears to be valid. No locks need be held. 565 1.15 ad */ 566 1.15 ad bool 567 1.15 ad cv_is_valid(kcondvar_t *cv) 568 1.15 ad { 569 1.15 ad 570 1.26 thorpej return CV_WMESG(cv) != deadcv && CV_WMESG(cv) != NULL; 571 1.15 ad } 572