Created
December 11, 2020 15:08
-
-
Save lithdew/ffc6620e632e965e6fc9fcb963e021eb to your computer and use it in GitHub Desktop.
sync.Counter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub const Counter = struct { | |
const Self = @This(); | |
state: isize = 0, | |
event: Event = .{}, | |
pub fn add(self: *Self, delta: isize) void { | |
var state = @atomicLoad(isize, &self.state, .Monotonic); | |
var new_state: isize = undefined; | |
while (true) { | |
new_state = state + delta; | |
state = @cmpxchgWeak( | |
isize, | |
&self.state, | |
state, | |
new_state, | |
.Monotonic, | |
.Monotonic, | |
) orelse break; | |
} | |
if (new_state == 0) { | |
self.event.notify(); | |
} | |
} | |
pub fn wait(self: *Self) void { | |
self.event.wait(); | |
} | |
}; | |
pub const Event = struct { | |
state: ?*pike.Task = null, | |
var notified: pike.Task = undefined; | |
pub fn wait(self: *Event) void { | |
var task = pike.Task.init(@frame()); | |
suspend { | |
var state = @atomicLoad(?*pike.Task, &self.state, .Monotonic); | |
while (true) { | |
const new_state = if (state == ¬ified) null else if (state == null) &task else unreachable; | |
state = @cmpxchgWeak( | |
?*pike.Task, | |
&self.state, | |
state, | |
new_state, | |
.Release, | |
.Monotonic, | |
) orelse { | |
if (new_state == null) pike.dispatch(&task, .{}); | |
break; | |
}; | |
} | |
} | |
} | |
pub fn notify(self: *Event) void { | |
var state = @atomicLoad(?*pike.Task, &self.state, .Monotonic); | |
while (true) { | |
if (state == ¬ified) | |
return; | |
const new_state = if (state == null) ¬ified else null; | |
state = @cmpxchgWeak( | |
?*pike.Task, | |
&self.state, | |
state, | |
new_state, | |
.Acquire, | |
.Monotonic, | |
) orelse { | |
if (state) |task| pike.dispatch(task, .{}); | |
break; | |
}; | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment