xref: /dragonfly/sys/kern/kern_condvar.c (revision 52f9f0d9)
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