aboutsummaryrefslogtreecommitdiff
path: root/std/spinlock.zig
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-10-03 13:19:10 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-10-03 13:19:10 -0400
commit66cb75d1148fffdd161e7829b9e27aa52f0f1616 (patch)
treef682927047f57940ebbd33ab81e254d69b731a39 /std/spinlock.zig
parentacefcdbca58efd97bf5346eb7dae22c49efa1a3d (diff)
downloadzig-66cb75d1148fffdd161e7829b9e27aa52f0f1616.tar.gz
zig-66cb75d1148fffdd161e7829b9e27aa52f0f1616.zip
std.Mutex: implement blocking mutexes on linux
closes #1463 Thanks to Shawn Landden for the original pull request. This commit is based on that code.
Diffstat (limited to 'std/spinlock.zig')
-rw-r--r--std/spinlock.zig32
1 files changed, 32 insertions, 0 deletions
diff --git a/std/spinlock.zig b/std/spinlock.zig
new file mode 100644
index 0000000000..75fdf9f6e1
--- /dev/null
+++ b/std/spinlock.zig
@@ -0,0 +1,32 @@
+const std = @import("index.zig");
+const builtin = @import("builtin");
+const AtomicOrder = builtin.AtomicOrder;
+const AtomicRmwOp = builtin.AtomicRmwOp;
+const assert = std.debug.assert;
+
+pub const SpinLock = struct {
+ lock: u8, // TODO use a bool or enum
+
+ pub const Held = struct {
+ spinlock: *SpinLock,
+
+ pub fn release(self: Held) void {
+ assert(@atomicRmw(u8, &self.spinlock.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);
+ }
+ };
+
+ pub fn init() SpinLock {
+ return SpinLock{ .lock = 0 };
+ }
+
+ pub fn acquire(self: *SpinLock) Held {
+ while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
+ return Held{ .spinlock = self };
+ }
+};
+
+test "spinlock" {
+ var lock = SpinLock.init();
+ const held = lock.acquire();
+ defer held.release();
+}