authorgravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2019-11-05 09:31:29-06:00
committergravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2019-11-05 09:31:29-06:00
log84e370d0b2ce2240356ebd0a6007aec8620dfa10
tree4315b502adbf5c7ae2cbc153495a70f569cd43f9
parent0d4f4aad9e44043b329de0f2e556c3b61cdaafa9

Move hybrid yielding into its own struct


1 files changed, 28 insertions(+), 16 deletions(-)

lib/std/spinlock.zig+28-16
...@@ -21,23 +21,10 @@ pub const SpinLock = struct {...@@ -21,23 +21,10 @@ pub const SpinLock = struct {
21 return SpinLock{ .lock = 0 };21 return SpinLock{ .lock = 0 };
22 }22 }
2323
24 // Hybrid spinning from
25 // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
26 pub fn acquire(self: *SpinLock) Held {24 pub fn acquire(self: *SpinLock) Held {
27 var backoff: usize = 0;25 var backoff = Backoff.init();
28 while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0) : (backoff +%= 1) {26 while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0)
29 if (backoff < 10) {27 backoff.yield();
30 yieldCpu();
31 } else if (backoff < 20) {
32 for (([30]void)(undefined)) |_| yieldCpu();
33 } else if (backoff < 24) {
34 yieldThread();
35 } else if (backoff < 26) {
36 time.sleep(1 * time.millisecond);
37 } else {
38 time.sleep(10 * time.millisecond);
39 }
40 }
41 return Held{ .spinlock = self };28 return Held{ .spinlock = self };
42 }29 }
4330
...@@ -56,6 +43,31 @@ pub const SpinLock = struct {...@@ -56,6 +43,31 @@ pub const SpinLock = struct {
56 else => time.sleep(1 * time.microsecond),43 else => time.sleep(1 * time.microsecond),
57 }44 }
58 }45 }
46
47 const Backoff = struct {
48 iteration: usize,
49
50 fn init() @This() {
51 return @This(){ .iteration = 0 };
52 }
53
54 // Hybrid yielding from
55 // http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
56 fn yield(self: *@This()) void {
57 defer self.iteration +%= 1;
58 if (self.iteration < 10) {
59 yieldCpu();
60 } else if (self.iteration < 20) {
61 for (([30]void)(undefined)) |_| yieldCpu();
62 } else if (self.iteration < 24) {
63 yieldThread();
64 } else if (self.iteration < 26) {
65 time.sleep(1 * time.millisecond);
66 } else {
67 time.sleep(10 * time.millisecond);
68 }
69 }
70 };
59};71};
6072
61test "spinlock" {73test "spinlock" {