2018-10-03 18:19:10 +01:00
|
|
|
const std = @import("index.zig");
|
|
|
|
const builtin = @import("builtin");
|
|
|
|
const AtomicOrder = builtin.AtomicOrder;
|
|
|
|
const AtomicRmwOp = builtin.AtomicRmwOp;
|
|
|
|
const assert = std.debug.assert;
|
|
|
|
|
2018-11-13 13:08:37 +00:00
|
|
|
pub const SpinLock = struct {
|
2018-10-03 18:19:10 +01:00
|
|
|
lock: u8, // TODO use a bool or enum
|
|
|
|
|
2018-11-13 13:08:37 +00:00
|
|
|
pub const Held = struct {
|
2018-10-03 18:19:10 +01:00
|
|
|
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 {
|
2018-11-13 13:08:37 +00:00
|
|
|
return SpinLock{ .lock = 0 };
|
2018-10-03 18:19:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn acquire(self: *SpinLock) Held {
|
|
|
|
while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
|
2018-11-13 13:08:37 +00:00
|
|
|
return Held{ .spinlock = self };
|
2018-10-03 18:19:10 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
test "spinlock" {
|
|
|
|
var lock = SpinLock.init();
|
|
|
|
const held = lock.acquire();
|
|
|
|
defer held.release();
|
|
|
|
}
|