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 21 _cv_timedwait(struct cv *c, struct lock *l, int timo, int wakesig) 22 { 23 int flags = wakesig ? PCATCH : 0; 24 int error; 25 26 spin_lock(&c->cv_lock); 27 tsleep_interlock(c, flags); 28 c->cv_waiters++; 29 spin_unlock(&c->cv_lock); 30 if (l != NULL) 31 lockmgr(l, LK_RELEASE); 32 error = tsleep(c, flags, c->cv_desc, timo); 33 if (l != NULL) 34 lockmgr(l, LK_EXCLUSIVE); 35 36 return (error); 37 } 38 39 void 40 _cv_signal(struct cv *c, int broadcast) 41 { 42 spin_lock(&c->cv_lock); 43 if (c->cv_waiters == 0) 44 goto out; 45 46 if (broadcast) { 47 c->cv_waiters = 0; 48 wakeup(c); 49 } else { 50 c->cv_waiters--; 51 wakeup_one(c); 52 } 53 54 out: 55 spin_unlock(&c->cv_lock); 56 } 57 58 int 59 cv_has_waiters(const struct cv *c) 60 { 61 return (c->cv_waiters); 62 } 63