diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-07-18 23:35:19 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-07-19 00:30:32 -0700 |
| commit | e8c4e79499fbb2a83a0f4fe2cac0d80e5d12a07e (patch) | |
| tree | fa8018ad4597f8f51ce760c34822ad50e9a7157c /lib/std/Thread | |
| parent | 16604a93b9159fafec3528457366ca146bf29ce5 (diff) | |
| download | zig-e8c4e79499fbb2a83a0f4fe2cac0d80e5d12a07e.tar.gz zig-e8c4e79499fbb2a83a0f4fe2cac0d80e5d12a07e.zip | |
std.c reorganization
It is now composed of these main sections:
* Declarations that are shared among all operating systems.
* Declarations that have the same name, but different type signatures
depending on the operating system. Often multiple operating systems
share the same type signatures however.
* Declarations that are specific to a single operating system.
- These are imported one per line so you can see where they come from,
protected by a comptime block to prevent accessing the wrong one.
Closes #19352 by changing the convention to making types `void` and
functions `{}`, so that it becomes possible to update `@hasDecl` sites
to use `@TypeOf(f) != void` or `T != void`. Happily, this ended up
removing some duplicate logic and update some bitrotted feature
detection checks.
A handful of types have been modified to gain namespacing and type
safety. This is a breaking change.
Oh, and the last usage of `usingnamespace` site is eliminated.
Diffstat (limited to 'lib/std/Thread')
| -rw-r--r-- | lib/std/Thread/Futex.zig | 52 | ||||
| -rw-r--r-- | lib/std/Thread/Mutex.zig | 6 |
2 files changed, 31 insertions, 27 deletions
diff --git a/lib/std/Thread/Futex.zig b/lib/std/Thread/Futex.zig index 4bbe1f6293..c067368041 100644 --- a/lib/std/Thread/Futex.zig +++ b/lib/std/Thread/Futex.zig @@ -196,7 +196,10 @@ const DarwinImpl = struct { var timeout_overflowed = false; const addr: *const anyopaque = ptr; - const flags = c.UL_COMPARE_AND_WAIT | c.ULF_NO_ERRNO; + const flags: c.UL = .{ + .op = .COMPARE_AND_WAIT, + .NO_ERRNO = true, + }; const status = blk: { if (supports_ulock_wait2) { break :blk c.__ulock_wait2(flags, addr, expect, timeout_ns, 0); @@ -228,10 +231,11 @@ const DarwinImpl = struct { } fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void { - var flags: u32 = c.UL_COMPARE_AND_WAIT | c.ULF_NO_ERRNO; - if (max_waiters > 1) { - flags |= c.ULF_WAKE_ALL; - } + const flags: c.UL = .{ + .op = .COMPARE_AND_WAIT, + .NO_ERRNO = true, + .WAKE_ALL = max_waiters > 1, + }; while (true) { const addr: *const anyopaque = ptr; @@ -242,7 +246,7 @@ const DarwinImpl = struct { .INTR => continue, // spurious wake() .FAULT => unreachable, // __ulock_wake doesn't generate EFAULT according to darwin pthread_cond_t .NOENT => return, // nothing was woken up - .ALREADY => unreachable, // only for ULF_WAKE_THREAD + .ALREADY => unreachable, // only for UL.Op.WAKE_THREAD else => unreachable, } } @@ -254,8 +258,8 @@ const LinuxImpl = struct { fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void { var ts: linux.timespec = undefined; if (timeout) |timeout_ns| { - ts.tv_sec = @as(@TypeOf(ts.tv_sec), @intCast(timeout_ns / std.time.ns_per_s)); - ts.tv_nsec = @as(@TypeOf(ts.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s)); + ts.sec = @as(@TypeOf(ts.sec), @intCast(timeout_ns / std.time.ns_per_s)); + ts.nsec = @as(@TypeOf(ts.nsec), @intCast(timeout_ns % std.time.ns_per_s)); } const rc = linux.futex_wait( @@ -306,10 +310,10 @@ const FreebsdImpl = struct { tm_ptr = &tm; tm_size = @sizeOf(@TypeOf(tm)); - tm._flags = 0; // use relative time not UMTX_ABSTIME - tm._clockid = c.CLOCK.MONOTONIC; - tm._timeout.tv_sec = @as(@TypeOf(tm._timeout.tv_sec), @intCast(timeout_ns / std.time.ns_per_s)); - tm._timeout.tv_nsec = @as(@TypeOf(tm._timeout.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s)); + tm.flags = 0; // use relative time not UMTX_ABSTIME + tm.clockid = .MONOTONIC; + tm.timeout.sec = @as(@TypeOf(tm.timeout.sec), @intCast(timeout_ns / std.time.ns_per_s)); + tm.timeout.nsec = @as(@TypeOf(tm.timeout.nsec), @intCast(timeout_ns % std.time.ns_per_s)); } const rc = c._umtx_op( @@ -356,16 +360,16 @@ const OpenbsdImpl = struct { fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void { var ts: c.timespec = undefined; if (timeout) |timeout_ns| { - ts.tv_sec = @as(@TypeOf(ts.tv_sec), @intCast(timeout_ns / std.time.ns_per_s)); - ts.tv_nsec = @as(@TypeOf(ts.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s)); + ts.sec = @as(@TypeOf(ts.sec), @intCast(timeout_ns / std.time.ns_per_s)); + ts.nsec = @as(@TypeOf(ts.nsec), @intCast(timeout_ns % std.time.ns_per_s)); } const rc = c.futex( @as(*const volatile u32, @ptrCast(&ptr.raw)), - c.FUTEX_WAIT | c.FUTEX_PRIVATE_FLAG, + c.FUTEX.WAIT | c.FUTEX.PRIVATE_FLAG, @as(c_int, @bitCast(expect)), if (timeout != null) &ts else null, - null, // FUTEX_WAIT takes no requeue address + null, // FUTEX.WAIT takes no requeue address ); switch (std.posix.errno(rc)) { @@ -387,10 +391,10 @@ const OpenbsdImpl = struct { fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void { const rc = c.futex( @as(*const volatile u32, @ptrCast(&ptr.raw)), - c.FUTEX_WAKE | c.FUTEX_PRIVATE_FLAG, + c.FUTEX.WAKE | c.FUTEX.PRIVATE_FLAG, std.math.cast(c_int, max_waiters) orelse std.math.maxInt(c_int), - null, // FUTEX_WAKE takes no timeout ptr - null, // FUTEX_WAKE takes no requeue address + null, // FUTEX.WAKE takes no timeout ptr + null, // FUTEX.WAKE takes no requeue address ); // returns number of threads woken up. @@ -540,12 +544,12 @@ const PosixImpl = struct { var ts: c.timespec = undefined; if (timeout) |timeout_ns| { std.posix.clock_gettime(c.CLOCK.REALTIME, &ts) catch unreachable; - ts.tv_sec +|= @as(@TypeOf(ts.tv_sec), @intCast(timeout_ns / std.time.ns_per_s)); - ts.tv_nsec += @as(@TypeOf(ts.tv_nsec), @intCast(timeout_ns % std.time.ns_per_s)); + ts.sec +|= @as(@TypeOf(ts.sec), @intCast(timeout_ns / std.time.ns_per_s)); + ts.nsec += @as(@TypeOf(ts.nsec), @intCast(timeout_ns % std.time.ns_per_s)); - if (ts.tv_nsec >= std.time.ns_per_s) { - ts.tv_sec +|= 1; - ts.tv_nsec -= std.time.ns_per_s; + if (ts.nsec >= std.time.ns_per_s) { + ts.sec +|= 1; + ts.nsec -= std.time.ns_per_s; } } diff --git a/lib/std/Thread/Mutex.zig b/lib/std/Thread/Mutex.zig index 11c6386569..032c19b7dd 100644 --- a/lib/std/Thread/Mutex.zig +++ b/lib/std/Thread/Mutex.zig @@ -103,8 +103,8 @@ const SingleThreadedImpl = struct { } }; -// SRWLOCK on windows is almost always faster than Futex solution. -// It also implements an efficient Condition with requeue support for us. +/// SRWLOCK on windows is almost always faster than Futex solution. +/// It also implements an efficient Condition with requeue support for us. const WindowsImpl = struct { srwlock: windows.SRWLOCK = .{}, @@ -123,7 +123,7 @@ const WindowsImpl = struct { const windows = std.os.windows; }; -// os_unfair_lock on darwin supports priority inheritance and is generally faster than Futex solutions. +/// os_unfair_lock on darwin supports priority inheritance and is generally faster than Futex solutions. const DarwinImpl = struct { oul: c.os_unfair_lock = .{}, |
