From 84e370d0b2ce2240356ebd0a6007aec8620dfa10 Mon Sep 17 00:00:00 2001 From: kprotty Date: Tue, 5 Nov 2019 09:31:29 -0600 Subject: [PATCH] Move hybrid yielding into its own struct --- lib/std/spinlock.zig | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig index 894acd0fc4..8a485ef0fe 100644 --- a/lib/std/spinlock.zig +++ b/lib/std/spinlock.zig @@ -21,23 +21,10 @@ pub const SpinLock = struct { return SpinLock{ .lock = 0 }; } - // Hybrid spinning from - // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning pub fn acquire(self: *SpinLock) Held { - var backoff: usize = 0; - while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0) : (backoff +%= 1) { - if (backoff < 10) { - yieldCpu(); - } else if (backoff < 20) { - for (([30]void)(undefined)) |_| yieldCpu(); - } else if (backoff < 24) { - yieldThread(); - } else if (backoff < 26) { - time.sleep(1 * time.millisecond); - } else { - time.sleep(10 * time.millisecond); - } - } + var backoff = Backoff.init(); + while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0) + backoff.yield(); return Held{ .spinlock = self }; } @@ -56,6 +43,31 @@ pub const SpinLock = struct { else => time.sleep(1 * time.microsecond), } } + + const Backoff = struct { + iteration: usize, + + fn init() @This() { + return @This(){ .iteration = 0 }; + } + + // Hybrid yielding from + // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning + fn yield(self: *@This()) void { + defer self.iteration +%= 1; + if (self.iteration < 10) { + yieldCpu(); + } else if (self.iteration < 20) { + for (([30]void)(undefined)) |_| yieldCpu(); + } else if (self.iteration < 24) { + yieldThread(); + } else if (self.iteration < 26) { + time.sleep(1 * time.millisecond); + } else { + time.sleep(10 * time.millisecond); + } + } + }; }; test "spinlock" {