Skip to content

Commit dd72991

Browse files
authored
Merge branch 'master' into eliza/psc-seq-ereport
2 parents 4390797 + dd76a4c commit dd72991

1 file changed

Lines changed: 28 additions & 13 deletions

File tree

drv/stm32xx-i2c/src/lib.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,18 +1196,33 @@ fn wfi_raw(event_mask: u32, timeout: I2cTimeout) -> I2cControlResult {
11961196

11971197
sys_set_timer(Some(dead), TIMER_NOTIFICATION);
11981198

1199-
let received = sys_recv_notification(event_mask | TIMER_NOTIFICATION);
1200-
1201-
// If the event arrived _and_ our timer went off, prioritize the event and
1202-
// ignore the timeout.
1203-
if received & event_mask != 0 {
1204-
// Attempt to clear our timer. Note that this does not protect against
1205-
// the race where the kernel decided to wake us up, but the timer went
1206-
// off before we got to this point.
1207-
sys_set_timer(None, TIMER_NOTIFICATION);
1208-
I2cControlResult::Interrupted
1209-
} else {
1210-
// The event_mask bit was not set, so:
1211-
I2cControlResult::TimedOut
1199+
loop {
1200+
let received = sys_recv_notification(event_mask | TIMER_NOTIFICATION);
1201+
1202+
// If the event arrived _and_ our timer went off, prioritize the event and
1203+
// ignore the timeout.
1204+
if received & event_mask != 0 {
1205+
// Attempt to clear our timer. Note that this does not protect against
1206+
// the race where the kernel decided to wake us up, but the timer went
1207+
// off before we got to this point.
1208+
sys_set_timer(None, TIMER_NOTIFICATION);
1209+
break I2cControlResult::Interrupted;
1210+
} else {
1211+
// The timer bit must have been set. Verify that our timer has
1212+
// actually expired:
1213+
if sys_get_timer().now >= dead {
1214+
break I2cControlResult::TimedOut;
1215+
}
1216+
1217+
// Otherwise, one of two things has happened:
1218+
// 1. Some joker has posted to our timer bit. Ha ha very funny.
1219+
// 2. The timer bit was _already set_ on entry to this routine, as a
1220+
// hangover from a previous run.
1221+
//
1222+
// We don't need to re-set our timer here because we sampled
1223+
// sys_get_timer _after_ receiving notifications, meaning it either
1224+
// hasn't gone off, or it has gone off but that fact is still stored
1225+
// in our notification bits.
1226+
}
12121227
}
12131228
}

0 commit comments

Comments
 (0)