authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-03 20:05:03-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-01-03 20:05:03-05:00
log6ea193946da13a42ecd8f8d46e4a140f9937d1e5
tree04cbfd5667eecb8169b8edc5c9c31bbd5a197bf3
parentb91eaba38c6661b5eb3558b0c0b88a22a50d2a57
parent45339aec02124b8ae9480eeb69fd6cd5bd2ee5aa
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3950 from nmichaels/master

Document std.Mutex.

1 files changed, 33 insertions(+), 5 deletions(-)

lib/std/mutex.zig+33-5
...@@ -7,11 +7,28 @@ const testing = std.testing;...@@ -7,11 +7,28 @@ const testing = std.testing;
7const SpinLock = std.SpinLock;7const SpinLock = std.SpinLock;
8const ResetEvent = std.ResetEvent;8const ResetEvent = std.ResetEvent;
99
10/// Lock may be held only once. If the same thread10/// Lock may be held only once. If the same thread tries to acquire
11/// tries to acquire the same mutex twice, it deadlocks.11/// the same mutex twice, it deadlocks. This type supports static
12/// This type supports static initialization and is at most `@sizeOf(usize)` in size.12/// initialization and is at most `@sizeOf(usize)` in size. When an
13/// When an application is built in single threaded release mode, all the functions are13/// application is built in single threaded release mode, all the
14/// no-ops. In single threaded debug mode, there is deadlock detection.14/// functions are no-ops. In single threaded debug mode, there is
15/// deadlock detection.
16///
17/// Example usage:
18/// var m = Mutex.init();
19/// defer m.deinit();
20///
21/// const lock = m.acquire();
22/// defer lock.release();
23/// ... critical code
24///
25/// Non-blocking:
26/// if (m.tryAcquire) |lock| {
27/// defer lock.release();
28/// // ... critical section
29/// } else {
30/// // ... lock not acquired
31/// }
15pub const Mutex = if (builtin.single_threaded)32pub const Mutex = if (builtin.single_threaded)
16 struct {33 struct {
17 lock: @TypeOf(lock_init),34 lock: @TypeOf(lock_init),
...@@ -28,14 +45,20 @@ pub const Mutex = if (builtin.single_threaded)...@@ -28,14 +45,20 @@ pub const Mutex = if (builtin.single_threaded)
28 }45 }
29 };46 };
3047
48 /// Create a new mutex in unlocked state.
31 pub fn init() Mutex {49 pub fn init() Mutex {
32 return Mutex{ .lock = lock_init };50 return Mutex{ .lock = lock_init };
33 }51 }
3452
53 /// Free a mutex created with init. Calling this while the
54 /// mutex is held is illegal behavior.
35 pub fn deinit(self: *Mutex) void {55 pub fn deinit(self: *Mutex) void {
36 self.* = undefined;56 self.* = undefined;
37 }57 }
3858
59 /// Try to acquire the mutex without blocking. Returns null if
60 /// the mutex is unavailable. Otherwise returns Held. Call
61 /// release on Held.
39 pub fn tryAcquire(self: *Mutex) ?Held {62 pub fn tryAcquire(self: *Mutex) ?Held {
40 if (std.debug.runtime_safety) {63 if (std.debug.runtime_safety) {
41 if (self.lock) return null;64 if (self.lock) return null;
...@@ -44,6 +67,8 @@ pub const Mutex = if (builtin.single_threaded)...@@ -44,6 +67,8 @@ pub const Mutex = if (builtin.single_threaded)
44 return Held{ .mutex = self };67 return Held{ .mutex = self };
45 }68 }
4669
70 /// Acquire the mutex. Will deadlock if the mutex is already
71 /// held by the calling thread.
47 pub fn acquire(self: *Mutex) Held {72 pub fn acquire(self: *Mutex) Held {
48 return self.tryAcquire() orelse @panic("deadlock detected");73 return self.tryAcquire() orelse @panic("deadlock detected");
49 }74 }
...@@ -220,9 +245,12 @@ else if (builtin.link_libc or builtin.os == .linux)...@@ -220,9 +245,12 @@ else if (builtin.link_libc or builtin.os == .linux)
220 }245 }
221 }246 }
222247
248 /// Returned when the lock is acquired. Call release to
249 /// release.
223 pub const Held = struct {250 pub const Held = struct {
224 mutex: *Mutex,251 mutex: *Mutex,
225252
253 /// Release the held lock.
226 pub fn release(self: Held) void {254 pub fn release(self: Held) void {
227 // first, remove the lock bit so another possibly parallel acquire() can succeed.255 // first, remove the lock bit so another possibly parallel acquire() can succeed.
228 // use .Sub since it can be usually compiled down more efficiency256 // use .Sub since it can be usually compiled down more efficiency