addr_hint has no semantic effect, but may allow the OS to optimize this operation.
fn unpark(tids: []const UnparkTid, addr_hint: ?*const anyopaque) void
fn unpark(tids: []const UnparkTid, addr_hint: ?*const anyopaque) void {
comptime assert(use_parking_futex or use_parking_sleep);
switch (native_os) {
.windows => {
// TODO: this condition is currently disabled because mingw-w64 does not contain this
// symbol. Once it's added, enable this check to use the new bulk API where possible.
if (false and (builtin.os.version_range.windows.isAtLeast(.win11_dt) orelse false)) {
_ = windows.ntdll.NtAlertMultipleThreadByThreadId(tids.ptr, @intCast(tids.len), null, null);
} else {
for (tids) |tid| {
_ = windows.ntdll.NtAlertThreadByThreadId(@intCast(tid));
}
}
},
.netbsd => {
switch (posix.errno(std.c._lwp_unpark_all(@ptrCast(tids.ptr), tids.len, addr_hint))) {
.SUCCESS => return,
// For errors, fall through to a loop over `tids`, though this is only expected to
// be possible for ENOMEM (even that is questionable) and ESRCH (see comment below).
.SRCH => {},
.FAULT => recoverableOsBugDetected(),
.INVAL => recoverableOsBugDetected(),
.NOMEM => {},
else => recoverableOsBugDetected(),
}
for (tids) |tid| {
switch (posix.errno(std.c._lwp_unpark(@bitCast(tid), addr_hint))) {
.SUCCESS => {},
.SRCH => {
// This can happen in a rare race: the thread might have been spuriously
// unparked, so already observed the changing status, and from there have
// exited. That's okay, because the thread has woken up like we wanted.
},
else => recoverableOsBugDetected(),
}
}
},
.illumos => @panic("TODO: illumos lwp_unpark"),
else => comptime unreachable,
}
}