| Commit | Line | Data |
|---|---|---|
| 6830d0fc SS |
1 | #include <sys/condvar.h> |
| 2 | #include <sys/spinlock2.h> | |
| 3 | #include <sys/systm.h> | |
| 4 | #include <sys/lock.h> | |
| 5 | ||
| 6 | void | |
| 7 | cv_init(struct cv *c, const char *desc) | |
| 8 | { | |
| 9 | c->cv_desc = desc; | |
| 10 | c->cv_waiters = 0; | |
| 11 | spin_init(&c->cv_lock); | |
| 12 | } | |
| 13 | ||
| 14 | void | |
| 15 | cv_destroy(struct cv *c) | |
| 16 | { | |
| 17 | spin_uninit(&c->cv_lock); | |
| 18 | } | |
| 19 | ||
| 20 | int | |
| a5fcdfa4 | 21 | _cv_timedwait(struct cv *c, struct lock *lk, int timo, int wakesig) |
| 6830d0fc SS |
22 | { |
| 23 | int flags = wakesig ? PCATCH : 0; | |
| 24 | int error; | |
| 25 | ||
| a5fcdfa4 MD |
26 | /* |
| 27 | * Can interlock without critical section/spinlock as long | |
| 28 | * as we don't block before calling *sleep(). PINTERLOCKED | |
| 29 | * must be passed to the *sleep() to use the manual interlock | |
| 30 | * (else a new one is created which opens a timing race). | |
| 31 | */ | |
| 6830d0fc | 32 | tsleep_interlock(c, flags); |
| a5fcdfa4 MD |
33 | |
| 34 | spin_lock(&c->cv_lock); | |
| 6830d0fc | 35 | c->cv_waiters++; |
| 287a8577 | 36 | spin_unlock(&c->cv_lock); |
| a5fcdfa4 MD |
37 | |
| 38 | if (lk) | |
| 39 | error = lksleep(c, lk, flags | PINTERLOCKED, c->cv_desc, timo); | |
| 40 | else | |
| 41 | error = tsleep(c, flags | PINTERLOCKED, c->cv_desc, timo); | |
| 6830d0fc SS |
42 | |
| 43 | return (error); | |
| 44 | } | |
| 45 | ||
| 46 | void | |
| 47 | _cv_signal(struct cv *c, int broadcast) | |
| 48 | { | |
| 287a8577 | 49 | spin_lock(&c->cv_lock); |
| a5fcdfa4 MD |
50 | if (c->cv_waiters == 0) { |
| 51 | spin_unlock(&c->cv_lock); | |
| 52 | } else if (broadcast) { | |
| 6830d0fc | 53 | c->cv_waiters = 0; |
| a5fcdfa4 | 54 | spin_unlock(&c->cv_lock); /* must unlock first */ |
| 6830d0fc SS |
55 | wakeup(c); |
| 56 | } else { | |
| 57 | c->cv_waiters--; | |
| a5fcdfa4 | 58 | spin_unlock(&c->cv_lock); /* must unlock first */ |
| 6830d0fc SS |
59 | wakeup_one(c); |
| 60 | } | |
| 6830d0fc | 61 | } |
| 70f34aab AH |
62 | |
| 63 | int | |
| c67284ab | 64 | cv_has_waiters(const struct cv *c) |
| 70f34aab AH |
65 | { |
| 66 | return (c->cv_waiters); | |
| 67 | } |