Skip to content

Commit

Permalink
Fix potential lost wakeup in cv_wait(_timed). (#673)
Browse files Browse the repository at this point in the history
Co-authored-by: Krystian Bacławski <[email protected]>
  • Loading branch information
j-piecuch and cahirwpz authored Oct 5, 2020
1 parent 6405b1a commit 19e3f18
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions sys/kern/condvar.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <sys/condvar.h>
#include <sys/sleepq.h>
#include <sys/sched.h>
#include <sys/interrupt.h>
#include <sys/lock.h>

void cv_init(condvar_t *cv, const char *name) {
Expand All @@ -9,17 +10,20 @@ void cv_init(condvar_t *cv, const char *name) {
}

void cv_wait(condvar_t *cv, lock_t m) {
WITH_NO_PREEMPTION {
WITH_INTR_DISABLED {
cv->waiters++;
lk_release(m);
/* If we got interrupted here and an interrupt filter called
* cv_signal, we would have a lost wakeup, so we need interrupts
* to be disabled. Same goes for cv_wait_timed. */
sleepq_wait(cv, __caller(0));
}
lk_acquire(m, __caller(0));
}

int cv_wait_timed(condvar_t *cv, lock_t m, systime_t timeout) {
int status;
WITH_NO_PREEMPTION {
WITH_INTR_DISABLED {
cv->waiters++;
lk_release(m);
status = sleepq_wait_timed(cv, __caller(0), timeout);
Expand Down

0 comments on commit 19e3f18

Please sign in to comment.