fn start(r: *Runnable, thread: *Thread, t: *Threaded) void {
_ = t;
const future: *Future = @fieldParentPtr("runnable", r);
thread.status.store(.{
.cancelation = .none,
.awaitable = .fromFuture(future),
}, .monotonic);
{
const old_status = future.status.fetchOr(.{
.tag = .pending,
.thread = .pack(thread),
}, .release);
assert(old_status.thread == .null);
switch (old_status.tag) {
.pending, .pending_awaited => {},
.pending_canceled => thread.status.store(.{
.cancelation = .canceling,
.awaitable = .fromFuture(future),
}, .monotonic),
.done => unreachable,
}
}
future.func(future.contextPointer(), future.resultPointer());
const had_acknowledged_cancel = switch (thread.status.load(.monotonic).cancelation) {
.none, .canceling => false,
.canceled => true,
.parked => unreachable,
.blocked => unreachable,
.blocked_alertable => unreachable,
.blocked_alertable_canceling => unreachable,
.blocked_canceling => unreachable,
};
thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic);
const old_status = future.status.swap(.{
.tag = .done,
.thread = if (had_acknowledged_cancel) .all_ones else .null,
}, .acq_rel); // acquire `future.awaiter`, release results
switch (old_status.tag) {
.pending => {},
.pending_awaited, .pending_canceled => {
const to_signal = future.awaiter;
_ = to_signal.fetchAdd(1, .release); // release results
Thread.futexWake(&to_signal.raw, 1);
},
.done => unreachable,
}
}