| ... | @@ -3,6 +3,9 @@ | ... | @@ -3,6 +3,9 @@ |
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. |
| 4 | // The MIT license requires this copyright notice to be included in all copies | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | // and substantial portions of the software. | 5 | // and substantial portions of the software. |
| | 6 | |
| | 7 | const builtin = @import("std").builtin; |
| | 8 | |
| 6 | /// Thread-safe, lock-free integer | 9 | /// Thread-safe, lock-free integer |
| 7 | pub fn Int(comptime T: type) type { | 10 | pub fn Int(comptime T: type) type { |
| 8 | return struct { | 11 | return struct { |
| ... | @@ -14,30 +17,43 @@ pub fn Int(comptime T: type) type { | ... | @@ -14,30 +17,43 @@ pub fn Int(comptime T: type) type { |
| 14 | return Self{ .unprotected_value = init_val }; | 17 | return Self{ .unprotected_value = init_val }; |
| 15 | } | 18 | } |
| 16 | | 19 | |
| | 20 | /// Read, Modify, Write |
| | 21 | pub fn rmw(self: *Self, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T { |
| | 22 | return @atomicRmw(T, &self.unprotected_value, operand, ordering); |
| | 23 | } |
| | 24 | |
| | 25 | pub fn load(self: *Self, comptime ordering: builtin.AtomicOrder) T { |
| | 26 | return @atomicLoad(T, &self.unprotected_value, ordering); |
| | 27 | } |
| | 28 | |
| | 29 | pub fn store(self: *Self, value: T, comptime ordering: builtin.AtomicOrder) void { |
| | 30 | @atomicStore(T, &self.unprotected_value, value, ordering); |
| | 31 | } |
| | 32 | |
| 17 | /// Returns previous value | 33 | /// Returns previous value |
| 18 | pub fn incr(self: *Self) T { | 34 | pub fn incr(self: *Self) T { |
| 19 | return @atomicRmw(T, &self.unprotected_value, .Add, 1, .SeqCst); | 35 | return self.rmw(.Add, 1, .SeqCst); |
| 20 | } | 36 | } |
| 21 | | 37 | |
| 22 | /// Returns previous value | 38 | /// Returns previous value |
| 23 | pub fn decr(self: *Self) T { | 39 | pub fn decr(self: *Self) T { |
| 24 | return @atomicRmw(T, &self.unprotected_value, .Sub, 1, .SeqCst); | 40 | return self.rmw(.Sub, 1, .SeqCst); |
| 25 | } | 41 | } |
| 26 | | 42 | |
| 27 | pub fn get(self: *Self) T { | 43 | pub fn get(self: *Self) T { |
| 28 | return @atomicLoad(T, &self.unprotected_value, .SeqCst); | 44 | return self.load(.SeqCst); |
| 29 | } | 45 | } |
| 30 | | 46 | |
| 31 | pub fn set(self: *Self, new_value: T) void { | 47 | pub fn set(self: *Self, new_value: T) void { |
| 32 | _ = self.xchg(new_value); | 48 | self.store(new_value, .SeqCst); |
| 33 | } | 49 | } |
| 34 | | 50 | |
| 35 | pub fn xchg(self: *Self, new_value: T) T { | 51 | pub fn xchg(self: *Self, new_value: T) T { |
| 36 | return @atomicRmw(T, &self.unprotected_value, .Xchg, new_value, .SeqCst); | 52 | return self.rmw(.Xchg, new_value, .SeqCst); |
| 37 | } | 53 | } |
| 38 | | 54 | |
| 39 | pub fn fetchAdd(self: *Self, op: T) T { | 55 | pub fn fetchAdd(self: *Self, op: T) T { |
| 40 | return @atomicRmw(T, &self.unprotected_value, .Add, op, .SeqCst); | 56 | return self.rmw(.Add, op, .SeqCst); |
| 41 | } | 57 | } |
| 42 | }; | 58 | }; |
| 43 | } | 59 | } |