authorgravatar for 77312308+billzez@users.noreply.github.combillzez <77312308+billzez@users.noreply.github.com> 2022-02-08 23:35:48-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-11 12:13:51-07:00
logbf6af1963cfb3451b3338d7488ec26f5fb7af0ed
tree2e28c99a0cc4ab4aa4332150b4f8d991bd5e0954
parent45d4e2f8160d8807c353a514332ab49bd8355980

update RwLock to use static initialization (#10838)


2 files changed, 14 insertions(+), 64 deletions(-)

lib/std/Thread.zig+1
......@@ -16,6 +16,7 @@ pub const StaticResetEvent = @import("Thread/StaticResetEvent.zig");
1616pub const Mutex = @import("Thread/Mutex.zig");
1717pub const Semaphore = @import("Thread/Semaphore.zig");
1818pub const Condition = @import("Thread/Condition.zig");
19pub const RwLock = @import("Thread/RwLock.zig");
1920
2021pub const use_pthreads = target.os.tag != .windows and target.os.tag != .wasi and builtin.link_libc;
2122const is_gnu = target.abi.isGnu();
lib/std/Thread/RwLock.zig+13-64
......@@ -3,15 +3,12 @@
33//! This API requires being initialized at runtime, and initialization
44//! can fail. Once initialized, the core operations cannot fail.
55
6impl: Impl,
6impl: Impl = .{},
77
88const RwLock = @This();
99const std = @import("../std.zig");
1010const builtin = @import("builtin");
1111const assert = std.debug.assert;
12const Mutex = std.Thread.Mutex;
13const Semaphore = std.Semaphore;
14const CondVar = std.CondVar;
1512
1613pub const Impl = if (builtin.single_threaded)
1714 SingleThreadedRwLock
......@@ -20,14 +17,6 @@ else if (std.Thread.use_pthreads)
2017else
2118 DefaultRwLock;
2219
23pub fn init(rwl: *RwLock) void {
24 return rwl.impl.init();
25}
26
27pub fn deinit(rwl: *RwLock) void {
28 return rwl.impl.deinit();
29}
30
3120/// Attempts to obtain exclusive lock ownership.
3221/// Returns `true` if the lock is obtained, `false` otherwise.
3322pub fn tryLock(rwl: *RwLock) bool {
......@@ -64,20 +53,8 @@ pub fn unlockShared(rwl: *RwLock) void {
6453/// Single-threaded applications use this for deadlock checks in
6554/// debug mode, and no-ops in release modes.
6655pub const SingleThreadedRwLock = struct {
67 state: enum { unlocked, locked_exclusive, locked_shared },
68 shared_count: usize,
69
70 pub fn init(rwl: *SingleThreadedRwLock) void {
71 rwl.* = .{
72 .state = .unlocked,
73 .shared_count = 0,
74 };
75 }
76
77 pub fn deinit(rwl: *SingleThreadedRwLock) void {
78 assert(rwl.state == .unlocked);
79 assert(rwl.shared_count == 0);
80 }
56 state: enum { unlocked, locked_exclusive, locked_shared } = .unlocked,
57 shared_count: usize = 0,
8158
8259 /// Attempts to obtain exclusive lock ownership.
8360 /// Returns `true` if the lock is obtained, `false` otherwise.
......@@ -152,55 +129,41 @@ pub const SingleThreadedRwLock = struct {
152129};
153130
154131pub const PthreadRwLock = struct {
155 rwlock: pthread_rwlock_t,
156
157 pub fn init(rwl: *PthreadRwLock) void {
158 rwl.* = .{ .rwlock = .{} };
159 }
160
161 pub fn deinit(rwl: *PthreadRwLock) void {
162 const safe_rc: std.os.E = switch (builtin.os.tag) {
163 .dragonfly, .netbsd => .AGAIN,
164 else => .SUCCESS,
165 };
166 const rc = std.c.pthread_rwlock_destroy(&rwl.rwlock);
167 assert(rc == .SUCCESS or rc == safe_rc);
168 rwl.* = undefined;
169 }
132 rwlock: std.c.pthread_rwlock_t = .{},
170133
171134 pub fn tryLock(rwl: *PthreadRwLock) bool {
172 return pthread_rwlock_trywrlock(&rwl.rwlock) == .SUCCESS;
135 return std.c.pthread_rwlock_trywrlock(&rwl.rwlock) == .SUCCESS;
173136 }
174137
175138 pub fn lock(rwl: *PthreadRwLock) void {
176 const rc = pthread_rwlock_wrlock(&rwl.rwlock);
139 const rc = std.c.pthread_rwlock_wrlock(&rwl.rwlock);
177140 assert(rc == .SUCCESS);
178141 }
179142
180143 pub fn unlock(rwl: *PthreadRwLock) void {
181 const rc = pthread_rwlock_unlock(&rwl.rwlock);
144 const rc = std.c.pthread_rwlock_unlock(&rwl.rwlock);
182145 assert(rc == .SUCCESS);
183146 }
184147
185148 pub fn tryLockShared(rwl: *PthreadRwLock) bool {
186 return pthread_rwlock_tryrdlock(&rwl.rwlock) == .SUCCESS;
149 return std.c.pthread_rwlock_tryrdlock(&rwl.rwlock) == .SUCCESS;
187150 }
188151
189152 pub fn lockShared(rwl: *PthreadRwLock) void {
190 const rc = pthread_rwlock_rdlock(&rwl.rwlock);
153 const rc = std.c.pthread_rwlock_rdlock(&rwl.rwlock);
191154 assert(rc == .SUCCESS);
192155 }
193156
194157 pub fn unlockShared(rwl: *PthreadRwLock) void {
195 const rc = pthread_rwlock_unlock(&rwl.rwlock);
158 const rc = std.c.pthread_rwlock_unlock(&rwl.rwlock);
196159 assert(rc == .SUCCESS);
197160 }
198161};
199162
200163pub const DefaultRwLock = struct {
201 state: usize,
202 mutex: Mutex,
203 semaphore: Semaphore,
164 state: usize = 0,
165 mutex: std.Thread.Mutex = .{},
166 semaphore: std.Thread.Semaphore = .{},
204167
205168 const IS_WRITING: usize = 1;
206169 const WRITER: usize = 1 << 1;
......@@ -209,20 +172,6 @@ pub const DefaultRwLock = struct {
209172 const READER_MASK: usize = std.math.maxInt(Count) << @ctz(usize, READER);
210173 const Count = std.meta.Int(.unsigned, @divFloor(std.meta.bitCount(usize) - 1, 2));
211174
212 pub fn init(rwl: *DefaultRwLock) void {
213 rwl.* = .{
214 .state = 0,
215 .mutex = Mutex.init(),
216 .semaphore = Semaphore.init(0),
217 };
218 }
219
220 pub fn deinit(rwl: *DefaultRwLock) void {
221 rwl.semaphore.deinit();
222 rwl.mutex.deinit();
223 rwl.* = undefined;
224 }
225
226175 pub fn tryLock(rwl: *DefaultRwLock) bool {
227176 if (rwl.mutex.tryLock()) {
228177 const state = @atomicLoad(usize, &rwl.state, .SeqCst);