| ... | @@ -5,6 +5,7 @@ const native_os = builtin.os.tag; | ... | @@ -5,6 +5,7 @@ const native_os = builtin.os.tag; |
| 5 | const is_windows = native_os == .windows; | 5 | const is_windows = native_os == .windows; |
| 6 | const windows = std.os.windows; | 6 | const windows = std.os.windows; |
| 7 | const ws2_32 = std.os.windows.ws2_32; | 7 | const ws2_32 = std.os.windows.ws2_32; |
| | 8 | const is_debug = builtin.mode == .Debug; |
| 8 | | 9 | |
| 9 | const std = @import("../std.zig"); | 10 | const std = @import("../std.zig"); |
| 10 | const Io = std.Io; | 11 | const Io = std.Io; |
| ... | @@ -72,11 +73,13 @@ const Closure = struct { | ... | @@ -72,11 +73,13 @@ const Closure = struct { |
| 72 | fn requestCancel(closure: *Closure) void { | 73 | fn requestCancel(closure: *Closure) void { |
| 73 | switch (@atomicRmw(CancelId, &closure.cancel_tid, .Xchg, .canceling, .acq_rel)) { | 74 | switch (@atomicRmw(CancelId, &closure.cancel_tid, .Xchg, .canceling, .acq_rel)) { |
| 74 | .none, .canceling => {}, | 75 | .none, .canceling => {}, |
| 75 | else => |tid| switch (native_os) { | 76 | else => |tid| { |
| 76 | .linux => _ = std.os.linux.tgkill(std.os.linux.getpid(), @bitCast(tid.toThreadId()), posix.SIG.IO), | 77 | if (std.Thread.use_pthreads) { |
| 77 | else => if (std.Thread.use_pthreads) { | 78 | const rc = std.c.pthread_kill(tid.toThreadId(), posix.SIG.IO); |
| 78 | assert(std.c.pthread_kill(tid.toThreadId(), posix.SIG.IO) == 0); | 79 | if (is_debug) assert(rc == 0); |
| 79 | }, | 80 | } else if (native_os == .linux) { |
| | 81 | _ = std.os.linux.tgkill(std.os.linux.getpid(), @bitCast(tid.toThreadId()), posix.SIG.IO); |
| | 82 | } |
| 80 | }, | 83 | }, |
| 81 | } | 84 | } |
| 82 | } | 85 | } |
| ... | @@ -4883,17 +4886,13 @@ fn address6ToPosix(a: *const net.Ip6Address) posix.sockaddr.in6 { | ... | @@ -4883,17 +4886,13 @@ fn address6ToPosix(a: *const net.Ip6Address) posix.sockaddr.in6 { |
| 4883 | } | 4886 | } |
| 4884 | | 4887 | |
| 4885 | pub fn errnoBug(err: posix.E) Io.UnexpectedError { | 4888 | pub fn errnoBug(err: posix.E) Io.UnexpectedError { |
| 4886 | switch (builtin.mode) { | 4889 | if (is_debug) std.debug.panic("programmer bug caused syscall error: {t}", .{err}); |
| 4887 | .Debug => std.debug.panic("programmer bug caused syscall error: {t}", .{err}), | 4890 | return error.Unexpected; |
| 4888 | else => return error.Unexpected, | | |
| 4889 | } | | |
| 4890 | } | 4891 | } |
| 4891 | | 4892 | |
| 4892 | fn wsaErrorBug(err: ws2_32.WinsockError) Io.UnexpectedError { | 4893 | fn wsaErrorBug(err: ws2_32.WinsockError) Io.UnexpectedError { |
| 4893 | switch (builtin.mode) { | 4894 | if (is_debug) std.debug.panic("programmer bug caused syscall error: {t}", .{err}); |
| 4894 | .Debug => std.debug.panic("programmer bug caused syscall error: {t}", .{err}), | 4895 | return error.Unexpected; |
| 4895 | else => return error.Unexpected, | | |
| 4896 | } | | |
| 4897 | } | 4896 | } |
| 4898 | | 4897 | |
| 4899 | pub fn posixSocketMode(mode: net.Socket.Mode) u32 { | 4898 | pub fn posixSocketMode(mode: net.Socket.Mode) u32 { |
| ... | @@ -4911,7 +4910,7 @@ pub fn posixProtocol(protocol: ?net.Protocol) u32 { | ... | @@ -4911,7 +4910,7 @@ pub fn posixProtocol(protocol: ?net.Protocol) u32 { |
| 4911 | } | 4910 | } |
| 4912 | | 4911 | |
| 4913 | fn recoverableOsBugDetected() void { | 4912 | fn recoverableOsBugDetected() void { |
| 4914 | if (builtin.mode == .Debug) unreachable; | 4913 | if (is_debug) unreachable; |
| 4915 | } | 4914 | } |
| 4916 | | 4915 | |
| 4917 | fn clockToPosix(clock: Io.Clock) posix.clockid_t { | 4916 | fn clockToPosix(clock: Io.Clock) posix.clockid_t { |
| ... | @@ -5424,7 +5423,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca | ... | @@ -5424,7 +5423,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca |
| 5424 | const linux = std.os.linux; | 5423 | const linux = std.os.linux; |
| 5425 | try t.checkCancel(); | 5424 | try t.checkCancel(); |
| 5426 | const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null); | 5425 | const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null); |
| 5427 | if (builtin.mode == .Debug) switch (linux.E.init(rc)) { | 5426 | if (is_debug) switch (linux.E.init(rc)) { |
| 5428 | .SUCCESS => {}, // notified by `wake()` | 5427 | .SUCCESS => {}, // notified by `wake()` |
| 5429 | .INTR => {}, // gives caller a chance to check cancellation | 5428 | .INTR => {}, // gives caller a chance to check cancellation |
| 5430 | .AGAIN => {}, // ptr.* != expect | 5429 | .AGAIN => {}, // ptr.* != expect |
| ... | @@ -5447,7 +5446,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca | ... | @@ -5447,7 +5446,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca |
| 5447 | | 5446 | |
| 5448 | if (status >= 0) return; | 5447 | if (status >= 0) return; |
| 5449 | | 5448 | |
| 5450 | if (builtin.mode == .Debug) switch (@as(c.E, @enumFromInt(-status))) { | 5449 | if (is_debug) switch (@as(c.E, @enumFromInt(-status))) { |
| 5451 | // Wait was interrupted by the OS or other spurious signalling. | 5450 | // Wait was interrupted by the OS or other spurious signalling. |
| 5452 | .INTR => {}, | 5451 | .INTR => {}, |
| 5453 | // Address of the futex was paged out. This is unlikely, but possible in theory, and | 5452 | // Address of the futex was paged out. This is unlikely, but possible in theory, and |
| ... | @@ -5473,7 +5472,6 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca | ... | @@ -5473,7 +5472,6 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca |
| 5473 | [expected] "r" (signed_expect), | 5472 | [expected] "r" (signed_expect), |
| 5474 | [timeout] "r" (timeout), | 5473 | [timeout] "r" (timeout), |
| 5475 | ); | 5474 | ); |
| 5476 | const is_debug = builtin.mode == .Debug; | | |
| 5477 | switch (result) { | 5475 | switch (result) { |
| 5478 | 0 => {}, // ok | 5476 | 0 => {}, // ok |
| 5479 | 1 => {}, // expected != loaded | 5477 | 1 => {}, // expected != loaded |
| ... | @@ -5498,7 +5496,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi | ... | @@ -5498,7 +5496,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi |
| 5498 | if (native_os == .linux) { | 5496 | if (native_os == .linux) { |
| 5499 | const linux = std.os.linux; | 5497 | const linux = std.os.linux; |
| 5500 | const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null); | 5498 | const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null); |
| 5501 | if (builtin.mode == .Debug) switch (linux.E.init(rc)) { | 5499 | if (is_debug) switch (linux.E.init(rc)) { |
| 5502 | .SUCCESS => {}, // notified by `wake()` | 5500 | .SUCCESS => {}, // notified by `wake()` |
| 5503 | .INTR => {}, // gives caller a chance to check cancellation | 5501 | .INTR => {}, // gives caller a chance to check cancellation |
| 5504 | .AGAIN => {}, // ptr.* != expect | 5502 | .AGAIN => {}, // ptr.* != expect |
| ... | @@ -5520,7 +5518,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi | ... | @@ -5520,7 +5518,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi |
| 5520 | | 5518 | |
| 5521 | if (status >= 0) return; | 5519 | if (status >= 0) return; |
| 5522 | | 5520 | |
| 5523 | if (builtin.mode == .Debug) switch (@as(c.E, @enumFromInt(-status))) { | 5521 | if (is_debug) switch (@as(c.E, @enumFromInt(-status))) { |
| 5524 | // Wait was interrupted by the OS or other spurious signalling. | 5522 | // Wait was interrupted by the OS or other spurious signalling. |
| 5525 | .INTR => {}, | 5523 | .INTR => {}, |
| 5526 | // Address of the futex was paged out. This is unlikely, but possible in theory, and | 5524 | // Address of the futex was paged out. This is unlikely, but possible in theory, and |
| ... | @@ -5545,7 +5543,6 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi | ... | @@ -5545,7 +5543,6 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi |
| 5545 | [expected] "r" (signed_expect), | 5543 | [expected] "r" (signed_expect), |
| 5546 | [timeout] "r" (timeout), | 5544 | [timeout] "r" (timeout), |
| 5547 | ); | 5545 | ); |
| 5548 | const is_debug = builtin.mode == .Debug; | | |
| 5549 | switch (result) { | 5546 | switch (result) { |
| 5550 | 0 => {}, // ok | 5547 | 0 => {}, // ok |
| 5551 | 1 => {}, // expected != loaded | 5548 | 1 => {}, // expected != loaded |
| ... | @@ -5569,7 +5566,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect: | ... | @@ -5569,7 +5566,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect: |
| 5569 | const linux = std.os.linux; | 5566 | const linux = std.os.linux; |
| 5570 | var ts = timestampToPosix(timeout.toNanoseconds()); | 5567 | var ts = timestampToPosix(timeout.toNanoseconds()); |
| 5571 | const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts); | 5568 | const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts); |
| 5572 | if (builtin.mode == .Debug) switch (linux.E.init(rc)) { | 5569 | if (is_debug) switch (linux.E.init(rc)) { |
| 5573 | .SUCCESS => {}, // notified by `wake()` | 5570 | .SUCCESS => {}, // notified by `wake()` |
| 5574 | .INTR => {}, // gives caller a chance to check cancellation | 5571 | .INTR => {}, // gives caller a chance to check cancellation |
| 5575 | .AGAIN => {}, // ptr.* != expect | 5572 | .AGAIN => {}, // ptr.* != expect |
| ... | @@ -5594,7 +5591,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void { | ... | @@ -5594,7 +5591,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void { |
| 5594 | .{ .cmd = .WAKE, .private = true }, | 5591 | .{ .cmd = .WAKE, .private = true }, |
| 5595 | @min(max_waiters, std.math.maxInt(i32)), | 5592 | @min(max_waiters, std.math.maxInt(i32)), |
| 5596 | ); | 5593 | ); |
| 5597 | if (builtin.mode == .Debug) switch (linux.E.init(rc)) { | 5594 | if (is_debug) switch (linux.E.init(rc)) { |
| 5598 | .SUCCESS => {}, // successful wake up | 5595 | .SUCCESS => {}, // successful wake up |
| 5599 | .INVAL => {}, // invalid futex_wait() on ptr done elsewhere | 5596 | .INVAL => {}, // invalid futex_wait() on ptr done elsewhere |
| 5600 | .FAULT => {}, // pointer became invalid while doing the wake | 5597 | .FAULT => {}, // pointer became invalid while doing the wake |
| ... | @@ -5607,7 +5604,6 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void { | ... | @@ -5607,7 +5604,6 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void { |
| 5607 | .NO_ERRNO = true, | 5604 | .NO_ERRNO = true, |
| 5608 | .WAKE_ALL = max_waiters > 1, | 5605 | .WAKE_ALL = max_waiters > 1, |
| 5609 | }; | 5606 | }; |
| 5610 | const is_debug = builtin.mode == .Debug; | | |
| 5611 | while (true) { | 5607 | while (true) { |
| 5612 | const status = c.__ulock_wake(flags, ptr, 0); | 5608 | const status = c.__ulock_wake(flags, ptr, 0); |
| 5613 | if (status >= 0) return; | 5609 | if (status >= 0) return; |
| ... | @@ -5756,7 +5752,7 @@ pub const ResetEvent = enum(u32) { | ... | @@ -5756,7 +5752,7 @@ pub const ResetEvent = enum(u32) { |
| 5756 | | 5752 | |
| 5757 | fn closeSocketWindows(s: ws2_32.SOCKET) void { | 5753 | fn closeSocketWindows(s: ws2_32.SOCKET) void { |
| 5758 | const rc = ws2_32.closesocket(s); | 5754 | const rc = ws2_32.closesocket(s); |
| 5759 | if (builtin.mode == .Debug) switch (rc) { | 5755 | if (is_debug) switch (rc) { |
| 5760 | 0 => {}, | 5756 | 0 => {}, |
| 5761 | ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) { | 5757 | ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) { |
| 5762 | else => recoverableOsBugDetected(), | 5758 | else => recoverableOsBugDetected(), |