| ... | ... | @@ -29,8 +29,8 @@ const ws2_32 = std.os.windows.ws2_32; |
| 29 | 29 | /// * scanning environment variables on some targets |
| 30 | 30 | /// * memory-mapping when mmap or equivalent is not available |
| 31 | 31 | allocator: Allocator, |
| 32 | | mutex: Mutex = .init, |
| 33 | | cond: Condition = .init, |
| 32 | mutex: Io.Mutex = .init, |
| 33 | cond: Io.Condition = .init, |
| 34 | 34 | run_queue: std.SinglyLinkedList = .{}, |
| 35 | 35 | join_requested: bool = false, |
| 36 | 36 | stack_size: usize, |
| ... | ... | @@ -1505,8 +1505,8 @@ var global_single_threaded_instance: Threaded = .init_single_threaded; |
| 1505 | 1505 | pub const global_single_threaded: *Threaded = &global_single_threaded_instance; |
| 1506 | 1506 | |
| 1507 | 1507 | pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void { |
| 1508 | | mutexLockInternal(&t.mutex); |
| 1509 | | defer mutexUnlockInternal(&t.mutex); |
| 1508 | mutexLock(&t.mutex); |
| 1509 | defer mutexUnlock(&t.mutex); |
| 1510 | 1510 | t.async_limit = new_limit; |
| 1511 | 1511 | } |
| 1512 | 1512 | |
| ... | ... | @@ -1527,8 +1527,8 @@ pub fn deinit(t: *Threaded) void { |
| 1527 | 1527 | fn join(t: *Threaded) void { |
| 1528 | 1528 | if (builtin.single_threaded) return; |
| 1529 | 1529 | { |
| 1530 | | mutexLockInternal(&t.mutex); |
| 1531 | | defer mutexUnlockInternal(&t.mutex); |
| 1530 | mutexLock(&t.mutex); |
| 1531 | defer mutexUnlock(&t.mutex); |
| 1532 | 1532 | t.join_requested = true; |
| 1533 | 1533 | } |
| 1534 | 1534 | condBroadcast(&t.cond); |
| ... | ... | @@ -1593,16 +1593,16 @@ fn worker(t: *Threaded) void { |
| 1593 | 1593 | |
| 1594 | 1594 | defer t.wait_group.finish(); |
| 1595 | 1595 | |
| 1596 | | mutexLockInternal(&t.mutex); |
| 1597 | | defer mutexUnlockInternal(&t.mutex); |
| 1596 | mutexLock(&t.mutex); |
| 1597 | defer mutexUnlock(&t.mutex); |
| 1598 | 1598 | |
| 1599 | 1599 | while (true) { |
| 1600 | 1600 | while (t.run_queue.popFirst()) |runnable_node| { |
| 1601 | | mutexUnlockInternal(&t.mutex); |
| 1601 | mutexUnlock(&t.mutex); |
| 1602 | 1602 | thread.cancel_protection = .unblocked; |
| 1603 | 1603 | const runnable: *Runnable = @fieldParentPtr("node", runnable_node); |
| 1604 | 1604 | runnable.startFn(runnable, &thread, t); |
| 1605 | | mutexLockInternal(&t.mutex); |
| 1605 | mutexLock(&t.mutex); |
| 1606 | 1606 | t.busy_count -= 1; |
| 1607 | 1607 | } |
| 1608 | 1608 | if (t.join_requested) break; |
| ... | ... | @@ -2025,12 +2025,12 @@ fn async( |
| 2025 | 2025 | }, |
| 2026 | 2026 | }; |
| 2027 | 2027 | |
| 2028 | | mutexLockInternal(&t.mutex); |
| 2028 | mutexLock(&t.mutex); |
| 2029 | 2029 | |
| 2030 | 2030 | const busy_count = t.busy_count; |
| 2031 | 2031 | |
| 2032 | 2032 | if (busy_count >= @intFromEnum(t.async_limit)) { |
| 2033 | | mutexUnlockInternal(&t.mutex); |
| 2033 | mutexUnlock(&t.mutex); |
| 2034 | 2034 | future.destroy(gpa); |
| 2035 | 2035 | start(context.ptr, result.ptr); |
| 2036 | 2036 | return null; |
| ... | ... | @@ -2044,7 +2044,7 @@ fn async( |
| 2044 | 2044 | const thread = std.Thread.spawn(.{ .stack_size = t.stack_size }, worker, .{t}) catch { |
| 2045 | 2045 | t.wait_group.finish(); |
| 2046 | 2046 | t.busy_count = busy_count; |
| 2047 | | mutexUnlockInternal(&t.mutex); |
| 2047 | mutexUnlock(&t.mutex); |
| 2048 | 2048 | future.destroy(gpa); |
| 2049 | 2049 | start(context.ptr, result.ptr); |
| 2050 | 2050 | return null; |
| ... | ... | @@ -2054,7 +2054,7 @@ fn async( |
| 2054 | 2054 | |
| 2055 | 2055 | t.run_queue.prepend(&future.runnable.node); |
| 2056 | 2056 | |
| 2057 | | mutexUnlockInternal(&t.mutex); |
| 2057 | mutexUnlock(&t.mutex); |
| 2058 | 2058 | condSignal(&t.cond); |
| 2059 | 2059 | return @ptrCast(future); |
| 2060 | 2060 | } |
| ... | ... | @@ -2077,8 +2077,8 @@ fn concurrent( |
| 2077 | 2077 | }; |
| 2078 | 2078 | errdefer future.destroy(gpa); |
| 2079 | 2079 | |
| 2080 | | mutexLockInternal(&t.mutex); |
| 2081 | | defer mutexUnlockInternal(&t.mutex); |
| 2080 | mutexLock(&t.mutex); |
| 2081 | defer mutexUnlock(&t.mutex); |
| 2082 | 2082 | |
| 2083 | 2083 | const busy_count = t.busy_count; |
| 2084 | 2084 | |
| ... | ... | @@ -2122,12 +2122,12 @@ fn groupAsync( |
| 2122 | 2122 | error.OutOfMemory => return groupAsyncEager(start, context.ptr), |
| 2123 | 2123 | }; |
| 2124 | 2124 | |
| 2125 | | mutexLockInternal(&t.mutex); |
| 2125 | mutexLock(&t.mutex); |
| 2126 | 2126 | |
| 2127 | 2127 | const busy_count = t.busy_count; |
| 2128 | 2128 | |
| 2129 | 2129 | if (busy_count >= @intFromEnum(t.async_limit)) { |
| 2130 | | mutexUnlockInternal(&t.mutex); |
| 2130 | mutexUnlock(&t.mutex); |
| 2131 | 2131 | task.destroy(gpa); |
| 2132 | 2132 | return groupAsyncEager(start, context.ptr); |
| 2133 | 2133 | } |
| ... | ... | @@ -2140,7 +2140,7 @@ fn groupAsync( |
| 2140 | 2140 | const thread = std.Thread.spawn(.{ .stack_size = t.stack_size }, worker, .{t}) catch { |
| 2141 | 2141 | t.wait_group.finish(); |
| 2142 | 2142 | t.busy_count = busy_count; |
| 2143 | | mutexUnlockInternal(&t.mutex); |
| 2143 | mutexUnlock(&t.mutex); |
| 2144 | 2144 | task.destroy(gpa); |
| 2145 | 2145 | return groupAsyncEager(start, context.ptr); |
| 2146 | 2146 | }; |
| ... | ... | @@ -2157,7 +2157,7 @@ fn groupAsync( |
| 2157 | 2157 | }, .monotonic); |
| 2158 | 2158 | t.run_queue.prepend(&task.runnable.node); |
| 2159 | 2159 | |
| 2160 | | mutexUnlockInternal(&t.mutex); |
| 2160 | mutexUnlock(&t.mutex); |
| 2161 | 2161 | condSignal(&t.cond); |
| 2162 | 2162 | } |
| 2163 | 2163 | fn groupAsyncEager( |
| ... | ... | @@ -2222,8 +2222,8 @@ fn groupConcurrent( |
| 2222 | 2222 | }; |
| 2223 | 2223 | errdefer task.destroy(gpa); |
| 2224 | 2224 | |
| 2225 | | mutexLockInternal(&t.mutex); |
| 2226 | | defer mutexUnlockInternal(&t.mutex); |
| 2225 | mutexLock(&t.mutex); |
| 2226 | defer mutexUnlock(&t.mutex); |
| 2227 | 2227 | |
| 2228 | 2228 | const busy_count = t.busy_count; |
| 2229 | 2229 | |
| ... | ... | @@ -3847,8 +3847,8 @@ fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat { |
| 3847 | 3847 | |
| 3848 | 3848 | fn systemBasicInformation(t: *Threaded) ?*const windows.SYSTEM_BASIC_INFORMATION { |
| 3849 | 3849 | if (!t.system_basic_information.initialized.load(.acquire)) { |
| 3850 | | mutexLockInternal(&t.mutex); |
| 3851 | | defer mutexUnlockInternal(&t.mutex); |
| 3850 | mutexLock(&t.mutex); |
| 3851 | defer mutexUnlock(&t.mutex); |
| 3852 | 3852 | |
| 3853 | 3853 | switch (windows.ntdll.NtQuerySystemInformation( |
| 3854 | 3854 | .SystemBasicInformation, |
| ... | ... | @@ -14359,10 +14359,9 @@ const Wsa = struct { |
| 14359 | 14359 | }; |
| 14360 | 14360 | |
| 14361 | 14361 | fn initializeWsa(t: *Threaded) error{ NetworkDown, Canceled }!void { |
| 14362 | | const t_io = io(t); |
| 14363 | 14362 | const wsa = &t.wsa; |
| 14364 | | try wsa.mutex.lock(t_io); |
| 14365 | | defer wsa.mutex.unlock(t_io); |
| 14363 | try mutexLock(&wsa.mutex); |
| 14364 | defer mutexUnlock(&wsa.mutex); |
| 14366 | 14365 | switch (wsa.status) { |
| 14367 | 14366 | .uninitialized => { |
| 14368 | 14367 | var wsa_data: ws2_32.WSADATA = undefined; |
| ... | ... | @@ -14433,8 +14432,8 @@ const WindowsEnvironStrings = struct { |
| 14433 | 14432 | }; |
| 14434 | 14433 | |
| 14435 | 14434 | fn scanEnviron(t: *Threaded) void { |
| 14436 | | mutexLockInternal(&t.mutex); |
| 14437 | | defer mutexUnlockInternal(&t.mutex); |
| 14435 | mutexLock(&t.mutex); |
| 14436 | defer mutexUnlock(&t.mutex); |
| 14438 | 14437 | |
| 14439 | 14438 | if (t.environ.initialized) return; |
| 14440 | 14439 | t.environ.initialized = true; |
| ... | ... | @@ -14789,8 +14788,8 @@ fn spawnPosix(t: *Threaded, options: process.SpawnOptions) process.SpawnError!Sp |
| 14789 | 14788 | |
| 14790 | 14789 | fn getDevNullFd(t: *Threaded) !posix.fd_t { |
| 14791 | 14790 | { |
| 14792 | | mutexLockInternal(&t.mutex); |
| 14793 | | defer mutexUnlockInternal(&t.mutex); |
| 14791 | mutexLock(&t.mutex); |
| 14792 | defer mutexUnlock(&t.mutex); |
| 14794 | 14793 | if (t.null_file.fd != -1) return t.null_file.fd; |
| 14795 | 14794 | } |
| 14796 | 14795 | const mode: u32 = 0; |
| ... | ... | @@ -14801,8 +14800,8 @@ fn getDevNullFd(t: *Threaded) !posix.fd_t { |
| 14801 | 14800 | .SUCCESS => { |
| 14802 | 14801 | syscall.finish(); |
| 14803 | 14802 | const fresh_fd: posix.fd_t = @intCast(rc); |
| 14804 | | mutexLockInternal(&t.mutex); // Another thread might have won the race. |
| 14805 | | defer mutexUnlockInternal(&t.mutex); |
| 14803 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 14804 | defer mutexUnlock(&t.mutex); |
| 14806 | 14805 | if (t.null_file.fd != -1) { |
| 14807 | 14806 | posix.close(fresh_fd); |
| 14808 | 14807 | return t.null_file.fd; |
| ... | ... | @@ -15462,8 +15461,8 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro |
| 15462 | 15461 | |
| 15463 | 15462 | fn getCngHandle(t: *Threaded) Io.RandomSecureError!windows.HANDLE { |
| 15464 | 15463 | { |
| 15465 | | mutexLockInternal(&t.mutex); |
| 15466 | | defer mutexUnlockInternal(&t.mutex); |
| 15464 | mutexLock(&t.mutex); |
| 15465 | defer mutexUnlock(&t.mutex); |
| 15467 | 15466 | if (t.random_file.handle) |handle| return handle; |
| 15468 | 15467 | } |
| 15469 | 15468 | |
| ... | ... | @@ -15497,8 +15496,8 @@ fn getCngHandle(t: *Threaded) Io.RandomSecureError!windows.HANDLE { |
| 15497 | 15496 | )) { |
| 15498 | 15497 | .SUCCESS => { |
| 15499 | 15498 | syscall.finish(); |
| 15500 | | mutexLockInternal(&t.mutex); // Another thread might have won the race. |
| 15501 | | defer mutexUnlockInternal(&t.mutex); |
| 15499 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 15500 | defer mutexUnlock(&t.mutex); |
| 15502 | 15501 | if (t.random_file.handle) |prev_handle| { |
| 15503 | 15502 | windows.CloseHandle(fresh_handle); |
| 15504 | 15503 | return prev_handle; |
| ... | ... | @@ -15518,8 +15517,8 @@ fn getCngHandle(t: *Threaded) Io.RandomSecureError!windows.HANDLE { |
| 15518 | 15517 | |
| 15519 | 15518 | fn getNulHandle(t: *Threaded) !windows.HANDLE { |
| 15520 | 15519 | { |
| 15521 | | mutexLockInternal(&t.mutex); |
| 15522 | | defer mutexUnlockInternal(&t.mutex); |
| 15520 | mutexLock(&t.mutex); |
| 15521 | defer mutexUnlock(&t.mutex); |
| 15523 | 15522 | if (t.null_file.handle) |handle| return handle; |
| 15524 | 15523 | } |
| 15525 | 15524 | |
| ... | ... | @@ -15565,8 +15564,8 @@ fn getNulHandle(t: *Threaded) !windows.HANDLE { |
| 15565 | 15564 | )) { |
| 15566 | 15565 | .SUCCESS => { |
| 15567 | 15566 | syscall.finish(); |
| 15568 | | mutexLockInternal(&t.mutex); // Another thread might have won the race. |
| 15569 | | defer mutexUnlockInternal(&t.mutex); |
| 15567 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 15568 | defer mutexUnlock(&t.mutex); |
| 15570 | 15569 | if (t.null_file.handle) |prev_handle| { |
| 15571 | 15570 | windows.CloseHandle(fresh_handle); |
| 15572 | 15571 | return prev_handle; |
| ... | ... | @@ -16611,15 +16610,15 @@ fn random(userdata: ?*anyopaque, buffer: []u8) void { |
| 16611 | 16610 | } |
| 16612 | 16611 | |
| 16613 | 16612 | fn randomMainThread(t: *Threaded, buffer: []u8) void { |
| 16614 | | mutexLockInternal(&t.mutex); |
| 16615 | | defer mutexUnlockInternal(&t.mutex); |
| 16613 | mutexLock(&t.mutex); |
| 16614 | defer mutexUnlock(&t.mutex); |
| 16616 | 16615 | |
| 16617 | 16616 | if (!t.csprng.isInitialized()) { |
| 16618 | 16617 | @branchHint(.unlikely); |
| 16619 | 16618 | var seed: [Csprng.seed_len]u8 = undefined; |
| 16620 | 16619 | { |
| 16621 | | mutexUnlockInternal(&t.mutex); |
| 16622 | | defer mutexLockInternal(&t.mutex); |
| 16620 | mutexUnlock(&t.mutex); |
| 16621 | defer mutexLock(&t.mutex); |
| 16623 | 16622 | |
| 16624 | 16623 | const prev = swapCancelProtection(t, .blocked); |
| 16625 | 16624 | defer _ = swapCancelProtection(t, prev); |
| ... | ... | @@ -16804,8 +16803,8 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void { |
| 16804 | 16803 | |
| 16805 | 16804 | fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |
| 16806 | 16805 | { |
| 16807 | | mutexLockInternal(&t.mutex); |
| 16808 | | defer mutexUnlockInternal(&t.mutex); |
| 16806 | mutexLock(&t.mutex); |
| 16807 | defer mutexUnlock(&t.mutex); |
| 16809 | 16808 | |
| 16810 | 16809 | if (t.random_file.fd == -2) return error.EntropyUnavailable; |
| 16811 | 16810 | if (t.random_file.fd != -1) return t.random_file.fd; |
| ... | ... | @@ -16845,8 +16844,8 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |
| 16845 | 16844 | .SUCCESS => { |
| 16846 | 16845 | syscall.finish(); |
| 16847 | 16846 | if (!statx.mask.TYPE) return error.EntropyUnavailable; |
| 16848 | | mutexLockInternal(&t.mutex); // Another thread might have won the race. |
| 16849 | | defer mutexUnlockInternal(&t.mutex); |
| 16847 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 16848 | defer mutexUnlock(&t.mutex); |
| 16850 | 16849 | if (t.random_file.fd >= 0) { |
| 16851 | 16850 | posix.close(fd); |
| 16852 | 16851 | return t.random_file.fd; |
| ... | ... | @@ -16873,8 +16872,8 @@ fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |
| 16873 | 16872 | switch (posix.errno(fstat_sym(fd, &stat))) { |
| 16874 | 16873 | .SUCCESS => { |
| 16875 | 16874 | syscall.finish(); |
| 16876 | | mutexLockInternal(&t.mutex); // Another thread might have won the race. |
| 16877 | | defer mutexUnlockInternal(&t.mutex); |
| 16875 | mutexLock(&t.mutex); // Another thread might have won the race. |
| 16876 | defer mutexUnlock(&t.mutex); |
| 16878 | 16877 | if (t.random_file.fd >= 0) { |
| 16879 | 16878 | posix.close(fd); |
| 16880 | 16879 | return t.random_file.fd; |
| ... | ... | @@ -16938,7 +16937,7 @@ const parking_futex = struct { |
| 16938 | 16937 | /// avoid a race. |
| 16939 | 16938 | num_waiters: std.atomic.Value(u32), |
| 16940 | 16939 | /// Protects `waiters`. |
| 16941 | | mutex: Mutex, |
| 16940 | mutex: Io.Mutex, |
| 16942 | 16941 | waiters: std.DoublyLinkedList, |
| 16943 | 16942 | |
| 16944 | 16943 | /// Prevent false sharing between buckets. |
| ... | ... | @@ -17007,8 +17006,8 @@ const parking_futex = struct { |
| 17007 | 17006 | var status_buf: std.atomic.Value(Thread.Status) = undefined; |
| 17008 | 17007 | |
| 17009 | 17008 | { |
| 17010 | | mutexLockInternal(&bucket.mutex); |
| 17011 | | defer mutexUnlockInternal(&bucket.mutex); |
| 17009 | mutexLock(&bucket.mutex); |
| 17010 | defer mutexUnlock(&bucket.mutex); |
| 17012 | 17011 | |
| 17013 | 17012 | _ = bucket.num_waiters.fetchAdd(1, .acquire); |
| 17014 | 17013 | |
| ... | ... | @@ -17077,8 +17076,8 @@ const parking_futex = struct { |
| 17077 | 17076 | .parked => { |
| 17078 | 17077 | // We saw a timeout and updated our own status from `.parked` to `.none`. It is |
| 17079 | 17078 | // our responsibility to remove `waiter` from `bucket`. |
| 17080 | | mutexLockInternal(&bucket.mutex); |
| 17081 | | defer mutexUnlockInternal(&bucket.mutex); |
| 17079 | mutexLock(&bucket.mutex); |
| 17080 | defer mutexUnlock(&bucket.mutex); |
| 17082 | 17081 | bucket.waiters.remove(&waiter.node); |
| 17083 | 17082 | assert(bucket.num_waiters.fetchSub(1, .monotonic) > 0); |
| 17084 | 17083 | }, |
| ... | ... | @@ -17117,8 +17116,8 @@ const parking_futex = struct { |
| 17117 | 17116 | // of the critical section. This forms a singly-linked list of waiters using `Waiter.node.next`. |
| 17118 | 17117 | var waking_head: ?*std.DoublyLinkedList.Node = null; |
| 17119 | 17118 | { |
| 17120 | | mutexLockInternal(&bucket.mutex); |
| 17121 | | defer mutexUnlockInternal(&bucket.mutex); |
| 17119 | mutexLock(&bucket.mutex); |
| 17120 | defer mutexUnlock(&bucket.mutex); |
| 17122 | 17121 | |
| 17123 | 17122 | var num_removed: u32 = 0; |
| 17124 | 17123 | var it = bucket.waiters.first; |
| ... | ... | @@ -17173,8 +17172,8 @@ const parking_futex = struct { |
| 17173 | 17172 | |
| 17174 | 17173 | fn removeCanceledWaiter(waiter: *Waiter) void { |
| 17175 | 17174 | const bucket = bucketForAddress(waiter.address); |
| 17176 | | mutexLockInternal(&bucket.mutex); |
| 17177 | | defer mutexUnlockInternal(&bucket.mutex); |
| 17175 | mutexLock(&bucket.mutex); |
| 17176 | defer mutexUnlock(&bucket.mutex); |
| 17178 | 17177 | bucket.waiters.remove(&waiter.node); |
| 17179 | 17178 | assert(bucket.num_waiters.fetchSub(1, .monotonic) > 0); |
| 17180 | 17179 | waiter.done.store(true, .release); // potentially invalidates `waiter.*` |
| ... | ... | @@ -18160,14 +18159,8 @@ fn eventSet(event: *Io.Event) void { |
| 18160 | 18159 | } |
| 18161 | 18160 | } |
| 18162 | 18161 | |
| 18163 | | const Condition = if (!is_windows) Io.Condition else struct { |
| 18164 | | condition: windows.CONDITION_VARIABLE, |
| 18165 | | const init: @This() = .{ .condition = .{} }; |
| 18166 | | }; |
| 18167 | | |
| 18168 | 18162 | /// Same as `Io.Condition.broadcast` but avoids the VTable. |
| 18169 | | fn condBroadcast(cond: *Condition) void { |
| 18170 | | if (is_windows) return windows.ntdll.RtlWakeAllConditionVariable(&cond.condition); |
| 18163 | fn condBroadcast(cond: *Io.Condition) void { |
| 18171 | 18164 | var prev_state = cond.state.load(.monotonic); |
| 18172 | 18165 | while (prev_state.waiters > prev_state.signals) { |
| 18173 | 18166 | @branchHint(.unlikely); |
| ... | ... | @@ -18187,8 +18180,7 @@ fn condBroadcast(cond: *Condition) void { |
| 18187 | 18180 | } |
| 18188 | 18181 | |
| 18189 | 18182 | /// Same as `Io.Condition.signal` but avoids the VTable. |
| 18190 | | fn condSignal(cond: *Condition) void { |
| 18191 | | if (is_windows) return windows.ntdll.RtlWakeConditionVariable(&cond.condition); |
| 18183 | fn condSignal(cond: *Io.Condition) void { |
| 18192 | 18184 | var prev_state = cond.state.load(.monotonic); |
| 18193 | 18185 | while (prev_state.waiters > prev_state.signals) { |
| 18194 | 18186 | @branchHint(.unlikely); |
| ... | ... | @@ -18208,11 +18200,7 @@ fn condSignal(cond: *Condition) void { |
| 18208 | 18200 | } |
| 18209 | 18201 | |
| 18210 | 18202 | /// Same as `Io.Condition.waitUncancelable` but avoids the VTable. |
| 18211 | | fn condWait(cond: *Condition, mutex: *Mutex) void { |
| 18212 | | if (is_windows) { |
| 18213 | | _ = windows.kernel32.SleepConditionVariableSRW(&cond.condition, &mutex.srwlock, windows.INFINITE, 0); |
| 18214 | | return; |
| 18215 | | } |
| 18203 | fn condWait(cond: *Io.Condition, mutex: *Io.Mutex) void { |
| 18216 | 18204 | var epoch = cond.epoch.load(.acquire); // `.acquire` to ensure ordered before state load |
| 18217 | 18205 | |
| 18218 | 18206 | { |
| ... | ... | @@ -18220,8 +18208,8 @@ fn condWait(cond: *Condition, mutex: *Mutex) void { |
| 18220 | 18208 | assert(prev_state.waiters < std.math.maxInt(u16)); // overflow caused by too many waiters |
| 18221 | 18209 | } |
| 18222 | 18210 | |
| 18223 | | mutexUnlockInternal(mutex); |
| 18224 | | defer mutexLockInternal(mutex); |
| 18211 | mutexUnlock(mutex); |
| 18212 | defer mutexLock(mutex); |
| 18225 | 18213 | |
| 18226 | 18214 | while (true) { |
| 18227 | 18215 | Thread.futexWaitUncancelable(&cond.epoch.raw, epoch, null); |
| ... | ... | @@ -18241,16 +18229,6 @@ fn condWait(cond: *Condition, mutex: *Mutex) void { |
| 18241 | 18229 | } |
| 18242 | 18230 | } |
| 18243 | 18231 | |
| 18244 | | const Mutex = if (!is_windows) Io.Mutex else struct { |
| 18245 | | srwlock: windows.SRWLOCK, |
| 18246 | | const init: @This() = .{ .srwlock = .{} }; |
| 18247 | | }; |
| 18248 | | |
| 18249 | | fn mutexLockInternal(m: *Mutex) void { |
| 18250 | | if (is_windows) return windows.ntdll.RtlAcquireSRWLockExclusive(&m.srwlock); |
| 18251 | | return mutexLock(m); |
| 18252 | | } |
| 18253 | | |
| 18254 | 18232 | /// Same as `Io.Mutex.lockUncancelable` but avoids the VTable. |
| 18255 | 18233 | pub fn mutexLock(m: *Io.Mutex) void { |
| 18256 | 18234 | const initial_state = m.state.cmpxchgWeak( |
| ... | ... | @@ -18270,11 +18248,6 @@ pub fn mutexLock(m: *Io.Mutex) void { |
| 18270 | 18248 | } |
| 18271 | 18249 | } |
| 18272 | 18250 | |
| 18273 | | fn mutexUnlockInternal(m: *Mutex) void { |
| 18274 | | if (is_windows) return windows.ntdll.RtlReleaseSRWLockExclusive(&m.srwlock); |
| 18275 | | return mutexUnlock(m); |
| 18276 | | } |
| 18277 | | |
| 18278 | 18251 | /// Same as `Io.Mutex.unlock` but avoids the VTable. |
| 18279 | 18252 | pub fn mutexUnlock(m: *Io.Mutex) void { |
| 18280 | 18253 | switch (m.state.swap(.unlocked, .release)) { |