diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-08-28 12:41:24 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-08-28 12:41:24 -0700 |
| commit | 6aeab0f323ff14d7ad248e18c372573f7a5a8cd1 (patch) | |
| tree | 7080297f629f39baa0b742985c5804cf6a2047e8 /lib/std/Thread | |
| parent | 47f7ed1c4cb8acf7fed99a057fb84202962e4b1b (diff) | |
| parent | 05cf44933d753f7a5a53ab289ea60fd43761de57 (diff) | |
| download | zig-6aeab0f323ff14d7ad248e18c372573f7a5a8cd1.tar.gz zig-6aeab0f323ff14d7ad248e18c372573f7a5a8cd1.zip | |
Merge remote-tracking branch 'origin/master' into llvm13
Conflicts:
lib/libcxx/include/__config
d57c0cc3bfeff9af297279759ec2b631e6d95140 added support for DragonFlyBSD
to libc++ by updating some ifdefs. This needed to be synced with llvm13.
Diffstat (limited to 'lib/std/Thread')
| -rw-r--r-- | lib/std/Thread/AutoResetEvent.zig | 6 | ||||
| -rw-r--r-- | lib/std/Thread/Condition.zig | 22 | ||||
| -rw-r--r-- | lib/std/Thread/Futex.zig | 84 | ||||
| -rw-r--r-- | lib/std/Thread/Mutex.zig | 38 | ||||
| -rw-r--r-- | lib/std/Thread/ResetEvent.zig | 30 | ||||
| -rw-r--r-- | lib/std/Thread/RwLock.zig | 30 | ||||
| -rw-r--r-- | lib/std/Thread/Semaphore.zig | 6 | ||||
| -rw-r--r-- | lib/std/Thread/StaticResetEvent.zig | 16 |
8 files changed, 91 insertions, 141 deletions
diff --git a/lib/std/Thread/AutoResetEvent.zig b/lib/std/Thread/AutoResetEvent.zig index 13e404d602..49639d60e9 100644 --- a/lib/std/Thread/AutoResetEvent.zig +++ b/lib/std/Thread/AutoResetEvent.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! Similar to `StaticResetEvent` but on `set()` it also (atomically) does `reset()`. //! Unlike StaticResetEvent, `wait()` can only be called by one thread (MPSC-like). //! diff --git a/lib/std/Thread/Condition.zig b/lib/std/Thread/Condition.zig index 8485f84aa4..647a50b913 100644 --- a/lib/std/Thread/Condition.zig +++ b/lib/std/Thread/Condition.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! A condition provides a way for a kernel thread to block until it is signaled //! to wake up. Spurious wakeups are possible. //! This API supports static initialization and does not require deinitialization. @@ -81,17 +75,17 @@ pub const PthreadCondition = struct { pub fn wait(cond: *PthreadCondition, mutex: *Mutex) void { const rc = std.c.pthread_cond_wait(&cond.cond, &mutex.impl.pthread_mutex); - assert(rc == 0); + assert(rc == .SUCCESS); } pub fn signal(cond: *PthreadCondition) void { const rc = std.c.pthread_cond_signal(&cond.cond); - assert(rc == 0); + assert(rc == .SUCCESS); } pub fn broadcast(cond: *PthreadCondition) void { const rc = std.c.pthread_cond_broadcast(&cond.cond); - assert(rc == 0); + assert(rc == .SUCCESS); } }; @@ -115,9 +109,9 @@ pub const AtomicCondition = struct { 0, null, ))) { - 0 => {}, - std.os.EINTR => {}, - std.os.EAGAIN => {}, + .SUCCESS => {}, + .INTR => {}, + .AGAIN => {}, else => unreachable, } }, @@ -136,8 +130,8 @@ pub const AtomicCondition = struct { linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAKE, 1, ))) { - 0 => {}, - std.os.EFAULT => {}, + .SUCCESS => {}, + .FAULT => {}, else => unreachable, } }, diff --git a/lib/std/Thread/Futex.zig b/lib/std/Thread/Futex.zig index 81dba07996..5a3da5cd94 100644 --- a/lib/std/Thread/Futex.zig +++ b/lib/std/Thread/Futex.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! Futex is a mechanism used to block (`wait`) and unblock (`wake`) threads using a 32bit memory address as hints. //! Blocking a thread is acknowledged only if the 32bit memory address is equal to a given value. //! This check helps avoid block/unblock deadlocks which occur if a `wake()` happens before a `wait()`. @@ -152,12 +146,12 @@ const LinuxFutex = struct { @bitCast(i32, expect), ts_ptr, ))) { - 0 => {}, // notified by `wake()` - std.os.EINTR => {}, // spurious wakeup - std.os.EAGAIN => {}, // ptr.* != expect - std.os.ETIMEDOUT => return error.TimedOut, - std.os.EINVAL => {}, // possibly timeout overflow - std.os.EFAULT => unreachable, + .SUCCESS => {}, // notified by `wake()` + .INTR => {}, // spurious wakeup + .AGAIN => {}, // ptr.* != expect + .TIMEDOUT => return error.TimedOut, + .INVAL => {}, // possibly timeout overflow + .FAULT => unreachable, else => unreachable, } } @@ -168,9 +162,9 @@ const LinuxFutex = struct { linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAKE, std.math.cast(i32, num_waiters) catch std.math.maxInt(i32), ))) { - 0 => {}, // successful wake up - std.os.EINVAL => {}, // invalid futex_wait() on ptr done elsewhere - std.os.EFAULT => {}, // pointer became invalid while doing the wake + .SUCCESS => {}, // successful wake up + .INVAL => {}, // invalid futex_wait() on ptr done elsewhere + .FAULT => {}, // pointer became invalid while doing the wake else => unreachable, } } @@ -215,13 +209,13 @@ const DarwinFutex = struct { }; if (status >= 0) return; - switch (-status) { - darwin.EINTR => {}, + switch (@intToEnum(std.os.E, -status)) { + .INTR => {}, // Address of the futex is paged out. This is unlikely, but possible in theory, and // pthread/libdispatch on darwin bother to handle it. In this case we'll return // without waiting, but the caller should retry anyway. - darwin.EFAULT => {}, - darwin.ETIMEDOUT => if (!timeout_overflowed) return error.TimedOut, + .FAULT => {}, + .TIMEDOUT => if (!timeout_overflowed) return error.TimedOut, else => unreachable, } } @@ -237,11 +231,11 @@ const DarwinFutex = struct { const status = darwin.__ulock_wake(flags, addr, 0); if (status >= 0) return; - switch (-status) { - darwin.EINTR => continue, // spurious wake() - darwin.EFAULT => continue, // address of the lock was paged out - darwin.ENOENT => return, // nothing was woken up - darwin.EALREADY => unreachable, // only for ULF_WAKE_THREAD + switch (@intToEnum(std.os.E, -status)) { + .INTR => continue, // spurious wake() + .FAULT => continue, // address of the lock was paged out + .NOENT => return, // nothing was woken up + .ALREADY => unreachable, // only for ULF_WAKE_THREAD else => unreachable, } } @@ -255,8 +249,8 @@ const PosixFutex = struct { var waiter: List.Node = undefined; { - assert(std.c.pthread_mutex_lock(&bucket.mutex) == 0); - defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == 0); + assert(std.c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS); + defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS); if (ptr.load(.SeqCst) != expect) { return; @@ -272,8 +266,8 @@ const PosixFutex = struct { waiter.data.wait(null) catch unreachable; }; - assert(std.c.pthread_mutex_lock(&bucket.mutex) == 0); - defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == 0); + assert(std.c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS); + defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS); if (waiter.data.address == address) { timed_out = true; @@ -297,8 +291,8 @@ const PosixFutex = struct { waiter.data.notify(); }; - assert(std.c.pthread_mutex_lock(&bucket.mutex) == 0); - defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == 0); + assert(std.c.pthread_mutex_lock(&bucket.mutex) == .SUCCESS); + defer assert(std.c.pthread_mutex_unlock(&bucket.mutex) == .SUCCESS); var waiters = bucket.list.first; while (waiters) |waiter| { @@ -340,16 +334,13 @@ const PosixFutex = struct { }; fn deinit(self: *Self) void { - const rc = std.c.pthread_cond_destroy(&self.cond); - assert(rc == 0 or rc == std.os.EINVAL); - - const rm = std.c.pthread_mutex_destroy(&self.mutex); - assert(rm == 0 or rm == std.os.EINVAL); + _ = std.c.pthread_cond_destroy(&self.cond); + _ = std.c.pthread_mutex_destroy(&self.mutex); } fn wait(self: *Self, timeout: ?u64) error{TimedOut}!void { - assert(std.c.pthread_mutex_lock(&self.mutex) == 0); - defer assert(std.c.pthread_mutex_unlock(&self.mutex) == 0); + assert(std.c.pthread_mutex_lock(&self.mutex) == .SUCCESS); + defer assert(std.c.pthread_mutex_unlock(&self.mutex) == .SUCCESS); switch (self.state) { .empty => self.state = .waiting, @@ -378,28 +369,31 @@ const PosixFutex = struct { } const ts_ref = ts_ptr orelse { - assert(std.c.pthread_cond_wait(&self.cond, &self.mutex) == 0); + assert(std.c.pthread_cond_wait(&self.cond, &self.mutex) == .SUCCESS); continue; }; const rc = std.c.pthread_cond_timedwait(&self.cond, &self.mutex, ts_ref); - assert(rc == 0 or rc == std.os.ETIMEDOUT); - if (rc == std.os.ETIMEDOUT) { - self.state = .empty; - return error.TimedOut; + switch (rc) { + .SUCCESS => {}, + .TIMEDOUT => { + self.state = .empty; + return error.TimedOut; + }, + else => unreachable, } } } fn notify(self: *Self) void { - assert(std.c.pthread_mutex_lock(&self.mutex) == 0); - defer assert(std.c.pthread_mutex_unlock(&self.mutex) == 0); + assert(std.c.pthread_mutex_lock(&self.mutex) == .SUCCESS); + defer assert(std.c.pthread_mutex_unlock(&self.mutex) == .SUCCESS); switch (self.state) { .empty => self.state = .notified, .waiting => { self.state = .notified; - assert(std.c.pthread_cond_signal(&self.cond) == 0); + assert(std.c.pthread_cond_signal(&self.cond) == .SUCCESS); }, .notified => unreachable, } diff --git a/lib/std/Thread/Mutex.zig b/lib/std/Thread/Mutex.zig index 35095b2a3c..ee54a1582b 100644 --- a/lib/std/Thread/Mutex.zig +++ b/lib/std/Thread/Mutex.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! Lock may be held only once. If the same thread tries to acquire //! the same mutex twice, it deadlocks. This type supports static //! initialization and is at most `@sizeOf(usize)` in size. When an @@ -143,9 +137,9 @@ pub const AtomicMutex = struct { @enumToInt(new_state), null, ))) { - 0 => {}, - std.os.EINTR => {}, - std.os.EAGAIN => {}, + .SUCCESS => {}, + .INTR => {}, + .AGAIN => {}, else => unreachable, } }, @@ -164,8 +158,8 @@ pub const AtomicMutex = struct { linux.FUTEX_PRIVATE_FLAG | linux.FUTEX_WAKE, 1, ))) { - 0 => {}, - std.os.EFAULT => {}, + .SUCCESS => {}, + .FAULT => unreachable, // invalid pointer passed to futex_wake else => unreachable, } }, @@ -182,10 +176,10 @@ pub const PthreadMutex = struct { pub fn release(held: Held) void { switch (std.c.pthread_mutex_unlock(&held.mutex.pthread_mutex)) { - 0 => return, - std.c.EINVAL => unreachable, - std.c.EAGAIN => unreachable, - std.c.EPERM => unreachable, + .SUCCESS => return, + .INVAL => unreachable, + .AGAIN => unreachable, + .PERM => unreachable, else => unreachable, } } @@ -195,7 +189,7 @@ pub const PthreadMutex = struct { /// the mutex is unavailable. Otherwise returns Held. Call /// release on Held. pub fn tryAcquire(m: *PthreadMutex) ?Held { - if (std.c.pthread_mutex_trylock(&m.pthread_mutex) == 0) { + if (std.c.pthread_mutex_trylock(&m.pthread_mutex) == .SUCCESS) { return Held{ .mutex = m }; } else { return null; @@ -206,12 +200,12 @@ pub const PthreadMutex = struct { /// held by the calling thread. pub fn acquire(m: *PthreadMutex) Held { switch (std.c.pthread_mutex_lock(&m.pthread_mutex)) { - 0 => return Held{ .mutex = m }, - std.c.EINVAL => unreachable, - std.c.EBUSY => unreachable, - std.c.EAGAIN => unreachable, - std.c.EDEADLK => unreachable, - std.c.EPERM => unreachable, + .SUCCESS => return Held{ .mutex = m }, + .INVAL => unreachable, + .BUSY => unreachable, + .AGAIN => unreachable, + .DEADLK => unreachable, + .PERM => unreachable, else => unreachable, } } diff --git a/lib/std/Thread/ResetEvent.zig b/lib/std/Thread/ResetEvent.zig index 356b8eb78d..d9304dd70b 100644 --- a/lib/std/Thread/ResetEvent.zig +++ b/lib/std/Thread/ResetEvent.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! A thread-safe resource which supports blocking until signaled. //! This API is for kernel threads, not evented I/O. //! This API requires being initialized at runtime, and initialization @@ -130,7 +124,7 @@ pub const PosixEvent = struct { pub fn init(ev: *PosixEvent) !void { switch (c.getErrno(c.sem_init(&ev.sem, 0, 0))) { - 0 => return, + .SUCCESS => return, else => return error.SystemResources, } } @@ -147,9 +141,9 @@ pub const PosixEvent = struct { pub fn wait(ev: *PosixEvent) void { while (true) { switch (c.getErrno(c.sem_wait(&ev.sem))) { - 0 => return, - c.EINTR => continue, - c.EINVAL => unreachable, + .SUCCESS => return, + .INTR => continue, + .INVAL => unreachable, else => unreachable, } } @@ -165,10 +159,10 @@ pub const PosixEvent = struct { ts.tv_nsec = @intCast(@TypeOf(ts.tv_nsec), @mod(timeout_abs, time.ns_per_s)); while (true) { switch (c.getErrno(c.sem_timedwait(&ev.sem, &ts))) { - 0 => return .event_set, - c.EINTR => continue, - c.EINVAL => unreachable, - c.ETIMEDOUT => return .timed_out, + .SUCCESS => return .event_set, + .INTR => continue, + .INVAL => unreachable, + .TIMEDOUT => return .timed_out, else => unreachable, } } @@ -177,10 +171,10 @@ pub const PosixEvent = struct { pub fn reset(ev: *PosixEvent) void { while (true) { switch (c.getErrno(c.sem_trywait(&ev.sem))) { - 0 => continue, // Need to make it go to zero. - c.EINTR => continue, - c.EINVAL => unreachable, - c.EAGAIN => return, // The semaphore currently has the value zero. + .SUCCESS => continue, // Need to make it go to zero. + .INTR => continue, + .INVAL => unreachable, + .AGAIN => return, // The semaphore currently has the value zero. else => unreachable, } } diff --git a/lib/std/Thread/RwLock.zig b/lib/std/Thread/RwLock.zig index 1d606a9cf1..cfe06c76e8 100644 --- a/lib/std/Thread/RwLock.zig +++ b/lib/std/Thread/RwLock.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! A lock that supports one writer or many readers. //! This API is for kernel threads, not evented I/O. //! This API requires being initialized at runtime, and initialization @@ -13,7 +7,7 @@ impl: Impl, const RwLock = @This(); const std = @import("../std.zig"); -const builtin = std.builtin; +const builtin = @import("builtin"); const assert = std.debug.assert; const Mutex = std.Thread.Mutex; const Semaphore = std.Semaphore; @@ -165,43 +159,41 @@ pub const PthreadRwLock = struct { } pub fn deinit(rwl: *PthreadRwLock) void { - const safe_rc = switch (std.builtin.os.tag) { - .dragonfly, .netbsd => std.os.EAGAIN, - else => 0, + const safe_rc: std.os.E = switch (builtin.os.tag) { + .dragonfly, .netbsd => .AGAIN, + else => .SUCCESS, }; - const rc = std.c.pthread_rwlock_destroy(&rwl.rwlock); - assert(rc == 0 or rc == safe_rc); - + assert(rc == .SUCCESS or rc == safe_rc); rwl.* = undefined; } pub fn tryLock(rwl: *PthreadRwLock) bool { - return pthread_rwlock_trywrlock(&rwl.rwlock) == 0; + return pthread_rwlock_trywrlock(&rwl.rwlock) == .SUCCESS; } pub fn lock(rwl: *PthreadRwLock) void { const rc = pthread_rwlock_wrlock(&rwl.rwlock); - assert(rc == 0); + assert(rc == .SUCCESS); } pub fn unlock(rwl: *PthreadRwLock) void { const rc = pthread_rwlock_unlock(&rwl.rwlock); - assert(rc == 0); + assert(rc == .SUCCESS); } pub fn tryLockShared(rwl: *PthreadRwLock) bool { - return pthread_rwlock_tryrdlock(&rwl.rwlock) == 0; + return pthread_rwlock_tryrdlock(&rwl.rwlock) == .SUCCESS; } pub fn lockShared(rwl: *PthreadRwLock) void { const rc = pthread_rwlock_rdlock(&rwl.rwlock); - assert(rc == 0); + assert(rc == .SUCCESS); } pub fn unlockShared(rwl: *PthreadRwLock) void { const rc = pthread_rwlock_unlock(&rwl.rwlock); - assert(rc == 0); + assert(rc == .SUCCESS); } }; diff --git a/lib/std/Thread/Semaphore.zig b/lib/std/Thread/Semaphore.zig index 169975b362..b5bde88d73 100644 --- a/lib/std/Thread/Semaphore.zig +++ b/lib/std/Thread/Semaphore.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! A semaphore is an unsigned integer that blocks the kernel thread if //! the number would become negative. //! This API supports static initialization and does not require deinitialization. diff --git a/lib/std/Thread/StaticResetEvent.zig b/lib/std/Thread/StaticResetEvent.zig index 40974938d0..d779a4de9e 100644 --- a/lib/std/Thread/StaticResetEvent.zig +++ b/lib/std/Thread/StaticResetEvent.zig @@ -1,9 +1,3 @@ -// SPDX-License-Identifier: MIT -// Copyright (c) 2015-2021 Zig Contributors -// This file is part of [zig](https://ziglang.org/), which is MIT licensed. -// The MIT license requires this copyright notice to be included in all copies -// and substantial portions of the software. - //! A thread-safe resource which supports blocking until signaled. //! This API is for kernel threads, not evented I/O. //! This API is statically initializable. It cannot fail to be initialized @@ -201,7 +195,7 @@ pub const AtomicEvent = struct { const waiting = std.math.maxInt(i32); // wake_count const ptr = @ptrCast(*const i32, waiters); const rc = linux.futex_wake(ptr, linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG, waiting); - assert(linux.getErrno(rc) == 0); + assert(linux.getErrno(rc) == .SUCCESS); } fn wait(waiters: *u32, timeout: ?u64) !void { @@ -221,10 +215,10 @@ pub const AtomicEvent = struct { const ptr = @ptrCast(*const i32, waiters); const rc = linux.futex_wait(ptr, linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG, expected, ts_ptr); switch (linux.getErrno(rc)) { - 0 => continue, - os.ETIMEDOUT => return error.TimedOut, - os.EINTR => continue, - os.EAGAIN => return, + .SUCCESS => continue, + .TIMEDOUT => return error.TimedOut, + .INTR => continue, + .AGAIN => return, else => unreachable, } } |
