1 #include <sys/condvar.h>
2 #include <sys/spinlock2.h>
7 cv_init(struct cv
*c
, const char *desc
)
11 spin_init(&c
->cv_lock
, "cvinit");
15 cv_destroy(struct cv
*c
)
17 spin_uninit(&c
->cv_lock
);
21 _cv_timedwait(struct cv
*c
, struct lock
*lk
, int timo
, int wakesig
)
23 int flags
= wakesig
? PCATCH
: 0;
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).
32 tsleep_interlock(c
, flags
);
34 spin_lock(&c
->cv_lock
);
36 spin_unlock(&c
->cv_lock
);
39 error
= lksleep(c
, lk
, flags
| PINTERLOCKED
, c
->cv_desc
, timo
);
41 error
= tsleep(c
, flags
| PINTERLOCKED
, c
->cv_desc
, timo
);
47 * _cv_timedwait() implementation using mtx.
50 _cv_mtx_timedwait(struct cv
*c
, struct mtx
*mtx
, int timo
, int wakesig
)
52 int flags
= wakesig
? PCATCH
: 0;
56 * Can interlock without critical section/spinlock as long
57 * as we don't block before calling *sleep(). PINTERLOCKED
58 * must be passed to the *sleep() to use the manual interlock
59 * (else a new one is created which opens a timing race).
61 tsleep_interlock(c
, flags
);
63 spin_lock(&c
->cv_lock
);
65 spin_unlock(&c
->cv_lock
);
68 error
= mtxsleep(c
, mtx
, flags
| PINTERLOCKED
, c
->cv_desc
, timo
);
70 error
= tsleep(c
, flags
| PINTERLOCKED
, c
->cv_desc
, timo
);
76 _cv_signal(struct cv
*c
, int broadcast
)
78 spin_lock(&c
->cv_lock
);
79 if (c
->cv_waiters
== 0) {
80 spin_unlock(&c
->cv_lock
);
81 } else if (broadcast
) {
83 spin_unlock(&c
->cv_lock
); /* must unlock first */
87 spin_unlock(&c
->cv_lock
); /* must unlock first */
93 cv_has_waiters(const struct cv
*c
)
95 return (c
->cv_waiters
);