Same as Io.Condition.waitUncancelable but avoids the VTable.
fn condWait(cond: *Io.Condition, mutex: *Io.Mutex) void
fn condWait(cond: *Io.Condition, mutex: *Io.Mutex) void {
var epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before state load
{
const prev_state = cond.state.fetchAdd(.{ .waiters = 1, .signals = 0 }, .monotonic);
assert(prev_state.waiters < std.math.maxInt(u16)); // overflow caused by too many waiters
}
mutexUnlock(mutex);
defer mutexLock(mutex);
while (true) {
Thread.futexWaitUncancelable(&cond.epoch.raw, epoch, null);
epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before `state` laod
var prev_state = cond.state.load(.monotonic);
while (prev_state.signals > 0) {
prev_state = cond.state.cmpxchgWeak(prev_state, .{
.waiters = prev_state.waiters - 1,
.signals = prev_state.signals - 1,
}, .acquire, .monotonic) orelse {
// We successfully consumed a signal.
return;
};
}
}
}