authorgravatar for tristan.ross@midstall.comTristan Ross <tristan.ross@midstall.com> 2024-02-18 21:52:23-08:00
committergravatar for tristan.ross@midstall.comTristan Ross <tristan.ross@midstall.com> 2024-03-11 07:09:10-07:00
log6067d39522f939c08dd3f3ea4fb5889ff0024e72
tree0eb768171ecfb058fba72d199afc951af206f8fb
parentc260b4c753d1e5f947e0d33ce39ce173e497309f
signaturelock-open Commit is signed but in an unrecognized format.

std.builtin: make atomic order fields lowercase


45 files changed, 367 insertions(+), 367 deletions(-)

lib/build_runner.zig+6-6
...@@ -892,10 +892,10 @@ fn workerMakeOneStep(...@@ -892,10 +892,10 @@ fn workerMakeOneStep(
892 // then we return without doing the step, relying on another worker to892 // then we return without doing the step, relying on another worker to
893 // queue this step up again when dependencies are met.893 // queue this step up again when dependencies are met.
894 for (s.dependencies.items) |dep| {894 for (s.dependencies.items) |dep| {
895 switch (@atomicLoad(Step.State, &dep.state, .SeqCst)) {895 switch (@atomicLoad(Step.State, &dep.state, .seq_cst)) {
896 .success, .skipped => continue,896 .success, .skipped => continue,
897 .failure, .dependency_failure, .skipped_oom => {897 .failure, .dependency_failure, .skipped_oom => {
898 @atomicStore(Step.State, &s.state, .dependency_failure, .SeqCst);898 @atomicStore(Step.State, &s.state, .dependency_failure, .seq_cst);
899 return;899 return;
900 },900 },
901 .precheck_done, .running => {901 .precheck_done, .running => {
...@@ -929,7 +929,7 @@ fn workerMakeOneStep(...@@ -929,7 +929,7 @@ fn workerMakeOneStep(
929 s.state = .running;929 s.state = .running;
930 } else {930 } else {
931 // Avoid running steps twice.931 // Avoid running steps twice.
932 if (@cmpxchgStrong(Step.State, &s.state, .precheck_done, .running, .SeqCst, .SeqCst) != null) {932 if (@cmpxchgStrong(Step.State, &s.state, .precheck_done, .running, .seq_cst, .seq_cst) != null) {
933 // Another worker got the job.933 // Another worker got the job.
934 return;934 return;
935 }935 }
...@@ -956,13 +956,13 @@ fn workerMakeOneStep(...@@ -956,13 +956,13 @@ fn workerMakeOneStep(
956956
957 handle_result: {957 handle_result: {
958 if (make_result) |_| {958 if (make_result) |_| {
959 @atomicStore(Step.State, &s.state, .success, .SeqCst);959 @atomicStore(Step.State, &s.state, .success, .seq_cst);
960 } else |err| switch (err) {960 } else |err| switch (err) {
961 error.MakeFailed => {961 error.MakeFailed => {
962 @atomicStore(Step.State, &s.state, .failure, .SeqCst);962 @atomicStore(Step.State, &s.state, .failure, .seq_cst);
963 break :handle_result;963 break :handle_result;
964 },964 },
965 error.MakeSkipped => @atomicStore(Step.State, &s.state, .skipped, .SeqCst),965 error.MakeSkipped => @atomicStore(Step.State, &s.state, .skipped, .seq_cst),
966 }966 }
967967
968 // Successful completion of a step, so we queue up its dependants as well.968 // Successful completion of a step, so we queue up its dependants as well.
lib/compiler_rt/atomics.zig+9-9
...@@ -74,7 +74,7 @@ const SpinlockTable = struct {...@@ -74,7 +74,7 @@ const SpinlockTable = struct {
74 : "memory"74 : "memory"
75 );75 );
76 } else flag: {76 } else flag: {
77 break :flag @atomicRmw(@TypeOf(self.v), &self.v, .Xchg, .Locked, .Acquire);77 break :flag @atomicRmw(@TypeOf(self.v), &self.v, .Xchg, .Locked, .acquire);
78 };78 };
7979
80 switch (flag) {80 switch (flag) {
...@@ -91,7 +91,7 @@ const SpinlockTable = struct {...@@ -91,7 +91,7 @@ const SpinlockTable = struct {
91 : "memory"91 : "memory"
92 );92 );
93 } else {93 } else {
94 @atomicStore(@TypeOf(self.v), &self.v, .Unlocked, .Release);94 @atomicStore(@TypeOf(self.v), &self.v, .Unlocked, .release);
95 }95 }
96 }96 }
97 };97 };
...@@ -172,7 +172,7 @@ inline fn atomic_load_N(comptime T: type, src: *T, model: i32) T {...@@ -172,7 +172,7 @@ inline fn atomic_load_N(comptime T: type, src: *T, model: i32) T {
172 defer sl.release();172 defer sl.release();
173 return src.*;173 return src.*;
174 } else {174 } else {
175 return @atomicLoad(T, src, .SeqCst);175 return @atomicLoad(T, src, .seq_cst);
176 }176 }
177}177}
178178
...@@ -203,7 +203,7 @@ inline fn atomic_store_N(comptime T: type, dst: *T, value: T, model: i32) void {...@@ -203,7 +203,7 @@ inline fn atomic_store_N(comptime T: type, dst: *T, value: T, model: i32) void {
203 defer sl.release();203 defer sl.release();
204 dst.* = value;204 dst.* = value;
205 } else {205 } else {
206 @atomicStore(T, dst, value, .SeqCst);206 @atomicStore(T, dst, value, .seq_cst);
207 }207 }
208}208}
209209
...@@ -239,12 +239,12 @@ fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T {...@@ -239,12 +239,12 @@ fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T {
239239
240 const mask = @as(WideAtomic, std.math.maxInt(T)) << inner_shift;240 const mask = @as(WideAtomic, std.math.maxInt(T)) << inner_shift;
241241
242 var wide_old = @atomicLoad(WideAtomic, wide_ptr, .SeqCst);242 var wide_old = @atomicLoad(WideAtomic, wide_ptr, .seq_cst);
243 while (true) {243 while (true) {
244 const old = @as(T, @truncate((wide_old & mask) >> inner_shift));244 const old = @as(T, @truncate((wide_old & mask) >> inner_shift));
245 const new = update(val, old);245 const new = update(val, old);
246 const wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift);246 const wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift);
247 if (@cmpxchgWeak(WideAtomic, wide_ptr, wide_old, wide_new, .SeqCst, .SeqCst)) |new_wide_old| {247 if (@cmpxchgWeak(WideAtomic, wide_ptr, wide_old, wide_new, .seq_cst, .seq_cst)) |new_wide_old| {
248 wide_old = new_wide_old;248 wide_old = new_wide_old;
249 } else {249 } else {
250 return old;250 return old;
...@@ -270,7 +270,7 @@ inline fn atomic_exchange_N(comptime T: type, ptr: *T, val: T, model: i32) T {...@@ -270,7 +270,7 @@ inline fn atomic_exchange_N(comptime T: type, ptr: *T, val: T, model: i32) T {
270 };270 };
271 return wideUpdate(T, ptr, val, Updater.update);271 return wideUpdate(T, ptr, val, Updater.update);
272 } else {272 } else {
273 return @atomicRmw(T, ptr, .Xchg, val, .SeqCst);273 return @atomicRmw(T, ptr, .Xchg, val, .seq_cst);
274 }274 }
275}275}
276276
...@@ -315,7 +315,7 @@ inline fn atomic_compare_exchange_N(...@@ -315,7 +315,7 @@ inline fn atomic_compare_exchange_N(
315 expected.* = value;315 expected.* = value;
316 return 0;316 return 0;
317 } else {317 } else {
318 if (@cmpxchgStrong(T, ptr, expected.*, desired, .SeqCst, .SeqCst)) |old_value| {318 if (@cmpxchgStrong(T, ptr, expected.*, desired, .seq_cst, .seq_cst)) |old_value| {
319 expected.* = old_value;319 expected.* = old_value;
320 return 0;320 return 0;
321 }321 }
...@@ -373,7 +373,7 @@ inline fn fetch_op_N(comptime T: type, comptime op: std.builtin.AtomicRmwOp, ptr...@@ -373,7 +373,7 @@ inline fn fetch_op_N(comptime T: type, comptime op: std.builtin.AtomicRmwOp, ptr
373 return wideUpdate(T, ptr, val, Updater.update);373 return wideUpdate(T, ptr, val, Updater.update);
374 }374 }
375375
376 return @atomicRmw(T, ptr, op, val, .SeqCst);376 return @atomicRmw(T, ptr, op, val, .seq_cst);
377}377}
378378
379fn __atomic_fetch_add_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 {379fn __atomic_fetch_add_1(ptr: *u8, val: u8, model: i32) callconv(.C) u8 {
lib/std/Progress.zig+13-13
...@@ -95,9 +95,9 @@ pub const Node = struct {...@@ -95,9 +95,9 @@ pub const Node = struct {
95 /// This is the same as calling `start` and then `end` on the returned `Node`. Thread-safe.95 /// This is the same as calling `start` and then `end` on the returned `Node`. Thread-safe.
96 pub fn completeOne(self: *Node) void {96 pub fn completeOne(self: *Node) void {
97 if (self.parent) |parent| {97 if (self.parent) |parent| {
98 @atomicStore(?*Node, &parent.recently_updated_child, self, .Release);98 @atomicStore(?*Node, &parent.recently_updated_child, self, .release);
99 }99 }
100 _ = @atomicRmw(usize, &self.unprotected_completed_items, .Add, 1, .Monotonic);100 _ = @atomicRmw(usize, &self.unprotected_completed_items, .Add, 1, .monotonic);
101 self.context.maybeRefresh();101 self.context.maybeRefresh();
102 }102 }
103103
...@@ -108,7 +108,7 @@ pub const Node = struct {...@@ -108,7 +108,7 @@ pub const Node = struct {
108 {108 {
109 self.context.update_mutex.lock();109 self.context.update_mutex.lock();
110 defer self.context.update_mutex.unlock();110 defer self.context.update_mutex.unlock();
111 _ = @cmpxchgStrong(?*Node, &parent.recently_updated_child, self, null, .Monotonic, .Monotonic);111 _ = @cmpxchgStrong(?*Node, &parent.recently_updated_child, self, null, .monotonic, .monotonic);
112 }112 }
113 parent.completeOne();113 parent.completeOne();
114 } else {114 } else {
...@@ -122,7 +122,7 @@ pub const Node = struct {...@@ -122,7 +122,7 @@ pub const Node = struct {
122 /// Tell the parent node that this node is actively being worked on. Thread-safe.122 /// Tell the parent node that this node is actively being worked on. Thread-safe.
123 pub fn activate(self: *Node) void {123 pub fn activate(self: *Node) void {
124 if (self.parent) |parent| {124 if (self.parent) |parent| {
125 @atomicStore(?*Node, &parent.recently_updated_child, self, .Release);125 @atomicStore(?*Node, &parent.recently_updated_child, self, .release);
126 self.context.maybeRefresh();126 self.context.maybeRefresh();
127 }127 }
128 }128 }
...@@ -134,9 +134,9 @@ pub const Node = struct {...@@ -134,9 +134,9 @@ pub const Node = struct {
134 defer progress.update_mutex.unlock();134 defer progress.update_mutex.unlock();
135 self.name = name;135 self.name = name;
136 if (self.parent) |parent| {136 if (self.parent) |parent| {
137 @atomicStore(?*Node, &parent.recently_updated_child, self, .Release);137 @atomicStore(?*Node, &parent.recently_updated_child, self, .release);
138 if (parent.parent) |grand_parent| {138 if (parent.parent) |grand_parent| {
139 @atomicStore(?*Node, &grand_parent.recently_updated_child, parent, .Release);139 @atomicStore(?*Node, &grand_parent.recently_updated_child, parent, .release);
140 }140 }
141 if (progress.timer) |*timer| progress.maybeRefreshWithHeldLock(timer);141 if (progress.timer) |*timer| progress.maybeRefreshWithHeldLock(timer);
142 }142 }
...@@ -149,9 +149,9 @@ pub const Node = struct {...@@ -149,9 +149,9 @@ pub const Node = struct {
149 defer progress.update_mutex.unlock();149 defer progress.update_mutex.unlock();
150 self.unit = unit;150 self.unit = unit;
151 if (self.parent) |parent| {151 if (self.parent) |parent| {
152 @atomicStore(?*Node, &parent.recently_updated_child, self, .Release);152 @atomicStore(?*Node, &parent.recently_updated_child, self, .release);
153 if (parent.parent) |grand_parent| {153 if (parent.parent) |grand_parent| {
154 @atomicStore(?*Node, &grand_parent.recently_updated_child, parent, .Release);154 @atomicStore(?*Node, &grand_parent.recently_updated_child, parent, .release);
155 }155 }
156 if (progress.timer) |*timer| progress.maybeRefreshWithHeldLock(timer);156 if (progress.timer) |*timer| progress.maybeRefreshWithHeldLock(timer);
157 }157 }
...@@ -159,12 +159,12 @@ pub const Node = struct {...@@ -159,12 +159,12 @@ pub const Node = struct {
159159
160 /// Thread-safe. 0 means unknown.160 /// Thread-safe. 0 means unknown.
161 pub fn setEstimatedTotalItems(self: *Node, count: usize) void {161 pub fn setEstimatedTotalItems(self: *Node, count: usize) void {
162 @atomicStore(usize, &self.unprotected_estimated_total_items, count, .Monotonic);162 @atomicStore(usize, &self.unprotected_estimated_total_items, count, .monotonic);
163 }163 }
164164
165 /// Thread-safe.165 /// Thread-safe.
166 pub fn setCompletedItems(self: *Node, completed_items: usize) void {166 pub fn setCompletedItems(self: *Node, completed_items: usize) void {
167 @atomicStore(usize, &self.unprotected_completed_items, completed_items, .Monotonic);167 @atomicStore(usize, &self.unprotected_completed_items, completed_items, .monotonic);
168 }168 }
169};169};
170170
...@@ -313,8 +313,8 @@ fn refreshWithHeldLock(self: *Progress) void {...@@ -313,8 +313,8 @@ fn refreshWithHeldLock(self: *Progress) void {
313 self.bufWrite(&end, "... ", .{});313 self.bufWrite(&end, "... ", .{});
314 }314 }
315 need_ellipse = false;315 need_ellipse = false;
316 const eti = @atomicLoad(usize, &node.unprotected_estimated_total_items, .Monotonic);316 const eti = @atomicLoad(usize, &node.unprotected_estimated_total_items, .monotonic);
317 const completed_items = @atomicLoad(usize, &node.unprotected_completed_items, .Monotonic);317 const completed_items = @atomicLoad(usize, &node.unprotected_completed_items, .monotonic);
318 const current_item = completed_items + 1;318 const current_item = completed_items + 1;
319 if (node.name.len != 0 or eti > 0) {319 if (node.name.len != 0 or eti > 0) {
320 if (node.name.len != 0) {320 if (node.name.len != 0) {
...@@ -331,7 +331,7 @@ fn refreshWithHeldLock(self: *Progress) void {...@@ -331,7 +331,7 @@ fn refreshWithHeldLock(self: *Progress) void {
331 need_ellipse = false;331 need_ellipse = false;
332 }332 }
333 }333 }
334 maybe_node = @atomicLoad(?*Node, &node.recently_updated_child, .Acquire);334 maybe_node = @atomicLoad(?*Node, &node.recently_updated_child, .acquire);
335 }335 }
336 if (need_ellipse) {336 if (need_ellipse) {
337 self.bufWrite(&end, "... ", .{});337 self.bufWrite(&end, "... ", .{});
lib/std/Thread.zig+12-12
...@@ -510,7 +510,7 @@ const WindowsThreadImpl = struct {...@@ -510,7 +510,7 @@ const WindowsThreadImpl = struct {
510510
511 fn entryFn(raw_ptr: windows.PVOID) callconv(.C) windows.DWORD {511 fn entryFn(raw_ptr: windows.PVOID) callconv(.C) windows.DWORD {
512 const self: *@This() = @ptrCast(@alignCast(raw_ptr));512 const self: *@This() = @ptrCast(@alignCast(raw_ptr));
513 defer switch (self.thread.completion.swap(.completed, .SeqCst)) {513 defer switch (self.thread.completion.swap(.completed, .seq_cst)) {
514 .running => {},514 .running => {},
515 .completed => unreachable,515 .completed => unreachable,
516 .detached => self.thread.free(),516 .detached => self.thread.free(),
...@@ -563,7 +563,7 @@ const WindowsThreadImpl = struct {...@@ -563,7 +563,7 @@ const WindowsThreadImpl = struct {
563563
564 fn detach(self: Impl) void {564 fn detach(self: Impl) void {
565 windows.CloseHandle(self.thread.thread_handle);565 windows.CloseHandle(self.thread.thread_handle);
566 switch (self.thread.completion.swap(.detached, .SeqCst)) {566 switch (self.thread.completion.swap(.detached, .seq_cst)) {
567 .running => {},567 .running => {},
568 .completed => self.thread.free(),568 .completed => self.thread.free(),
569 .detached => unreachable,569 .detached => unreachable,
...@@ -573,7 +573,7 @@ const WindowsThreadImpl = struct {...@@ -573,7 +573,7 @@ const WindowsThreadImpl = struct {
573 fn join(self: Impl) void {573 fn join(self: Impl) void {
574 windows.WaitForSingleObjectEx(self.thread.thread_handle, windows.INFINITE, false) catch unreachable;574 windows.WaitForSingleObjectEx(self.thread.thread_handle, windows.INFINITE, false) catch unreachable;
575 windows.CloseHandle(self.thread.thread_handle);575 windows.CloseHandle(self.thread.thread_handle);
576 assert(self.thread.completion.load(.SeqCst) == .completed);576 assert(self.thread.completion.load(.seq_cst) == .completed);
577 self.thread.free();577 self.thread.free();
578 }578 }
579};579};
...@@ -780,11 +780,11 @@ const WasiThreadImpl = struct {...@@ -780,11 +780,11 @@ const WasiThreadImpl = struct {
780 }780 }
781781
782 fn getHandle(self: Impl) ThreadHandle {782 fn getHandle(self: Impl) ThreadHandle {
783 return self.thread.tid.load(.SeqCst);783 return self.thread.tid.load(.seq_cst);
784 }784 }
785785
786 fn detach(self: Impl) void {786 fn detach(self: Impl) void {
787 switch (self.thread.state.swap(.detached, .SeqCst)) {787 switch (self.thread.state.swap(.detached, .seq_cst)) {
788 .running => {},788 .running => {},
789 .completed => self.join(),789 .completed => self.join(),
790 .detached => unreachable,790 .detached => unreachable,
...@@ -801,7 +801,7 @@ const WasiThreadImpl = struct {...@@ -801,7 +801,7 @@ const WasiThreadImpl = struct {
801801
802 var spin: u8 = 10;802 var spin: u8 = 10;
803 while (true) {803 while (true) {
804 const tid = self.thread.tid.load(.SeqCst);804 const tid = self.thread.tid.load(.seq_cst);
805 if (tid == 0) {805 if (tid == 0) {
806 break;806 break;
807 }807 }
...@@ -901,7 +901,7 @@ const WasiThreadImpl = struct {...@@ -901,7 +901,7 @@ const WasiThreadImpl = struct {
901 if (tid < 0) {901 if (tid < 0) {
902 return error.SystemResources;902 return error.SystemResources;
903 }903 }
904 instance.thread.tid.store(tid, .SeqCst);904 instance.thread.tid.store(tid, .seq_cst);
905905
906 return .{ .thread = &instance.thread };906 return .{ .thread = &instance.thread };
907 }907 }
...@@ -914,12 +914,12 @@ const WasiThreadImpl = struct {...@@ -914,12 +914,12 @@ const WasiThreadImpl = struct {
914 }914 }
915 __set_stack_pointer(arg.thread.memory.ptr + arg.stack_offset);915 __set_stack_pointer(arg.thread.memory.ptr + arg.stack_offset);
916 __wasm_init_tls(arg.thread.memory.ptr + arg.tls_offset);916 __wasm_init_tls(arg.thread.memory.ptr + arg.tls_offset);
917 @atomicStore(u32, &WasiThreadImpl.tls_thread_id, @intCast(tid), .SeqCst);917 @atomicStore(u32, &WasiThreadImpl.tls_thread_id, @intCast(tid), .seq_cst);
918918
919 // Finished bootstrapping, call user's procedure.919 // Finished bootstrapping, call user's procedure.
920 arg.call_back(arg.raw_ptr);920 arg.call_back(arg.raw_ptr);
921921
922 switch (arg.thread.state.swap(.completed, .SeqCst)) {922 switch (arg.thread.state.swap(.completed, .seq_cst)) {
923 .running => {923 .running => {
924 // reset the Thread ID924 // reset the Thread ID
925 asm volatile (925 asm volatile (
...@@ -1191,7 +1191,7 @@ const LinuxThreadImpl = struct {...@@ -1191,7 +1191,7 @@ const LinuxThreadImpl = struct {
11911191
1192 fn entryFn(raw_arg: usize) callconv(.C) u8 {1192 fn entryFn(raw_arg: usize) callconv(.C) u8 {
1193 const self = @as(*@This(), @ptrFromInt(raw_arg));1193 const self = @as(*@This(), @ptrFromInt(raw_arg));
1194 defer switch (self.thread.completion.swap(.completed, .SeqCst)) {1194 defer switch (self.thread.completion.swap(.completed, .seq_cst)) {
1195 .running => {},1195 .running => {},
1196 .completed => unreachable,1196 .completed => unreachable,
1197 .detached => self.thread.freeAndExit(),1197 .detached => self.thread.freeAndExit(),
...@@ -1311,7 +1311,7 @@ const LinuxThreadImpl = struct {...@@ -1311,7 +1311,7 @@ const LinuxThreadImpl = struct {
1311 }1311 }
13121312
1313 fn detach(self: Impl) void {1313 fn detach(self: Impl) void {
1314 switch (self.thread.completion.swap(.detached, .SeqCst)) {1314 switch (self.thread.completion.swap(.detached, .seq_cst)) {
1315 .running => {},1315 .running => {},
1316 .completed => self.join(),1316 .completed => self.join(),
1317 .detached => unreachable,1317 .detached => unreachable,
...@@ -1323,7 +1323,7 @@ const LinuxThreadImpl = struct {...@@ -1323,7 +1323,7 @@ const LinuxThreadImpl = struct {
13231323
1324 var spin: u8 = 10;1324 var spin: u8 = 10;
1325 while (true) {1325 while (true) {
1326 const tid = self.thread.child_tid.load(.SeqCst);1326 const tid = self.thread.child_tid.load(.seq_cst);
1327 if (tid == 0) {1327 if (tid == 0) {
1328 break;1328 break;
1329 }1329 }
lib/std/Thread/Condition.zig+12-12
...@@ -163,7 +163,7 @@ const WindowsImpl = struct {...@@ -163,7 +163,7 @@ const WindowsImpl = struct {
163163
164 if (comptime builtin.mode == .Debug) {164 if (comptime builtin.mode == .Debug) {
165 // The internal state of the DebugMutex needs to be handled here as well.165 // The internal state of the DebugMutex needs to be handled here as well.
166 mutex.impl.locking_thread.store(0, .Unordered);166 mutex.impl.locking_thread.store(0, .unordered);
167 }167 }
168 const rc = os.windows.kernel32.SleepConditionVariableSRW(168 const rc = os.windows.kernel32.SleepConditionVariableSRW(
169 &self.condition,169 &self.condition,
...@@ -173,7 +173,7 @@ const WindowsImpl = struct {...@@ -173,7 +173,7 @@ const WindowsImpl = struct {
173 );173 );
174 if (comptime builtin.mode == .Debug) {174 if (comptime builtin.mode == .Debug) {
175 // The internal state of the DebugMutex needs to be handled here as well.175 // The internal state of the DebugMutex needs to be handled here as well.
176 mutex.impl.locking_thread.store(std.Thread.getCurrentId(), .Unordered);176 mutex.impl.locking_thread.store(std.Thread.getCurrentId(), .unordered);
177 }177 }
178178
179 // Return error.Timeout if we know the timeout elapsed correctly.179 // Return error.Timeout if we know the timeout elapsed correctly.
...@@ -212,8 +212,8 @@ const FutexImpl = struct {...@@ -212,8 +212,8 @@ const FutexImpl = struct {
212 // - T1: s & signals == 0 -> FUTEX_WAIT(&epoch, e) (missed the state update + the epoch change)212 // - T1: s & signals == 0 -> FUTEX_WAIT(&epoch, e) (missed the state update + the epoch change)
213 //213 //
214 // Acquire barrier to ensure the epoch load happens before the state load.214 // Acquire barrier to ensure the epoch load happens before the state load.
215 var epoch = self.epoch.load(.Acquire);215 var epoch = self.epoch.load(.acquire);
216 var state = self.state.fetchAdd(one_waiter, .Monotonic);216 var state = self.state.fetchAdd(one_waiter, .monotonic);
217 assert(state & waiter_mask != waiter_mask);217 assert(state & waiter_mask != waiter_mask);
218 state += one_waiter;218 state += one_waiter;
219219
...@@ -231,30 +231,30 @@ const FutexImpl = struct {...@@ -231,30 +231,30 @@ const FutexImpl = struct {
231 // Acquire barrier ensures code before the wake() which added the signal happens before we decrement it and return.231 // Acquire barrier ensures code before the wake() which added the signal happens before we decrement it and return.
232 while (state & signal_mask != 0) {232 while (state & signal_mask != 0) {
233 const new_state = state - one_waiter - one_signal;233 const new_state = state - one_waiter - one_signal;
234 state = self.state.cmpxchgWeak(state, new_state, .Acquire, .Monotonic) orelse return;234 state = self.state.cmpxchgWeak(state, new_state, .acquire, .monotonic) orelse return;
235 }235 }
236236
237 // Remove the waiter we added and officially return timed out.237 // Remove the waiter we added and officially return timed out.
238 const new_state = state - one_waiter;238 const new_state = state - one_waiter;
239 state = self.state.cmpxchgWeak(state, new_state, .Monotonic, .Monotonic) orelse return err;239 state = self.state.cmpxchgWeak(state, new_state, .monotonic, .monotonic) orelse return err;
240 }240 }
241 },241 },
242 };242 };
243243
244 epoch = self.epoch.load(.Acquire);244 epoch = self.epoch.load(.acquire);
245 state = self.state.load(.Monotonic);245 state = self.state.load(.monotonic);
246246
247 // Try to wake up by consuming a signal and decremented the waiter we added previously.247 // Try to wake up by consuming a signal and decremented the waiter we added previously.
248 // Acquire barrier ensures code before the wake() which added the signal happens before we decrement it and return.248 // Acquire barrier ensures code before the wake() which added the signal happens before we decrement it and return.
249 while (state & signal_mask != 0) {249 while (state & signal_mask != 0) {
250 const new_state = state - one_waiter - one_signal;250 const new_state = state - one_waiter - one_signal;
251 state = self.state.cmpxchgWeak(state, new_state, .Acquire, .Monotonic) orelse return;251 state = self.state.cmpxchgWeak(state, new_state, .acquire, .monotonic) orelse return;
252 }252 }
253 }253 }
254 }254 }
255255
256 fn wake(self: *Impl, comptime notify: Notify) void {256 fn wake(self: *Impl, comptime notify: Notify) void {
257 var state = self.state.load(.Monotonic);257 var state = self.state.load(.monotonic);
258 while (true) {258 while (true) {
259 const waiters = (state & waiter_mask) / one_waiter;259 const waiters = (state & waiter_mask) / one_waiter;
260 const signals = (state & signal_mask) / one_signal;260 const signals = (state & signal_mask) / one_signal;
...@@ -275,7 +275,7 @@ const FutexImpl = struct {...@@ -275,7 +275,7 @@ const FutexImpl = struct {
275 // Reserve the amount of waiters to wake by incrementing the signals count.275 // Reserve the amount of waiters to wake by incrementing the signals count.
276 // Release barrier ensures code before the wake() happens before the signal it posted and consumed by the wait() threads.276 // Release barrier ensures code before the wake() happens before the signal it posted and consumed by the wait() threads.
277 const new_state = state + (one_signal * to_wake);277 const new_state = state + (one_signal * to_wake);
278 state = self.state.cmpxchgWeak(state, new_state, .Release, .Monotonic) orelse {278 state = self.state.cmpxchgWeak(state, new_state, .release, .monotonic) orelse {
279 // Wake up the waiting threads we reserved above by changing the epoch value.279 // Wake up the waiting threads we reserved above by changing the epoch value.
280 // NOTE: a waiting thread could miss a wake up if *exactly* ((1<<32)-1) wake()s happen between it observing the epoch and sleeping on it.280 // NOTE: a waiting thread could miss a wake up if *exactly* ((1<<32)-1) wake()s happen between it observing the epoch and sleeping on it.
281 // This is very unlikely due to how many precise amount of Futex.wake() calls that would be between the waiting thread's potential preemption.281 // This is very unlikely due to how many precise amount of Futex.wake() calls that would be between the waiting thread's potential preemption.
...@@ -288,7 +288,7 @@ const FutexImpl = struct {...@@ -288,7 +288,7 @@ const FutexImpl = struct {
288 // - T1: s = LOAD(&state)288 // - T1: s = LOAD(&state)
289 // - T2: UPDATE(&state, signal) + FUTEX_WAKE(&epoch)289 // - T2: UPDATE(&state, signal) + FUTEX_WAKE(&epoch)
290 // - T1: s & signals == 0 -> FUTEX_WAIT(&epoch, e) (missed both epoch change and state change)290 // - T1: s & signals == 0 -> FUTEX_WAIT(&epoch, e) (missed both epoch change and state change)
291 _ = self.epoch.fetchAdd(1, .Release);291 _ = self.epoch.fetchAdd(1, .release);
292 Futex.wake(&self.epoch, to_wake);292 Futex.wake(&self.epoch, to_wake);
293 return;293 return;
294 };294 };
lib/std/Thread/Futex.zig+15-15
...@@ -40,7 +40,7 @@ pub fn timedWait(ptr: *const atomic.Value(u32), expect: u32, timeout_ns: u64) er...@@ -40,7 +40,7 @@ pub fn timedWait(ptr: *const atomic.Value(u32), expect: u32, timeout_ns: u64) er
4040
41 // Avoid calling into the OS for no-op timeouts.41 // Avoid calling into the OS for no-op timeouts.
42 if (timeout_ns == 0) {42 if (timeout_ns == 0) {
43 if (ptr.load(.SeqCst) != expect) return;43 if (ptr.load(.seq_cst) != expect) return;
44 return error.Timeout;44 return error.Timeout;
45 }45 }
4646
...@@ -783,16 +783,16 @@ const PosixImpl = struct {...@@ -783,16 +783,16 @@ const PosixImpl = struct {
783 // - T1: bumps pending waiters (was reordered after the ptr == expect check)783 // - T1: bumps pending waiters (was reordered after the ptr == expect check)
784 // - T1: goes to sleep and misses both the ptr change and T2's wake up784 // - T1: goes to sleep and misses both the ptr change and T2's wake up
785 //785 //
786 // SeqCst as Acquire barrier to ensure the announcement happens before the ptr check below.786 // seq_cst as Acquire barrier to ensure the announcement happens before the ptr check below.
787 // SeqCst as shared modification order to form a happens-before edge with the fence(.SeqCst)+load() in wake().787 // seq_cst as shared modification order to form a happens-before edge with the fence(.seq_cst)+load() in wake().
788 var pending = bucket.pending.fetchAdd(1, .SeqCst);788 var pending = bucket.pending.fetchAdd(1, .seq_cst);
789 assert(pending < std.math.maxInt(usize));789 assert(pending < std.math.maxInt(usize));
790790
791 // If the wait gets cancelled, remove the pending count we previously added.791 // If the wait gets cancelled, remove the pending count we previously added.
792 // This is done outside the mutex lock to keep the critical section short in case of contention.792 // This is done outside the mutex lock to keep the critical section short in case of contention.
793 var cancelled = false;793 var cancelled = false;
794 defer if (cancelled) {794 defer if (cancelled) {
795 pending = bucket.pending.fetchSub(1, .Monotonic);795 pending = bucket.pending.fetchSub(1, .monotonic);
796 assert(pending > 0);796 assert(pending > 0);
797 };797 };
798798
...@@ -850,11 +850,11 @@ const PosixImpl = struct {...@@ -850,11 +850,11 @@ const PosixImpl = struct {
850 // but the RMW operation unconditionally marks the cache-line as modified for others causing unnecessary fetching/contention.850 // but the RMW operation unconditionally marks the cache-line as modified for others causing unnecessary fetching/contention.
851 //851 //
852 // Instead we opt to do a full-fence + load instead which avoids taking ownership of the cache-line.852 // Instead we opt to do a full-fence + load instead which avoids taking ownership of the cache-line.
853 // fence(SeqCst) effectively converts the ptr update to SeqCst and the pending load to SeqCst: creating a Store-Load barrier.853 // fence(seq_cst) effectively converts the ptr update to seq_cst and the pending load to seq_cst: creating a Store-Load barrier.
854 //854 //
855 // The pending count increment in wait() must also now use SeqCst for the update + this pending load855 // The pending count increment in wait() must also now use seq_cst for the update + this pending load
856 // to be in the same modification order as our load isn't using Release/Acquire to guarantee it.856 // to be in the same modification order as our load isn't using release/acquire to guarantee it.
857 bucket.pending.fence(.SeqCst);857 bucket.pending.fence(.seq_cst);
858 if (bucket.pending.load(.Monotonic) == 0) {858 if (bucket.pending.load(.Monotonic) == 0) {
859 return;859 return;
860 }860 }
...@@ -912,7 +912,7 @@ test "signaling" {...@@ -912,7 +912,7 @@ test "signaling" {
912 current: u32 = 0,912 current: u32 = 0,
913913
914 fn hit(self: *@This()) void {914 fn hit(self: *@This()) void {
915 _ = self.value.fetchAdd(1, .Release);915 _ = self.value.fetchAdd(1, .release);
916 Futex.wake(&self.value, 1);916 Futex.wake(&self.value, 1);
917 }917 }
918918
...@@ -921,7 +921,7 @@ test "signaling" {...@@ -921,7 +921,7 @@ test "signaling" {
921 // Wait for the value to change from hit()921 // Wait for the value to change from hit()
922 var new_value: u32 = undefined;922 var new_value: u32 = undefined;
923 while (true) {923 while (true) {
924 new_value = self.value.load(.Acquire);924 new_value = self.value.load(.acquire);
925 if (new_value != self.current) break;925 if (new_value != self.current) break;
926 Futex.wait(&self.value, self.current);926 Futex.wait(&self.value, self.current);
927 }927 }
...@@ -968,7 +968,7 @@ test "broadcasting" {...@@ -968,7 +968,7 @@ test "broadcasting" {
968 fn wait(self: *@This()) !void {968 fn wait(self: *@This()) !void {
969 // Decrement the counter.969 // Decrement the counter.
970 // Release ensures stuff before this barrier.wait() happens before the last one.970 // Release ensures stuff before this barrier.wait() happens before the last one.
971 const count = self.count.fetchSub(1, .Release);971 const count = self.count.fetchSub(1, .release);
972 try testing.expect(count <= num_threads);972 try testing.expect(count <= num_threads);
973 try testing.expect(count > 0);973 try testing.expect(count > 0);
974974
...@@ -976,15 +976,15 @@ test "broadcasting" {...@@ -976,15 +976,15 @@ test "broadcasting" {
976 // Acquire for the last counter ensures stuff before previous barrier.wait()s happened before it.976 // Acquire for the last counter ensures stuff before previous barrier.wait()s happened before it.
977 // Release on futex update ensures stuff before all barrier.wait()'s happens before they all return.977 // Release on futex update ensures stuff before all barrier.wait()'s happens before they all return.
978 if (count - 1 == 0) {978 if (count - 1 == 0) {
979 _ = self.count.load(.Acquire); // TODO: could be fence(Acquire) if not for TSAN979 _ = self.count.load(.acquire); // TODO: could be fence(acquire) if not for TSAN
980 self.futex.store(1, .Release);980 self.futex.store(1, .release);
981 Futex.wake(&self.futex, num_threads - 1);981 Futex.wake(&self.futex, num_threads - 1);
982 return;982 return;
983 }983 }
984984
985 // Other threads wait until last counter wakes them up.985 // Other threads wait until last counter wakes them up.
986 // Acquire on futex synchronizes with last barrier count to ensure stuff before all barrier.wait()'s happen before us.986 // Acquire on futex synchronizes with last barrier count to ensure stuff before all barrier.wait()'s happen before us.
987 while (self.futex.load(.Acquire) == 0) {987 while (self.futex.load(.acquire) == 0) {
988 Futex.wait(&self.futex, 0);988 Futex.wait(&self.futex, 0);
989 }989 }
990 }990 }
lib/std/Thread/Mutex.zig+10-10
...@@ -72,23 +72,23 @@ const DebugImpl = struct {...@@ -72,23 +72,23 @@ const DebugImpl = struct {
72 inline fn tryLock(self: *@This()) bool {72 inline fn tryLock(self: *@This()) bool {
73 const locking = self.impl.tryLock();73 const locking = self.impl.tryLock();
74 if (locking) {74 if (locking) {
75 self.locking_thread.store(Thread.getCurrentId(), .Unordered);75 self.locking_thread.store(Thread.getCurrentId(), .unordered);
76 }76 }
77 return locking;77 return locking;
78 }78 }
7979
80 inline fn lock(self: *@This()) void {80 inline fn lock(self: *@This()) void {
81 const current_id = Thread.getCurrentId();81 const current_id = Thread.getCurrentId();
82 if (self.locking_thread.load(.Unordered) == current_id and current_id != 0) {82 if (self.locking_thread.load(.unordered) == current_id and current_id != 0) {
83 @panic("Deadlock detected");83 @panic("Deadlock detected");
84 }84 }
85 self.impl.lock();85 self.impl.lock();
86 self.locking_thread.store(current_id, .Unordered);86 self.locking_thread.store(current_id, .unordered);
87 }87 }
8888
89 inline fn unlock(self: *@This()) void {89 inline fn unlock(self: *@This()) void {
90 assert(self.locking_thread.load(.Unordered) == Thread.getCurrentId());90 assert(self.locking_thread.load(.unordered) == Thread.getCurrentId());
91 self.locking_thread.store(0, .Unordered);91 self.locking_thread.store(0, .unordered);
92 self.impl.unlock();92 self.impl.unlock();
93 }93 }
94};94};
...@@ -167,12 +167,12 @@ const FutexImpl = struct {...@@ -167,12 +167,12 @@ const FutexImpl = struct {
167 // - `lock bts` is smaller instruction-wise which makes it better for inlining167 // - `lock bts` is smaller instruction-wise which makes it better for inlining
168 if (comptime builtin.target.cpu.arch.isX86()) {168 if (comptime builtin.target.cpu.arch.isX86()) {
169 const locked_bit = @ctz(locked);169 const locked_bit = @ctz(locked);
170 return self.state.bitSet(locked_bit, .Acquire) == 0;170 return self.state.bitSet(locked_bit, .acquire) == 0;
171 }171 }
172172
173 // Acquire barrier ensures grabbing the lock happens before the critical section173 // Acquire barrier ensures grabbing the lock happens before the critical section
174 // and that the previous lock holder's critical section happens before we grab the lock.174 // and that the previous lock holder's critical section happens before we grab the lock.
175 return self.state.cmpxchgWeak(unlocked, locked, .Acquire, .Monotonic) == null;175 return self.state.cmpxchgWeak(unlocked, locked, .acquire, .monotonic) == null;
176 }176 }
177177
178 fn lockSlow(self: *@This()) void {178 fn lockSlow(self: *@This()) void {
...@@ -180,7 +180,7 @@ const FutexImpl = struct {...@@ -180,7 +180,7 @@ const FutexImpl = struct {
180180
181 // Avoid doing an atomic swap below if we already know the state is contended.181 // Avoid doing an atomic swap below if we already know the state is contended.
182 // An atomic swap unconditionally stores which marks the cache-line as modified unnecessarily.182 // An atomic swap unconditionally stores which marks the cache-line as modified unnecessarily.
183 if (self.state.load(.Monotonic) == contended) {183 if (self.state.load(.monotonic) == contended) {
184 Futex.wait(&self.state, contended);184 Futex.wait(&self.state, contended);
185 }185 }
186186
...@@ -193,7 +193,7 @@ const FutexImpl = struct {...@@ -193,7 +193,7 @@ const FutexImpl = struct {
193 //193 //
194 // Acquire barrier ensures grabbing the lock happens before the critical section194 // Acquire barrier ensures grabbing the lock happens before the critical section
195 // and that the previous lock holder's critical section happens before we grab the lock.195 // and that the previous lock holder's critical section happens before we grab the lock.
196 while (self.state.swap(contended, .Acquire) != unlocked) {196 while (self.state.swap(contended, .acquire) != unlocked) {
197 Futex.wait(&self.state, contended);197 Futex.wait(&self.state, contended);
198 }198 }
199 }199 }
...@@ -206,7 +206,7 @@ const FutexImpl = struct {...@@ -206,7 +206,7 @@ const FutexImpl = struct {
206 //206 //
207 // Release barrier ensures the critical section happens before we let go of the lock207 // Release barrier ensures the critical section happens before we let go of the lock
208 // and that our critical section happens before the next lock holder grabs the lock.208 // and that our critical section happens before the next lock holder grabs the lock.
209 const state = self.state.swap(unlocked, .Release);209 const state = self.state.swap(unlocked, .release);
210 assert(state != unlocked);210 assert(state != unlocked);
211211
212 if (state == contended) {212 if (state == contended) {
lib/std/Thread/ResetEvent.zig+9-9
...@@ -96,7 +96,7 @@ const FutexImpl = struct {...@@ -96,7 +96,7 @@ const FutexImpl = struct {
9696
97 fn isSet(self: *const Impl) bool {97 fn isSet(self: *const Impl) bool {
98 // Acquire barrier ensures memory accesses before set() happen before we return true.98 // Acquire barrier ensures memory accesses before set() happen before we return true.
99 return self.state.load(.Acquire) == is_set;99 return self.state.load(.acquire) == is_set;
100 }100 }
101101
102 fn wait(self: *Impl, timeout: ?u64) error{Timeout}!void {102 fn wait(self: *Impl, timeout: ?u64) error{Timeout}!void {
...@@ -112,9 +112,9 @@ const FutexImpl = struct {...@@ -112,9 +112,9 @@ const FutexImpl = struct {
112 // Try to set the state from `unset` to `waiting` to indicate112 // Try to set the state from `unset` to `waiting` to indicate
113 // to the set() thread that others are blocked on the ResetEvent.113 // to the set() thread that others are blocked on the ResetEvent.
114 // We avoid using any strict barriers until the end when we know the ResetEvent is set.114 // We avoid using any strict barriers until the end when we know the ResetEvent is set.
115 var state = self.state.load(.Monotonic);115 var state = self.state.load(.monotonic);
116 if (state == unset) {116 if (state == unset) {
117 state = self.state.cmpxchgStrong(state, waiting, .Monotonic, .Monotonic) orelse waiting;117 state = self.state.cmpxchgStrong(state, waiting, .monotonic, .monotonic) orelse waiting;
118 }118 }
119119
120 // Wait until the ResetEvent is set since the state is waiting.120 // Wait until the ResetEvent is set since the state is waiting.
...@@ -124,7 +124,7 @@ const FutexImpl = struct {...@@ -124,7 +124,7 @@ const FutexImpl = struct {
124 const wait_result = futex_deadline.wait(&self.state, waiting);124 const wait_result = futex_deadline.wait(&self.state, waiting);
125125
126 // Check if the ResetEvent was set before possibly reporting error.Timeout below.126 // Check if the ResetEvent was set before possibly reporting error.Timeout below.
127 state = self.state.load(.Monotonic);127 state = self.state.load(.monotonic);
128 if (state != waiting) {128 if (state != waiting) {
129 break;129 break;
130 }130 }
...@@ -135,25 +135,25 @@ const FutexImpl = struct {...@@ -135,25 +135,25 @@ const FutexImpl = struct {
135135
136 // Acquire barrier ensures memory accesses before set() happen before we return.136 // Acquire barrier ensures memory accesses before set() happen before we return.
137 assert(state == is_set);137 assert(state == is_set);
138 self.state.fence(.Acquire);138 self.state.fence(.acquire);
139 }139 }
140140
141 fn set(self: *Impl) void {141 fn set(self: *Impl) void {
142 // Quick check if the ResetEvent is already set before doing the atomic swap below.142 // Quick check if the ResetEvent is already set before doing the atomic swap below.
143 // set() could be getting called quite often and multiple threads calling swap() increases contention unnecessarily.143 // set() could be getting called quite often and multiple threads calling swap() increases contention unnecessarily.
144 if (self.state.load(.Monotonic) == is_set) {144 if (self.state.load(.monotonic) == is_set) {
145 return;145 return;
146 }146 }
147147
148 // Mark the ResetEvent as set and unblock all waiters waiting on it if any.148 // Mark the ResetEvent as set and unblock all waiters waiting on it if any.
149 // Release barrier ensures memory accesses before set() happen before the ResetEvent is observed to be "set".149 // Release barrier ensures memory accesses before set() happen before the ResetEvent is observed to be "set".
150 if (self.state.swap(is_set, .Release) == waiting) {150 if (self.state.swap(is_set, .release) == waiting) {
151 Futex.wake(&self.state, std.math.maxInt(u32));151 Futex.wake(&self.state, std.math.maxInt(u32));
152 }152 }
153 }153 }
154154
155 fn reset(self: *Impl) void {155 fn reset(self: *Impl) void {
156 self.state.store(unset, .Monotonic);156 self.state.store(unset, .monotonic);
157 }157 }
158};158};
159159
...@@ -254,7 +254,7 @@ test "broadcast" {...@@ -254,7 +254,7 @@ test "broadcast" {
254 counter: std.atomic.Value(usize) = std.atomic.Value(usize).init(num_threads),254 counter: std.atomic.Value(usize) = std.atomic.Value(usize).init(num_threads),
255255
256 fn wait(self: *@This()) void {256 fn wait(self: *@This()) void {
257 if (self.counter.fetchSub(1, .AcqRel) == 1) {257 if (self.counter.fetchSub(1, .acq_rel) == 1) {
258 self.event.set();258 self.event.set();
259 }259 }
260 }260 }
lib/std/Thread/RwLock.zig+16-16
...@@ -179,9 +179,9 @@ pub const DefaultRwLock = struct {...@@ -179,9 +179,9 @@ pub const DefaultRwLock = struct {
179179
180 pub fn tryLock(rwl: *DefaultRwLock) bool {180 pub fn tryLock(rwl: *DefaultRwLock) bool {
181 if (rwl.mutex.tryLock()) {181 if (rwl.mutex.tryLock()) {
182 const state = @atomicLoad(usize, &rwl.state, .SeqCst);182 const state = @atomicLoad(usize, &rwl.state, .seq_cst);
183 if (state & READER_MASK == 0) {183 if (state & READER_MASK == 0) {
184 _ = @atomicRmw(usize, &rwl.state, .Or, IS_WRITING, .SeqCst);184 _ = @atomicRmw(usize, &rwl.state, .Or, IS_WRITING, .seq_cst);
185 return true;185 return true;
186 }186 }
187187
...@@ -192,34 +192,34 @@ pub const DefaultRwLock = struct {...@@ -192,34 +192,34 @@ pub const DefaultRwLock = struct {
192 }192 }
193193
194 pub fn lock(rwl: *DefaultRwLock) void {194 pub fn lock(rwl: *DefaultRwLock) void {
195 _ = @atomicRmw(usize, &rwl.state, .Add, WRITER, .SeqCst);195 _ = @atomicRmw(usize, &rwl.state, .Add, WRITER, .seq_cst);
196 rwl.mutex.lock();196 rwl.mutex.lock();
197197
198 const state = @atomicRmw(usize, &rwl.state, .Add, IS_WRITING -% WRITER, .SeqCst);198 const state = @atomicRmw(usize, &rwl.state, .Add, IS_WRITING -% WRITER, .seq_cst);
199 if (state & READER_MASK != 0)199 if (state & READER_MASK != 0)
200 rwl.semaphore.wait();200 rwl.semaphore.wait();
201 }201 }
202202
203 pub fn unlock(rwl: *DefaultRwLock) void {203 pub fn unlock(rwl: *DefaultRwLock) void {
204 _ = @atomicRmw(usize, &rwl.state, .And, ~IS_WRITING, .SeqCst);204 _ = @atomicRmw(usize, &rwl.state, .And, ~IS_WRITING, .seq_cst);
205 rwl.mutex.unlock();205 rwl.mutex.unlock();
206 }206 }
207207
208 pub fn tryLockShared(rwl: *DefaultRwLock) bool {208 pub fn tryLockShared(rwl: *DefaultRwLock) bool {
209 const state = @atomicLoad(usize, &rwl.state, .SeqCst);209 const state = @atomicLoad(usize, &rwl.state, .seq_cst);
210 if (state & (IS_WRITING | WRITER_MASK) == 0) {210 if (state & (IS_WRITING | WRITER_MASK) == 0) {
211 _ = @cmpxchgStrong(211 _ = @cmpxchgStrong(
212 usize,212 usize,
213 &rwl.state,213 &rwl.state,
214 state,214 state,
215 state + READER,215 state + READER,
216 .SeqCst,216 .seq_cst,
217 .SeqCst,217 .seq_cst,
218 ) orelse return true;218 ) orelse return true;
219 }219 }
220220
221 if (rwl.mutex.tryLock()) {221 if (rwl.mutex.tryLock()) {
222 _ = @atomicRmw(usize, &rwl.state, .Add, READER, .SeqCst);222 _ = @atomicRmw(usize, &rwl.state, .Add, READER, .seq_cst);
223 rwl.mutex.unlock();223 rwl.mutex.unlock();
224 return true;224 return true;
225 }225 }
...@@ -228,25 +228,25 @@ pub const DefaultRwLock = struct {...@@ -228,25 +228,25 @@ pub const DefaultRwLock = struct {
228 }228 }
229229
230 pub fn lockShared(rwl: *DefaultRwLock) void {230 pub fn lockShared(rwl: *DefaultRwLock) void {
231 var state = @atomicLoad(usize, &rwl.state, .SeqCst);231 var state = @atomicLoad(usize, &rwl.state, .seq_cst);
232 while (state & (IS_WRITING | WRITER_MASK) == 0) {232 while (state & (IS_WRITING | WRITER_MASK) == 0) {
233 state = @cmpxchgWeak(233 state = @cmpxchgWeak(
234 usize,234 usize,
235 &rwl.state,235 &rwl.state,
236 state,236 state,
237 state + READER,237 state + READER,
238 .SeqCst,238 .seq_cst,
239 .SeqCst,239 .seq_cst,
240 ) orelse return;240 ) orelse return;
241 }241 }
242242
243 rwl.mutex.lock();243 rwl.mutex.lock();
244 _ = @atomicRmw(usize, &rwl.state, .Add, READER, .SeqCst);244 _ = @atomicRmw(usize, &rwl.state, .Add, READER, .seq_cst);
245 rwl.mutex.unlock();245 rwl.mutex.unlock();
246 }246 }
247247
248 pub fn unlockShared(rwl: *DefaultRwLock) void {248 pub fn unlockShared(rwl: *DefaultRwLock) void {
249 const state = @atomicRmw(usize, &rwl.state, .Sub, READER, .SeqCst);249 const state = @atomicRmw(usize, &rwl.state, .Sub, READER, .seq_cst);
250250
251 if ((state & READER_MASK == READER) and (state & IS_WRITING != 0))251 if ((state & READER_MASK == READER) and (state & IS_WRITING != 0))
252 rwl.semaphore.post();252 rwl.semaphore.post();
...@@ -318,12 +318,12 @@ test "concurrent access" {...@@ -318,12 +318,12 @@ test "concurrent access" {
318 self.rwl.lockShared();318 self.rwl.lockShared();
319 defer self.rwl.unlockShared();319 defer self.rwl.unlockShared();
320320
321 if (self.writes >= num_writes or self.reads.load(.Unordered) >= num_reads)321 if (self.writes >= num_writes or self.reads.load(.unordered) >= num_reads)
322 break;322 break;
323323
324 try self.check();324 try self.check();
325325
326 _ = self.reads.fetchAdd(1, .Monotonic);326 _ = self.reads.fetchAdd(1, .monotonic);
327 }327 }
328 }328 }
329329
lib/std/Thread/WaitGroup.zig+6-6
...@@ -10,22 +10,22 @@ state: std.atomic.Value(usize) = std.atomic.Value(usize).init(0),...@@ -10,22 +10,22 @@ state: std.atomic.Value(usize) = std.atomic.Value(usize).init(0),
10event: std.Thread.ResetEvent = .{},10event: std.Thread.ResetEvent = .{},
1111
12pub fn start(self: *WaitGroup) void {12pub fn start(self: *WaitGroup) void {
13 const state = self.state.fetchAdd(one_pending, .Monotonic);13 const state = self.state.fetchAdd(one_pending, .monotonic);
14 assert((state / one_pending) < (std.math.maxInt(usize) / one_pending));14 assert((state / one_pending) < (std.math.maxInt(usize) / one_pending));
15}15}
1616
17pub fn finish(self: *WaitGroup) void {17pub fn finish(self: *WaitGroup) void {
18 const state = self.state.fetchSub(one_pending, .Release);18 const state = self.state.fetchSub(one_pending, .release);
19 assert((state / one_pending) > 0);19 assert((state / one_pending) > 0);
2020
21 if (state == (one_pending | is_waiting)) {21 if (state == (one_pending | is_waiting)) {
22 self.state.fence(.Acquire);22 self.state.fence(.acquire);
23 self.event.set();23 self.event.set();
24 }24 }
25}25}
2626
27pub fn wait(self: *WaitGroup) void {27pub fn wait(self: *WaitGroup) void {
28 const state = self.state.fetchAdd(is_waiting, .Acquire);28 const state = self.state.fetchAdd(is_waiting, .acquire);
29 assert(state & is_waiting == 0);29 assert(state & is_waiting == 0);
3030
31 if ((state / one_pending) > 0) {31 if ((state / one_pending) > 0) {
...@@ -34,12 +34,12 @@ pub fn wait(self: *WaitGroup) void {...@@ -34,12 +34,12 @@ pub fn wait(self: *WaitGroup) void {
34}34}
3535
36pub fn reset(self: *WaitGroup) void {36pub fn reset(self: *WaitGroup) void {
37 self.state.store(0, .Monotonic);37 self.state.store(0, .monotonic);
38 self.event.reset();38 self.event.reset();
39}39}
4040
41pub fn isDone(wg: *WaitGroup) bool {41pub fn isDone(wg: *WaitGroup) bool {
42 const state = wg.state.load(.Acquire);42 const state = wg.state.load(.acquire);
43 assert(state & is_waiting == 0);43 assert(state & is_waiting == 0);
4444
45 return (state / one_pending) == 0;45 return (state / one_pending) == 0;
lib/std/atomic.zig+82-82
...@@ -23,10 +23,10 @@ pub fn Value(comptime T: type) type {...@@ -23,10 +23,10 @@ pub fn Value(comptime T: type) type {
2323
24 const addr: *anyopaque = self;24 const addr: *anyopaque = self;
25 return switch (order) {25 return switch (order) {
26 .Unordered, .Monotonic => @compileError(@tagName(order) ++ " only applies to atomic loads and stores"),26 .unordered, .monotonic => @compileError(@tagName(order) ++ " only applies to atomic loads and stores"),
27 .Acquire => tsan.__tsan_acquire(addr),27 .acquire => tsan.__tsan_acquire(addr),
28 .Release => tsan.__tsan_release(addr),28 .release => tsan.__tsan_release(addr),
29 .AcqRel, .SeqCst => {29 .acq_rel, .seq_cst => {
30 tsan.__tsan_acquire(addr);30 tsan.__tsan_acquire(addr);
31 tsan.__tsan_release(addr);31 tsan.__tsan_release(addr);
32 },32 },
...@@ -149,20 +149,20 @@ test Value {...@@ -149,20 +149,20 @@ test Value {
149149
150 fn ref(rc: *RefCount) void {150 fn ref(rc: *RefCount) void {
151 // No ordering necessary; just updating a counter.151 // No ordering necessary; just updating a counter.
152 _ = rc.count.fetchAdd(1, .Monotonic);152 _ = rc.count.fetchAdd(1, .monotonic);
153 }153 }
154154
155 fn unref(rc: *RefCount) void {155 fn unref(rc: *RefCount) void {
156 // Release ensures code before unref() happens-before the156 // Release ensures code before unref() happens-before the
157 // count is decremented as dropFn could be called by then.157 // count is decremented as dropFn could be called by then.
158 if (rc.count.fetchSub(1, .Release) == 1) {158 if (rc.count.fetchSub(1, .release) == 1) {
159 // Acquire ensures count decrement and code before159 // acquire ensures count decrement and code before
160 // previous unrefs()s happens-before we call dropFn160 // previous unrefs()s happens-before we call dropFn
161 // below.161 // below.
162 // Another alternative is to use .AcqRel on the162 // Another alternative is to use .AcqRel on the
163 // fetchSub count decrement but it's extra barrier in163 // fetchSub count decrement but it's extra barrier in
164 // possibly hot path.164 // possibly hot path.
165 rc.count.fence(.Acquire);165 rc.count.fence(.acquire);
166 (rc.dropFn)(rc);166 (rc.dropFn)(rc);
167 }167 }
168 }168 }
...@@ -182,118 +182,118 @@ test Value {...@@ -182,118 +182,118 @@ test Value {
182182
183test "Value.swap" {183test "Value.swap" {
184 var x = Value(usize).init(5);184 var x = Value(usize).init(5);
185 try testing.expectEqual(@as(usize, 5), x.swap(10, .SeqCst));185 try testing.expectEqual(@as(usize, 5), x.swap(10, .seq_cst));
186 try testing.expectEqual(@as(usize, 10), x.load(.SeqCst));186 try testing.expectEqual(@as(usize, 10), x.load(.seq_cst));
187187
188 const E = enum(usize) { a, b, c };188 const E = enum(usize) { a, b, c };
189 var y = Value(E).init(.c);189 var y = Value(E).init(.c);
190 try testing.expectEqual(E.c, y.swap(.a, .SeqCst));190 try testing.expectEqual(E.c, y.swap(.a, .seq_cst));
191 try testing.expectEqual(E.a, y.load(.SeqCst));191 try testing.expectEqual(E.a, y.load(.seq_cst));
192192
193 var z = Value(f32).init(5.0);193 var z = Value(f32).init(5.0);
194 try testing.expectEqual(@as(f32, 5.0), z.swap(10.0, .SeqCst));194 try testing.expectEqual(@as(f32, 5.0), z.swap(10.0, .seq_cst));
195 try testing.expectEqual(@as(f32, 10.0), z.load(.SeqCst));195 try testing.expectEqual(@as(f32, 10.0), z.load(.seq_cst));
196196
197 var a = Value(bool).init(false);197 var a = Value(bool).init(false);
198 try testing.expectEqual(false, a.swap(true, .SeqCst));198 try testing.expectEqual(false, a.swap(true, .seq_cst));
199 try testing.expectEqual(true, a.load(.SeqCst));199 try testing.expectEqual(true, a.load(.seq_cst));
200200
201 var b = Value(?*u8).init(null);201 var b = Value(?*u8).init(null);
202 try testing.expectEqual(@as(?*u8, null), b.swap(@as(?*u8, @ptrFromInt(@alignOf(u8))), .SeqCst));202 try testing.expectEqual(@as(?*u8, null), b.swap(@as(?*u8, @ptrFromInt(@alignOf(u8))), .seq_cst));
203 try testing.expectEqual(@as(?*u8, @ptrFromInt(@alignOf(u8))), b.load(.SeqCst));203 try testing.expectEqual(@as(?*u8, @ptrFromInt(@alignOf(u8))), b.load(.seq_cst));
204}204}
205205
206test "Value.store" {206test "Value.store" {
207 var x = Value(usize).init(5);207 var x = Value(usize).init(5);
208 x.store(10, .SeqCst);208 x.store(10, .seq_cst);
209 try testing.expectEqual(@as(usize, 10), x.load(.SeqCst));209 try testing.expectEqual(@as(usize, 10), x.load(.seq_cst));
210}210}
211211
212test "Value.cmpxchgWeak" {212test "Value.cmpxchgWeak" {
213 var x = Value(usize).init(0);213 var x = Value(usize).init(0);
214214
215 try testing.expectEqual(@as(?usize, 0), x.cmpxchgWeak(1, 0, .SeqCst, .SeqCst));215 try testing.expectEqual(@as(?usize, 0), x.cmpxchgWeak(1, 0, .seq_cst, .seq_cst));
216 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));216 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
217217
218 while (x.cmpxchgWeak(0, 1, .SeqCst, .SeqCst)) |_| {}218 while (x.cmpxchgWeak(0, 1, .seq_cst, .seq_cst)) |_| {}
219 try testing.expectEqual(@as(usize, 1), x.load(.SeqCst));219 try testing.expectEqual(@as(usize, 1), x.load(.seq_cst));
220220
221 while (x.cmpxchgWeak(1, 0, .SeqCst, .SeqCst)) |_| {}221 while (x.cmpxchgWeak(1, 0, .seq_cst, .seq_cst)) |_| {}
222 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));222 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
223}223}
224224
225test "Value.cmpxchgStrong" {225test "Value.cmpxchgStrong" {
226 var x = Value(usize).init(0);226 var x = Value(usize).init(0);
227 try testing.expectEqual(@as(?usize, 0), x.cmpxchgStrong(1, 0, .SeqCst, .SeqCst));227 try testing.expectEqual(@as(?usize, 0), x.cmpxchgStrong(1, 0, .seq_cst, .seq_cst));
228 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));228 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
229 try testing.expectEqual(@as(?usize, null), x.cmpxchgStrong(0, 1, .SeqCst, .SeqCst));229 try testing.expectEqual(@as(?usize, null), x.cmpxchgStrong(0, 1, .seq_cst, .seq_cst));
230 try testing.expectEqual(@as(usize, 1), x.load(.SeqCst));230 try testing.expectEqual(@as(usize, 1), x.load(.seq_cst));
231 try testing.expectEqual(@as(?usize, null), x.cmpxchgStrong(1, 0, .SeqCst, .SeqCst));231 try testing.expectEqual(@as(?usize, null), x.cmpxchgStrong(1, 0, .seq_cst, .seq_cst));
232 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));232 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
233}233}
234234
235test "Value.fetchAdd" {235test "Value.fetchAdd" {
236 var x = Value(usize).init(5);236 var x = Value(usize).init(5);
237 try testing.expectEqual(@as(usize, 5), x.fetchAdd(5, .SeqCst));237 try testing.expectEqual(@as(usize, 5), x.fetchAdd(5, .seq_cst));
238 try testing.expectEqual(@as(usize, 10), x.load(.SeqCst));238 try testing.expectEqual(@as(usize, 10), x.load(.seq_cst));
239 try testing.expectEqual(@as(usize, 10), x.fetchAdd(std.math.maxInt(usize), .SeqCst));239 try testing.expectEqual(@as(usize, 10), x.fetchAdd(std.math.maxInt(usize), .seq_cst));
240 try testing.expectEqual(@as(usize, 9), x.load(.SeqCst));240 try testing.expectEqual(@as(usize, 9), x.load(.seq_cst));
241}241}
242242
243test "Value.fetchSub" {243test "Value.fetchSub" {
244 var x = Value(usize).init(5);244 var x = Value(usize).init(5);
245 try testing.expectEqual(@as(usize, 5), x.fetchSub(5, .SeqCst));245 try testing.expectEqual(@as(usize, 5), x.fetchSub(5, .seq_cst));
246 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));246 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
247 try testing.expectEqual(@as(usize, 0), x.fetchSub(1, .SeqCst));247 try testing.expectEqual(@as(usize, 0), x.fetchSub(1, .seq_cst));
248 try testing.expectEqual(@as(usize, std.math.maxInt(usize)), x.load(.SeqCst));248 try testing.expectEqual(@as(usize, std.math.maxInt(usize)), x.load(.seq_cst));
249}249}
250250
251test "Value.fetchMin" {251test "Value.fetchMin" {
252 var x = Value(usize).init(5);252 var x = Value(usize).init(5);
253 try testing.expectEqual(@as(usize, 5), x.fetchMin(0, .SeqCst));253 try testing.expectEqual(@as(usize, 5), x.fetchMin(0, .seq_cst));
254 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));254 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
255 try testing.expectEqual(@as(usize, 0), x.fetchMin(10, .SeqCst));255 try testing.expectEqual(@as(usize, 0), x.fetchMin(10, .seq_cst));
256 try testing.expectEqual(@as(usize, 0), x.load(.SeqCst));256 try testing.expectEqual(@as(usize, 0), x.load(.seq_cst));
257}257}
258258
259test "Value.fetchMax" {259test "Value.fetchMax" {
260 var x = Value(usize).init(5);260 var x = Value(usize).init(5);
261 try testing.expectEqual(@as(usize, 5), x.fetchMax(10, .SeqCst));261 try testing.expectEqual(@as(usize, 5), x.fetchMax(10, .seq_cst));
262 try testing.expectEqual(@as(usize, 10), x.load(.SeqCst));262 try testing.expectEqual(@as(usize, 10), x.load(.seq_cst));
263 try testing.expectEqual(@as(usize, 10), x.fetchMax(5, .SeqCst));263 try testing.expectEqual(@as(usize, 10), x.fetchMax(5, .seq_cst));
264 try testing.expectEqual(@as(usize, 10), x.load(.SeqCst));264 try testing.expectEqual(@as(usize, 10), x.load(.seq_cst));
265}265}
266266
267test "Value.fetchAnd" {267test "Value.fetchAnd" {
268 var x = Value(usize).init(0b11);268 var x = Value(usize).init(0b11);
269 try testing.expectEqual(@as(usize, 0b11), x.fetchAnd(0b10, .SeqCst));269 try testing.expectEqual(@as(usize, 0b11), x.fetchAnd(0b10, .seq_cst));
270 try testing.expectEqual(@as(usize, 0b10), x.load(.SeqCst));270 try testing.expectEqual(@as(usize, 0b10), x.load(.seq_cst));
271 try testing.expectEqual(@as(usize, 0b10), x.fetchAnd(0b00, .SeqCst));271 try testing.expectEqual(@as(usize, 0b10), x.fetchAnd(0b00, .seq_cst));
272 try testing.expectEqual(@as(usize, 0b00), x.load(.SeqCst));272 try testing.expectEqual(@as(usize, 0b00), x.load(.seq_cst));
273}273}
274274
275test "Value.fetchNand" {275test "Value.fetchNand" {
276 var x = Value(usize).init(0b11);276 var x = Value(usize).init(0b11);
277 try testing.expectEqual(@as(usize, 0b11), x.fetchNand(0b10, .SeqCst));277 try testing.expectEqual(@as(usize, 0b11), x.fetchNand(0b10, .seq_cst));
278 try testing.expectEqual(~@as(usize, 0b10), x.load(.SeqCst));278 try testing.expectEqual(~@as(usize, 0b10), x.load(.seq_cst));
279 try testing.expectEqual(~@as(usize, 0b10), x.fetchNand(0b00, .SeqCst));279 try testing.expectEqual(~@as(usize, 0b10), x.fetchNand(0b00, .seq_cst));
280 try testing.expectEqual(~@as(usize, 0b00), x.load(.SeqCst));280 try testing.expectEqual(~@as(usize, 0b00), x.load(.seq_cst));
281}281}
282282
283test "Value.fetchOr" {283test "Value.fetchOr" {
284 var x = Value(usize).init(0b11);284 var x = Value(usize).init(0b11);
285 try testing.expectEqual(@as(usize, 0b11), x.fetchOr(0b100, .SeqCst));285 try testing.expectEqual(@as(usize, 0b11), x.fetchOr(0b100, .seq_cst));
286 try testing.expectEqual(@as(usize, 0b111), x.load(.SeqCst));286 try testing.expectEqual(@as(usize, 0b111), x.load(.seq_cst));
287 try testing.expectEqual(@as(usize, 0b111), x.fetchOr(0b010, .SeqCst));287 try testing.expectEqual(@as(usize, 0b111), x.fetchOr(0b010, .seq_cst));
288 try testing.expectEqual(@as(usize, 0b111), x.load(.SeqCst));288 try testing.expectEqual(@as(usize, 0b111), x.load(.seq_cst));
289}289}
290290
291test "Value.fetchXor" {291test "Value.fetchXor" {
292 var x = Value(usize).init(0b11);292 var x = Value(usize).init(0b11);
293 try testing.expectEqual(@as(usize, 0b11), x.fetchXor(0b10, .SeqCst));293 try testing.expectEqual(@as(usize, 0b11), x.fetchXor(0b10, .seq_cst));
294 try testing.expectEqual(@as(usize, 0b01), x.load(.SeqCst));294 try testing.expectEqual(@as(usize, 0b01), x.load(.seq_cst));
295 try testing.expectEqual(@as(usize, 0b01), x.fetchXor(0b01, .SeqCst));295 try testing.expectEqual(@as(usize, 0b01), x.fetchXor(0b01, .seq_cst));
296 try testing.expectEqual(@as(usize, 0b00), x.load(.SeqCst));296 try testing.expectEqual(@as(usize, 0b00), x.load(.seq_cst));
297}297}
298298
299test "Value.bitSet" {299test "Value.bitSet" {
...@@ -304,19 +304,19 @@ test "Value.bitSet" {...@@ -304,19 +304,19 @@ test "Value.bitSet" {
304 const mask = @as(usize, 1) << bit;304 const mask = @as(usize, 1) << bit;
305305
306 // setting the bit should change the bit306 // setting the bit should change the bit
307 try testing.expect(x.load(.SeqCst) & mask == 0);307 try testing.expect(x.load(.seq_cst) & mask == 0);
308 try testing.expectEqual(@as(u1, 0), x.bitSet(bit, .SeqCst));308 try testing.expectEqual(@as(u1, 0), x.bitSet(bit, .seq_cst));
309 try testing.expect(x.load(.SeqCst) & mask != 0);309 try testing.expect(x.load(.seq_cst) & mask != 0);
310310
311 // setting it again shouldn't change the bit311 // setting it again shouldn't change the bit
312 try testing.expectEqual(@as(u1, 1), x.bitSet(bit, .SeqCst));312 try testing.expectEqual(@as(u1, 1), x.bitSet(bit, .seq_cst));
313 try testing.expect(x.load(.SeqCst) & mask != 0);313 try testing.expect(x.load(.seq_cst) & mask != 0);
314314
315 // all the previous bits should have not changed (still be set)315 // all the previous bits should have not changed (still be set)
316 for (0..bit_index) |prev_bit_index| {316 for (0..bit_index) |prev_bit_index| {
317 const prev_bit = @as(std.math.Log2Int(usize), @intCast(prev_bit_index));317 const prev_bit = @as(std.math.Log2Int(usize), @intCast(prev_bit_index));
318 const prev_mask = @as(usize, 1) << prev_bit;318 const prev_mask = @as(usize, 1) << prev_bit;
319 try testing.expect(x.load(.SeqCst) & prev_mask != 0);319 try testing.expect(x.load(.seq_cst) & prev_mask != 0);
320 }320 }
321 }321 }
322}322}
...@@ -330,19 +330,19 @@ test "Value.bitReset" {...@@ -330,19 +330,19 @@ test "Value.bitReset" {
330 x.raw |= mask;330 x.raw |= mask;
331331
332 // unsetting the bit should change the bit332 // unsetting the bit should change the bit
333 try testing.expect(x.load(.SeqCst) & mask != 0);333 try testing.expect(x.load(.seq_cst) & mask != 0);
334 try testing.expectEqual(@as(u1, 1), x.bitReset(bit, .SeqCst));334 try testing.expectEqual(@as(u1, 1), x.bitReset(bit, .seq_cst));
335 try testing.expect(x.load(.SeqCst) & mask == 0);335 try testing.expect(x.load(.seq_cst) & mask == 0);
336336
337 // unsetting it again shouldn't change the bit337 // unsetting it again shouldn't change the bit
338 try testing.expectEqual(@as(u1, 0), x.bitReset(bit, .SeqCst));338 try testing.expectEqual(@as(u1, 0), x.bitReset(bit, .seq_cst));
339 try testing.expect(x.load(.SeqCst) & mask == 0);339 try testing.expect(x.load(.seq_cst) & mask == 0);
340340
341 // all the previous bits should have not changed (still be reset)341 // all the previous bits should have not changed (still be reset)
342 for (0..bit_index) |prev_bit_index| {342 for (0..bit_index) |prev_bit_index| {
343 const prev_bit = @as(std.math.Log2Int(usize), @intCast(prev_bit_index));343 const prev_bit = @as(std.math.Log2Int(usize), @intCast(prev_bit_index));
344 const prev_mask = @as(usize, 1) << prev_bit;344 const prev_mask = @as(usize, 1) << prev_bit;
345 try testing.expect(x.load(.SeqCst) & prev_mask == 0);345 try testing.expect(x.load(.seq_cst) & prev_mask == 0);
346 }346 }
347 }347 }
348}348}
...@@ -355,19 +355,19 @@ test "Value.bitToggle" {...@@ -355,19 +355,19 @@ test "Value.bitToggle" {
355 const mask = @as(usize, 1) << bit;355 const mask = @as(usize, 1) << bit;
356356
357 // toggling the bit should change the bit357 // toggling the bit should change the bit
358 try testing.expect(x.load(.SeqCst) & mask == 0);358 try testing.expect(x.load(.seq_cst) & mask == 0);
359 try testing.expectEqual(@as(u1, 0), x.bitToggle(bit, .SeqCst));359 try testing.expectEqual(@as(u1, 0), x.bitToggle(bit, .seq_cst));
360 try testing.expect(x.load(.SeqCst) & mask != 0);360 try testing.expect(x.load(.seq_cst) & mask != 0);
361361
362 // toggling it again *should* change the bit362 // toggling it again *should* change the bit
363 try testing.expectEqual(@as(u1, 1), x.bitToggle(bit, .SeqCst));363 try testing.expectEqual(@as(u1, 1), x.bitToggle(bit, .seq_cst));
364 try testing.expect(x.load(.SeqCst) & mask == 0);364 try testing.expect(x.load(.seq_cst) & mask == 0);
365365
366 // all the previous bits should have not changed (still be toggled back)366 // all the previous bits should have not changed (still be toggled back)
367 for (0..bit_index) |prev_bit_index| {367 for (0..bit_index) |prev_bit_index| {
368 const prev_bit = @as(std.math.Log2Int(usize), @intCast(prev_bit_index));368 const prev_bit = @as(std.math.Log2Int(usize), @intCast(prev_bit_index));
369 const prev_mask = @as(usize, 1) << prev_bit;369 const prev_mask = @as(usize, 1) << prev_bit;
370 try testing.expect(x.load(.SeqCst) & prev_mask == 0);370 try testing.expect(x.load(.seq_cst) & prev_mask == 0);
371 }371 }
372 }372 }
373}373}
lib/std/builtin.zig+6-6
...@@ -81,12 +81,12 @@ pub const SymbolVisibility = enum {...@@ -81,12 +81,12 @@ pub const SymbolVisibility = enum {
81/// This data structure is used by the Zig language code generation and81/// This data structure is used by the Zig language code generation and
82/// therefore must be kept in sync with the compiler implementation.82/// therefore must be kept in sync with the compiler implementation.
83pub const AtomicOrder = enum {83pub const AtomicOrder = enum {
84 Unordered,84 unordered,
85 Monotonic,85 monotonic,
86 Acquire,86 acquire,
87 Release,87 release,
88 AcqRel,88 acq_rel,
89 SeqCst,89 seq_cst,
90};90};
9191
92/// This data structure is used by the Zig language code generation and92/// This data structure is used by the Zig language code generation and
lib/std/child_process.zig+1-1
...@@ -1420,7 +1420,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons...@@ -1420,7 +1420,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
1420 const pipe_path = std.fmt.bufPrintZ(1420 const pipe_path = std.fmt.bufPrintZ(
1421 &tmp_buf,1421 &tmp_buf,
1422 "\\\\.\\pipe\\zig-childprocess-{d}-{d}",1422 "\\\\.\\pipe\\zig-childprocess-{d}-{d}",
1423 .{ windows.kernel32.GetCurrentProcessId(), pipe_name_counter.fetchAdd(1, .Monotonic) },1423 .{ windows.kernel32.GetCurrentProcessId(), pipe_name_counter.fetchAdd(1, .monotonic) },
1424 ) catch unreachable;1424 ) catch unreachable;
1425 const len = std.unicode.wtf8ToWtf16Le(&tmp_bufw, pipe_path) catch unreachable;1425 const len = std.unicode.wtf8ToWtf16Le(&tmp_bufw, pipe_path) catch unreachable;
1426 tmp_bufw[len] = 0;1426 tmp_bufw[len] = 0;
lib/std/debug.zig+4-4
...@@ -461,7 +461,7 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize...@@ -461,7 +461,7 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
461 0 => {461 0 => {
462 panic_stage = 1;462 panic_stage = 1;
463463
464 _ = panicking.fetchAdd(1, .SeqCst);464 _ = panicking.fetchAdd(1, .seq_cst);
465465
466 // Make sure to release the mutex when done466 // Make sure to release the mutex when done
467 {467 {
...@@ -503,7 +503,7 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize...@@ -503,7 +503,7 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
503503
504/// Must be called only after adding 1 to `panicking`. There are three callsites.504/// Must be called only after adding 1 to `panicking`. There are three callsites.
505fn waitForOtherThreadToFinishPanicking() void {505fn waitForOtherThreadToFinishPanicking() void {
506 if (panicking.fetchSub(1, .SeqCst) != 1) {506 if (panicking.fetchSub(1, .seq_cst) != 1) {
507 // Another thread is panicking, wait for the last one to finish507 // Another thread is panicking, wait for the last one to finish
508 // and call abort()508 // and call abort()
509 if (builtin.single_threaded) unreachable;509 if (builtin.single_threaded) unreachable;
...@@ -2587,7 +2587,7 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any...@@ -2587,7 +2587,7 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
2587 nosuspend switch (panic_stage) {2587 nosuspend switch (panic_stage) {
2588 0 => {2588 0 => {
2589 panic_stage = 1;2589 panic_stage = 1;
2590 _ = panicking.fetchAdd(1, .SeqCst);2590 _ = panicking.fetchAdd(1, .seq_cst);
25912591
2592 {2592 {
2593 panic_mutex.lock();2593 panic_mutex.lock();
...@@ -2663,7 +2663,7 @@ fn handleSegfaultWindowsExtra(...@@ -2663,7 +2663,7 @@ fn handleSegfaultWindowsExtra(
2663 nosuspend switch (panic_stage) {2663 nosuspend switch (panic_stage) {
2664 0 => {2664 0 => {
2665 panic_stage = 1;2665 panic_stage = 1;
2666 _ = panicking.fetchAdd(1, .SeqCst);2666 _ = panicking.fetchAdd(1, .seq_cst);
26672667
2668 {2668 {
2669 panic_mutex.lock();2669 panic_mutex.lock();
lib/std/heap.zig+4-4
...@@ -303,11 +303,11 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -303,11 +303,11 @@ pub const HeapAllocator = switch (builtin.os.tag) {
303303
304 const ptr_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_ptr_align));304 const ptr_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_ptr_align));
305 const amt = n + ptr_align - 1 + @sizeOf(usize);305 const amt = n + ptr_align - 1 + @sizeOf(usize);
306 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .SeqCst);306 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .seq_cst);
307 const heap_handle = optional_heap_handle orelse blk: {307 const heap_handle = optional_heap_handle orelse blk: {
308 const options = if (builtin.single_threaded) os.windows.HEAP_NO_SERIALIZE else 0;308 const options = if (builtin.single_threaded) os.windows.HEAP_NO_SERIALIZE else 0;
309 const hh = os.windows.kernel32.HeapCreate(options, amt, 0) orelse return null;309 const hh = os.windows.kernel32.HeapCreate(options, amt, 0) orelse return null;
310 const other_hh = @cmpxchgStrong(?HeapHandle, &self.heap_handle, null, hh, .SeqCst, .SeqCst) orelse break :blk hh;310 const other_hh = @cmpxchgStrong(?HeapHandle, &self.heap_handle, null, hh, .seq_cst, .seq_cst) orelse break :blk hh;
311 os.windows.HeapDestroy(hh);311 os.windows.HeapDestroy(hh);
312 break :blk other_hh.?; // can't be null because of the cmpxchg312 break :blk other_hh.?; // can't be null because of the cmpxchg
313 };313 };
...@@ -482,13 +482,13 @@ pub const FixedBufferAllocator = struct {...@@ -482,13 +482,13 @@ pub const FixedBufferAllocator = struct {
482 const self: *FixedBufferAllocator = @ptrCast(@alignCast(ctx));482 const self: *FixedBufferAllocator = @ptrCast(@alignCast(ctx));
483 _ = ra;483 _ = ra;
484 const ptr_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_ptr_align));484 const ptr_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_ptr_align));
485 var end_index = @atomicLoad(usize, &self.end_index, .SeqCst);485 var end_index = @atomicLoad(usize, &self.end_index, .seq_cst);
486 while (true) {486 while (true) {
487 const adjust_off = mem.alignPointerOffset(self.buffer.ptr + end_index, ptr_align) orelse return null;487 const adjust_off = mem.alignPointerOffset(self.buffer.ptr + end_index, ptr_align) orelse return null;
488 const adjusted_index = end_index + adjust_off;488 const adjusted_index = end_index + adjust_off;
489 const new_end_index = adjusted_index + n;489 const new_end_index = adjusted_index + n;
490 if (new_end_index > self.buffer.len) return null;490 if (new_end_index > self.buffer.len) return null;
491 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, .SeqCst, .SeqCst) orelse491 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, .seq_cst, .seq_cst) orelse
492 return self.buffer[adjusted_index..new_end_index].ptr;492 return self.buffer[adjusted_index..new_end_index].ptr;
493 }493 }
494 }494 }
lib/std/heap/PageAllocator.zig+2-2
...@@ -30,7 +30,7 @@ fn alloc(_: *anyopaque, n: usize, log2_align: u8, ra: usize) ?[*]u8 {...@@ -30,7 +30,7 @@ fn alloc(_: *anyopaque, n: usize, log2_align: u8, ra: usize) ?[*]u8 {
30 return @ptrCast(addr);30 return @ptrCast(addr);
31 }31 }
3232
33 const hint = @atomicLoad(@TypeOf(std.heap.next_mmap_addr_hint), &std.heap.next_mmap_addr_hint, .Unordered);33 const hint = @atomicLoad(@TypeOf(std.heap.next_mmap_addr_hint), &std.heap.next_mmap_addr_hint, .unordered);
34 const slice = os.mmap(34 const slice = os.mmap(
35 hint,35 hint,
36 aligned_len,36 aligned_len,
...@@ -41,7 +41,7 @@ fn alloc(_: *anyopaque, n: usize, log2_align: u8, ra: usize) ?[*]u8 {...@@ -41,7 +41,7 @@ fn alloc(_: *anyopaque, n: usize, log2_align: u8, ra: usize) ?[*]u8 {
41 ) catch return null;41 ) catch return null;
42 assert(mem.isAligned(@intFromPtr(slice.ptr), mem.page_size));42 assert(mem.isAligned(@intFromPtr(slice.ptr), mem.page_size));
43 const new_hint: [*]align(mem.page_size) u8 = @alignCast(slice.ptr + aligned_len);43 const new_hint: [*]align(mem.page_size) u8 = @alignCast(slice.ptr + aligned_len);
44 _ = @cmpxchgStrong(@TypeOf(std.heap.next_mmap_addr_hint), &std.heap.next_mmap_addr_hint, hint, new_hint, .Monotonic, .Monotonic);44 _ = @cmpxchgStrong(@TypeOf(std.heap.next_mmap_addr_hint), &std.heap.next_mmap_addr_hint, hint, new_hint, .monotonic, .monotonic);
45 return slice.ptr;45 return slice.ptr;
46}46}
4747
lib/std/http/Client.zig+2-2
...@@ -1642,7 +1642,7 @@ pub fn open(...@@ -1642,7 +1642,7 @@ pub fn open(
16421642
1643 const host = uri.host orelse return error.UriMissingHost;1643 const host = uri.host orelse return error.UriMissingHost;
16441644
1645 if (protocol == .tls and @atomicLoad(bool, &client.next_https_rescan_certs, .Acquire)) {1645 if (protocol == .tls and @atomicLoad(bool, &client.next_https_rescan_certs, .acquire)) {
1646 if (disable_tls) unreachable;1646 if (disable_tls) unreachable;
16471647
1648 client.ca_bundle_mutex.lock();1648 client.ca_bundle_mutex.lock();
...@@ -1650,7 +1650,7 @@ pub fn open(...@@ -1650,7 +1650,7 @@ pub fn open(
16501650
1651 if (client.next_https_rescan_certs) {1651 if (client.next_https_rescan_certs) {
1652 client.ca_bundle.rescan(client.allocator) catch return error.CertificateBundleLoadFailure;1652 client.ca_bundle.rescan(client.allocator) catch return error.CertificateBundleLoadFailure;
1653 @atomicStore(bool, &client.next_https_rescan_certs, false, .Release);1653 @atomicStore(bool, &client.next_https_rescan_certs, false, .release);
1654 }1654 }
1655 }1655 }
16561656
lib/std/once.zig+2-2
...@@ -17,7 +17,7 @@ pub fn Once(comptime f: fn () void) type {...@@ -17,7 +17,7 @@ pub fn Once(comptime f: fn () void) type {
17 /// first time.17 /// first time.
18 /// The invocations are thread-safe.18 /// The invocations are thread-safe.
19 pub fn call(self: *@This()) void {19 pub fn call(self: *@This()) void {
20 if (@atomicLoad(bool, &self.done, .Acquire))20 if (@atomicLoad(bool, &self.done, .acquire))
21 return;21 return;
2222
23 return self.callSlow();23 return self.callSlow();
...@@ -32,7 +32,7 @@ pub fn Once(comptime f: fn () void) type {...@@ -32,7 +32,7 @@ pub fn Once(comptime f: fn () void) type {
32 // The first thread to acquire the mutex gets to run the initializer32 // The first thread to acquire the mutex gets to run the initializer
33 if (!self.done) {33 if (!self.done) {
34 f();34 f();
35 @atomicStore(bool, &self.done, true, .Release);35 @atomicStore(bool, &self.done, true, .release);
36 }36 }
37 }37 }
38 };38 };
lib/std/os.zig+5-5
...@@ -436,7 +436,7 @@ fn fchmodat1(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr...@@ -436,7 +436,7 @@ fn fchmodat1(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
436fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {436fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtError!void {
437 const path_c = try toPosixPath(path);437 const path_c = try toPosixPath(path);
438 const use_fchmodat2 = (builtin.os.isAtLeast(.linux, .{ .major = 6, .minor = 6, .patch = 0 }) orelse false) and438 const use_fchmodat2 = (builtin.os.isAtLeast(.linux, .{ .major = 6, .minor = 6, .patch = 0 }) orelse false) and
439 has_fchmodat2_syscall.load(.Monotonic);439 has_fchmodat2_syscall.load(.monotonic);
440 while (use_fchmodat2) {440 while (use_fchmodat2) {
441 // Later on this should be changed to `system.fchmodat2`441 // Later on this should be changed to `system.fchmodat2`
442 // when the musl/glibc add a wrapper.442 // when the musl/glibc add a wrapper.
...@@ -458,7 +458,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr...@@ -458,7 +458,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
458 .ROFS => return error.ReadOnlyFileSystem,458 .ROFS => return error.ReadOnlyFileSystem,
459459
460 .NOSYS => { // Use fallback.460 .NOSYS => { // Use fallback.
461 has_fchmodat2_syscall.store(false, .Monotonic);461 has_fchmodat2_syscall.store(false, .monotonic);
462 break;462 break;
463 },463 },
464 else => |err| return unexpectedErrno(err),464 else => |err| return unexpectedErrno(err),
...@@ -729,7 +729,7 @@ pub fn abort() noreturn {...@@ -729,7 +729,7 @@ pub fn abort() noreturn {
729 const global = struct {729 const global = struct {
730 var abort_entered: bool = false;730 var abort_entered: bool = false;
731 };731 };
732 while (@cmpxchgWeak(bool, &global.abort_entered, false, true, .SeqCst, .SeqCst)) |_| {}732 while (@cmpxchgWeak(bool, &global.abort_entered, false, true, .seq_cst, .seq_cst)) |_| {}
733 }733 }
734734
735 // Install default handler so that the tkill below will terminate.735 // Install default handler so that the tkill below will terminate.
...@@ -6809,7 +6809,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -6809,7 +6809,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
6809 if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or6809 if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or
6810 ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and6810 ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and
6811 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and6811 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and
6812 has_copy_file_range_syscall.load(.Monotonic)))6812 has_copy_file_range_syscall.load(.monotonic)))
6813 {6813 {
6814 var off_in_copy: i64 = @bitCast(off_in);6814 var off_in_copy: i64 = @bitCast(off_in);
6815 var off_out_copy: i64 = @bitCast(off_out);6815 var off_out_copy: i64 = @bitCast(off_out);
...@@ -6844,7 +6844,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -6844,7 +6844,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
6844 .TXTBSY => return error.SwapFile,6844 .TXTBSY => return error.SwapFile,
6845 .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback6845 .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback
6846 .NOSYS => { // syscall added in Linux 4.5, use fallback6846 .NOSYS => { // syscall added in Linux 4.5, use fallback
6847 has_copy_file_range_syscall.store(false, .Monotonic);6847 has_copy_file_range_syscall.store(false, .monotonic);
6848 break;6848 break;
6849 },6849 },
6850 else => |err| return unexpectedErrno(err),6850 else => |err| return unexpectedErrno(err),
lib/std/os/linux.zig+2-2
...@@ -1334,7 +1334,7 @@ const vdso_clock_gettime_ty = *align(1) const fn (i32, *timespec) callconv(.C) u...@@ -1334,7 +1334,7 @@ const vdso_clock_gettime_ty = *align(1) const fn (i32, *timespec) callconv(.C) u
13341334
1335pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {1335pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
1336 if (@hasDecl(VDSO, "CGT_SYM")) {1336 if (@hasDecl(VDSO, "CGT_SYM")) {
1337 const ptr = @atomicLoad(?*const anyopaque, &vdso_clock_gettime, .Unordered);1337 const ptr = @atomicLoad(?*const anyopaque, &vdso_clock_gettime, .unordered);
1338 if (ptr) |fn_ptr| {1338 if (ptr) |fn_ptr| {
1339 const f = @as(vdso_clock_gettime_ty, @ptrCast(fn_ptr));1339 const f = @as(vdso_clock_gettime_ty, @ptrCast(fn_ptr));
1340 const rc = f(clk_id, tp);1340 const rc = f(clk_id, tp);
...@@ -1351,7 +1351,7 @@ fn init_vdso_clock_gettime(clk: i32, ts: *timespec) callconv(.C) usize {...@@ -1351,7 +1351,7 @@ fn init_vdso_clock_gettime(clk: i32, ts: *timespec) callconv(.C) usize {
1351 const ptr = @as(?*const anyopaque, @ptrFromInt(vdso.lookup(VDSO.CGT_VER, VDSO.CGT_SYM)));1351 const ptr = @as(?*const anyopaque, @ptrFromInt(vdso.lookup(VDSO.CGT_VER, VDSO.CGT_SYM)));
1352 // Note that we may not have a VDSO at all, update the stub address anyway1352 // Note that we may not have a VDSO at all, update the stub address anyway
1353 // so that clock_gettime will fall back on the good old (and slow) syscall1353 // so that clock_gettime will fall back on the good old (and slow) syscall
1354 @atomicStore(?*const anyopaque, &vdso_clock_gettime, ptr, .Monotonic);1354 @atomicStore(?*const anyopaque, &vdso_clock_gettime, ptr, .monotonic);
1355 // Call into the VDSO if available1355 // Call into the VDSO if available
1356 if (ptr) |fn_ptr| {1356 if (ptr) |fn_ptr| {
1357 const f = @as(vdso_clock_gettime_ty, @ptrCast(fn_ptr));1357 const f = @as(vdso_clock_gettime_ty, @ptrCast(fn_ptr));
lib/std/os/linux/IoUring.zig+7-7
...@@ -133,7 +133,7 @@ pub fn deinit(self: *IoUring) void {...@@ -133,7 +133,7 @@ pub fn deinit(self: *IoUring) void {
133/// alternative. In Zig, we have first-class error handling... so let's use it.133/// alternative. In Zig, we have first-class error handling... so let's use it.
134/// Matches the implementation of io_uring_get_sqe() in liburing.134/// Matches the implementation of io_uring_get_sqe() in liburing.
135pub fn get_sqe(self: *IoUring) !*linux.io_uring_sqe {135pub fn get_sqe(self: *IoUring) !*linux.io_uring_sqe {
136 const head = @atomicLoad(u32, self.sq.head, .Acquire);136 const head = @atomicLoad(u32, self.sq.head, .acquire);
137 // Remember that these head and tail offsets wrap around every four billion operations.137 // Remember that these head and tail offsets wrap around every four billion operations.
138 // We must therefore use wrapping addition and subtraction to avoid a runtime crash.138 // We must therefore use wrapping addition and subtraction to avoid a runtime crash.
139 const next = self.sq.sqe_tail +% 1;139 const next = self.sq.sqe_tail +% 1;
...@@ -222,7 +222,7 @@ pub fn flush_sq(self: *IoUring) u32 {...@@ -222,7 +222,7 @@ pub fn flush_sq(self: *IoUring) u32 {
222 self.sq.sqe_head +%= 1;222 self.sq.sqe_head +%= 1;
223 }223 }
224 // Ensure that the kernel can actually see the SQE updates when it sees the tail update.224 // Ensure that the kernel can actually see the SQE updates when it sees the tail update.
225 @atomicStore(u32, self.sq.tail, tail, .Release);225 @atomicStore(u32, self.sq.tail, tail, .release);
226 }226 }
227 return self.sq_ready();227 return self.sq_ready();
228}228}
...@@ -234,7 +234,7 @@ pub fn flush_sq(self: *IoUring) u32 {...@@ -234,7 +234,7 @@ pub fn flush_sq(self: *IoUring) u32 {
234pub fn sq_ring_needs_enter(self: *IoUring, flags: *u32) bool {234pub fn sq_ring_needs_enter(self: *IoUring, flags: *u32) bool {
235 assert(flags.* == 0);235 assert(flags.* == 0);
236 if ((self.flags & linux.IORING_SETUP_SQPOLL) == 0) return true;236 if ((self.flags & linux.IORING_SETUP_SQPOLL) == 0) return true;
237 if ((@atomicLoad(u32, self.sq.flags, .Unordered) & linux.IORING_SQ_NEED_WAKEUP) != 0) {237 if ((@atomicLoad(u32, self.sq.flags, .unordered) & linux.IORING_SQ_NEED_WAKEUP) != 0) {
238 flags.* |= linux.IORING_ENTER_SQ_WAKEUP;238 flags.* |= linux.IORING_ENTER_SQ_WAKEUP;
239 return true;239 return true;
240 }240 }
...@@ -248,14 +248,14 @@ pub fn sq_ring_needs_enter(self: *IoUring, flags: *u32) bool {...@@ -248,14 +248,14 @@ pub fn sq_ring_needs_enter(self: *IoUring, flags: *u32) bool {
248pub fn sq_ready(self: *IoUring) u32 {248pub fn sq_ready(self: *IoUring) u32 {
249 // Always use the shared ring state (i.e. head and not sqe_head) to avoid going out of sync,249 // Always use the shared ring state (i.e. head and not sqe_head) to avoid going out of sync,
250 // see https://github.com/axboe/liburing/issues/92.250 // see https://github.com/axboe/liburing/issues/92.
251 return self.sq.sqe_tail -% @atomicLoad(u32, self.sq.head, .Acquire);251 return self.sq.sqe_tail -% @atomicLoad(u32, self.sq.head, .acquire);
252}252}
253253
254/// Returns the number of CQEs in the completion queue, i.e. its length.254/// Returns the number of CQEs in the completion queue, i.e. its length.
255/// These are CQEs that the application is yet to consume.255/// These are CQEs that the application is yet to consume.
256/// Matches the implementation of io_uring_cq_ready in liburing.256/// Matches the implementation of io_uring_cq_ready in liburing.
257pub fn cq_ready(self: *IoUring) u32 {257pub fn cq_ready(self: *IoUring) u32 {
258 return @atomicLoad(u32, self.cq.tail, .Acquire) -% self.cq.head.*;258 return @atomicLoad(u32, self.cq.tail, .acquire) -% self.cq.head.*;
259}259}
260260
261/// Copies as many CQEs as are ready, and that can fit into the destination `cqes` slice.261/// Copies as many CQEs as are ready, and that can fit into the destination `cqes` slice.
...@@ -313,7 +313,7 @@ pub fn copy_cqe(ring: *IoUring) !linux.io_uring_cqe {...@@ -313,7 +313,7 @@ pub fn copy_cqe(ring: *IoUring) !linux.io_uring_cqe {
313313
314/// Matches the implementation of cq_ring_needs_flush() in liburing.314/// Matches the implementation of cq_ring_needs_flush() in liburing.
315pub fn cq_ring_needs_flush(self: *IoUring) bool {315pub fn cq_ring_needs_flush(self: *IoUring) bool {
316 return (@atomicLoad(u32, self.sq.flags, .Unordered) & linux.IORING_SQ_CQ_OVERFLOW) != 0;316 return (@atomicLoad(u32, self.sq.flags, .unordered) & linux.IORING_SQ_CQ_OVERFLOW) != 0;
317}317}
318318
319/// For advanced use cases only that implement custom completion queue methods.319/// For advanced use cases only that implement custom completion queue methods.
...@@ -331,7 +331,7 @@ pub fn cqe_seen(self: *IoUring, cqe: *linux.io_uring_cqe) void {...@@ -331,7 +331,7 @@ pub fn cqe_seen(self: *IoUring, cqe: *linux.io_uring_cqe) void {
331pub fn cq_advance(self: *IoUring, count: u32) void {331pub fn cq_advance(self: *IoUring, count: u32) void {
332 if (count > 0) {332 if (count > 0) {
333 // Ensure the kernel only sees the new head value after the CQEs have been read.333 // Ensure the kernel only sees the new head value after the CQEs have been read.
334 @atomicStore(u32, self.cq.head, self.cq.head.* +% count, .Release);334 @atomicStore(u32, self.cq.head, self.cq.head.* +% count, .release);
335 }335 }
336}336}
337337
lib/std/os/test.zig+1-1
...@@ -425,7 +425,7 @@ fn start1() u8 {...@@ -425,7 +425,7 @@ fn start1() u8 {
425}425}
426426
427fn start2(ctx: *i32) u8 {427fn start2(ctx: *i32) u8 {
428 _ = @atomicRmw(i32, ctx, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);428 _ = @atomicRmw(i32, ctx, AtomicRmwOp.Add, 1, AtomicOrder.seq_cst);
429 return 0;429 return 0;
430}430}
431431
src/Sema.zig+18-18
...@@ -6450,8 +6450,8 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co...@@ -6450,8 +6450,8 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co
6450 .needed_comptime_reason = "atomic order of @fence must be comptime-known",6450 .needed_comptime_reason = "atomic order of @fence must be comptime-known",
6451 });6451 });
64526452
6453 if (@intFromEnum(order) < @intFromEnum(std.builtin.AtomicOrder.Acquire)) {6453 if (@intFromEnum(order) < @intFromEnum(std.builtin.AtomicOrder.acquire)) {
6454 return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{});6454 return sema.fail(block, order_src, "atomic ordering must be acquire or stricter", .{});
6455 }6455 }
64566456
6457 _ = try block.addInst(.{6457 _ = try block.addInst(.{
...@@ -23894,17 +23894,17 @@ fn zirCmpxchg(...@@ -23894,17 +23894,17 @@ fn zirCmpxchg(
23894 .needed_comptime_reason = "atomic order of cmpxchg failure must be comptime-known",23894 .needed_comptime_reason = "atomic order of cmpxchg failure must be comptime-known",
23895 });23895 });
2389623896
23897 if (@intFromEnum(success_order) < @intFromEnum(std.builtin.AtomicOrder.Monotonic)) {23897 if (@intFromEnum(success_order) < @intFromEnum(std.builtin.AtomicOrder.monotonic)) {
23898 return sema.fail(block, success_order_src, "success atomic ordering must be Monotonic or stricter", .{});23898 return sema.fail(block, success_order_src, "success atomic ordering must be monotonic or stricter", .{});
23899 }23899 }
23900 if (@intFromEnum(failure_order) < @intFromEnum(std.builtin.AtomicOrder.Monotonic)) {23900 if (@intFromEnum(failure_order) < @intFromEnum(std.builtin.AtomicOrder.monotonic)) {
23901 return sema.fail(block, failure_order_src, "failure atomic ordering must be Monotonic or stricter", .{});23901 return sema.fail(block, failure_order_src, "failure atomic ordering must be monotonic or stricter", .{});
23902 }23902 }
23903 if (@intFromEnum(failure_order) > @intFromEnum(success_order)) {23903 if (@intFromEnum(failure_order) > @intFromEnum(success_order)) {
23904 return sema.fail(block, failure_order_src, "failure atomic ordering must be no stricter than success", .{});23904 return sema.fail(block, failure_order_src, "failure atomic ordering must be no stricter than success", .{});
23905 }23905 }
23906 if (failure_order == .Release or failure_order == .AcqRel) {23906 if (failure_order == .release or failure_order == .acq_rel) {
23907 return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{});23907 return sema.fail(block, failure_order_src, "failure atomic ordering must not be release or acq_rel", .{});
23908 }23908 }
2390923909
23910 const result_ty = try mod.optionalType(elem_ty.toIntern());23910 const result_ty = try mod.optionalType(elem_ty.toIntern());
...@@ -24346,11 +24346,11 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -24346,11 +24346,11 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
24346 });24346 });
2434724347
24348 switch (order) {24348 switch (order) {
24349 .Release, .AcqRel => {24349 .release, .acq_rel => {
24350 return sema.fail(24350 return sema.fail(
24351 block,24351 block,
24352 order_src,24352 order_src,
24353 "@atomicLoad atomic ordering must not be Release or AcqRel",24353 "@atomicLoad atomic ordering must not be release or acq_rel",
24354 .{},24354 .{},
24355 );24355 );
24356 },24356 },
...@@ -24412,8 +24412,8 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -24412,8 +24412,8 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
24412 .needed_comptime_reason = "atomic order of @atomicRmW must be comptime-known",24412 .needed_comptime_reason = "atomic order of @atomicRmW must be comptime-known",
24413 });24413 });
2441424414
24415 if (order == .Unordered) {24415 if (order == .unordered) {
24416 return sema.fail(block, order_src, "@atomicRmw atomic ordering must not be Unordered", .{});24416 return sema.fail(block, order_src, "@atomicRmw atomic ordering must not be unordered", .{});
24417 }24417 }
2441824418
24419 // special case zero bit types24419 // special case zero bit types
...@@ -24482,18 +24482,18 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24482,18 +24482,18 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24482 });24482 });
2448324483
24484 const air_tag: Air.Inst.Tag = switch (order) {24484 const air_tag: Air.Inst.Tag = switch (order) {
24485 .Acquire, .AcqRel => {24485 .acquire, .acq_rel => {
24486 return sema.fail(24486 return sema.fail(
24487 block,24487 block,
24488 order_src,24488 order_src,
24489 "@atomicStore atomic ordering must not be Acquire or AcqRel",24489 "@atomicStore atomic ordering must not be acquire or acq_rel",
24490 .{},24490 .{},
24491 );24491 );
24492 },24492 },
24493 .Unordered => .atomic_store_unordered,24493 .unordered => .atomic_store_unordered,
24494 .Monotonic => .atomic_store_monotonic,24494 .monotonic => .atomic_store_monotonic,
24495 .Release => .atomic_store_release,24495 .release => .atomic_store_release,
24496 .SeqCst => .atomic_store_seq_cst,24496 .seq_cst => .atomic_store_seq_cst,
24497 };24497 };
2449824498
24499 return sema.storePtr2(block, src, ptr, ptr_src, operand, operand_src, air_tag);24499 return sema.storePtr2(block, src, ptr, ptr_src, operand, operand_src, air_tag);
src/arch/aarch64/CodeGen.zig+4-4
...@@ -815,10 +815,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -815,10 +815,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
815 .call_never_tail => try self.airCall(inst, .never_tail),815 .call_never_tail => try self.airCall(inst, .never_tail),
816 .call_never_inline => try self.airCall(inst, .never_inline),816 .call_never_inline => try self.airCall(inst, .never_inline),
817817
818 .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),818 .atomic_store_unordered => try self.airAtomicStore(inst, .unordered),
819 .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),819 .atomic_store_monotonic => try self.airAtomicStore(inst, .monotonic),
820 .atomic_store_release => try self.airAtomicStore(inst, .Release),820 .atomic_store_release => try self.airAtomicStore(inst, .release),
821 .atomic_store_seq_cst => try self.airAtomicStore(inst, .SeqCst),821 .atomic_store_seq_cst => try self.airAtomicStore(inst, .seq_cst),
822822
823 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),823 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
824 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),824 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
src/arch/arm/CodeGen.zig+4-4
...@@ -801,10 +801,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -801,10 +801,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
801 .call_never_tail => try self.airCall(inst, .never_tail),801 .call_never_tail => try self.airCall(inst, .never_tail),
802 .call_never_inline => try self.airCall(inst, .never_inline),802 .call_never_inline => try self.airCall(inst, .never_inline),
803803
804 .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),804 .atomic_store_unordered => try self.airAtomicStore(inst, .unordered),
805 .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),805 .atomic_store_monotonic => try self.airAtomicStore(inst, .monotonic),
806 .atomic_store_release => try self.airAtomicStore(inst, .Release),806 .atomic_store_release => try self.airAtomicStore(inst, .release),
807 .atomic_store_seq_cst => try self.airAtomicStore(inst, .SeqCst),807 .atomic_store_seq_cst => try self.airAtomicStore(inst, .seq_cst),
808808
809 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),809 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
810 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),810 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
src/arch/riscv64/CodeGen.zig+4-4
...@@ -634,10 +634,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -634,10 +634,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
634 .call_never_tail => try self.airCall(inst, .never_tail),634 .call_never_tail => try self.airCall(inst, .never_tail),
635 .call_never_inline => try self.airCall(inst, .never_inline),635 .call_never_inline => try self.airCall(inst, .never_inline),
636636
637 .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),637 .atomic_store_unordered => try self.airAtomicStore(inst, .unordered),
638 .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),638 .atomic_store_monotonic => try self.airAtomicStore(inst, .monotonic),
639 .atomic_store_release => try self.airAtomicStore(inst, .Release),639 .atomic_store_release => try self.airAtomicStore(inst, .release),
640 .atomic_store_seq_cst => try self.airAtomicStore(inst, .SeqCst),640 .atomic_store_seq_cst => try self.airAtomicStore(inst, .seq_cst),
641641
642 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),642 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
643 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),643 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
src/arch/x86_64/CodeGen.zig+10-10
...@@ -2111,10 +2111,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -2111,10 +2111,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2111 .call_never_tail => try self.airCall(inst, .never_tail),2111 .call_never_tail => try self.airCall(inst, .never_tail),
2112 .call_never_inline => try self.airCall(inst, .never_inline),2112 .call_never_inline => try self.airCall(inst, .never_inline),
21132113
2114 .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),2114 .atomic_store_unordered => try self.airAtomicStore(inst, .unordered),
2115 .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),2115 .atomic_store_monotonic => try self.airAtomicStore(inst, .monotonic),
2116 .atomic_store_release => try self.airAtomicStore(inst, .Release),2116 .atomic_store_release => try self.airAtomicStore(inst, .release),
2117 .atomic_store_seq_cst => try self.airAtomicStore(inst, .SeqCst),2117 .atomic_store_seq_cst => try self.airAtomicStore(inst, .seq_cst),
21182118
2119 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),2119 .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
2120 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),2120 .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
...@@ -11977,9 +11977,9 @@ fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {...@@ -11977,9 +11977,9 @@ fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
11977fn airFence(self: *Self, inst: Air.Inst.Index) !void {11977fn airFence(self: *Self, inst: Air.Inst.Index) !void {
11978 const order = self.air.instructions.items(.data)[@intFromEnum(inst)].fence;11978 const order = self.air.instructions.items(.data)[@intFromEnum(inst)].fence;
11979 switch (order) {11979 switch (order) {
11980 .Unordered, .Monotonic => unreachable,11980 .unordered, .monotonic => unreachable,
11981 .Acquire, .Release, .AcqRel => {},11981 .acquire, .release, .acq_rel => {},
11982 .SeqCst => try self.asmOpOnly(.{ ._, .mfence }),11982 .seq_cst => try self.asmOpOnly(.{ ._, .mfence }),
11983 }11983 }
11984 self.finishAirBookkeeping();11984 self.finishAirBookkeeping();
11985}11985}
...@@ -15747,9 +15747,9 @@ fn atomicOp(...@@ -15747,9 +15747,9 @@ fn atomicOp(
15747 .Xor => .xor,15747 .Xor => .xor,
15748 else => unreachable,15748 else => unreachable,
15749 } else switch (order) {15749 } else switch (order) {
15750 .Unordered, .Monotonic, .Release, .AcqRel => .mov,15750 .unordered, .monotonic, .release, .acq_rel => .mov,
15751 .Acquire => unreachable,15751 .acquire => unreachable,
15752 .SeqCst => .xchg,15752 .seq_cst => .xchg,
15753 };15753 };
1575415754
15755 const dst_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);15755 const dst_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
src/codegen/c.zig+9-9
...@@ -3278,10 +3278,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -3278,10 +3278,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
32783278
3279 .int_from_ptr => try airIntFromPtr(f, inst),3279 .int_from_ptr => try airIntFromPtr(f, inst),
32803280
3281 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),3281 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.unordered)),
3282 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),3282 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.monotonic)),
3283 .atomic_store_release => try airAtomicStore(f, inst, toMemoryOrder(.Release)),3283 .atomic_store_release => try airAtomicStore(f, inst, toMemoryOrder(.release)),
3284 .atomic_store_seq_cst => try airAtomicStore(f, inst, toMemoryOrder(.SeqCst)),3284 .atomic_store_seq_cst => try airAtomicStore(f, inst, toMemoryOrder(.seq_cst)),
32853285
3286 .struct_field_ptr_index_0 => try airStructFieldPtrIndex(f, inst, 0),3286 .struct_field_ptr_index_0 => try airStructFieldPtrIndex(f, inst, 0),
3287 .struct_field_ptr_index_1 => try airStructFieldPtrIndex(f, inst, 1),3287 .struct_field_ptr_index_1 => try airStructFieldPtrIndex(f, inst, 1),
...@@ -7482,11 +7482,11 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7482,11 +7482,11 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
7482fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {7482fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
7483 return switch (order) {7483 return switch (order) {
7484 // Note: unordered is actually even less atomic than relaxed7484 // Note: unordered is actually even less atomic than relaxed
7485 .Unordered, .Monotonic => "zig_memory_order_relaxed",7485 .unordered, .monotonic => "zig_memory_order_relaxed",
7486 .Acquire => "zig_memory_order_acquire",7486 .acquire => "zig_memory_order_acquire",
7487 .Release => "zig_memory_order_release",7487 .release => "zig_memory_order_release",
7488 .AcqRel => "zig_memory_order_acq_rel",7488 .acq_rel => "zig_memory_order_acq_rel",
7489 .SeqCst => "zig_memory_order_seq_cst",7489 .seq_cst => "zig_memory_order_seq_cst",
7490 };7490 };
7491}7491}
74927492
src/codegen/llvm.zig+7-7
...@@ -1278,7 +1278,7 @@ pub const Object = struct {...@@ -1278,7 +1278,7 @@ pub const Object = struct {
12781278
1279 const reloc_mode: llvm.RelocMode = if (pic)1279 const reloc_mode: llvm.RelocMode = if (pic)
1280 .PIC1280 .PIC
1281 else if (self.module.comp.config.link_mode == .Dynamic)1281 else if (self.module.comp.config.link_mode == .dynamic)
1282 llvm.RelocMode.DynamicNoPIC1282 llvm.RelocMode.DynamicNoPIC
1283 else1283 else
1284 .Static;1284 .Static;
...@@ -10801,12 +10801,12 @@ pub const FuncGen = struct {...@@ -10801,12 +10801,12 @@ pub const FuncGen = struct {
1080110801
10802fn toLlvmAtomicOrdering(atomic_order: std.builtin.AtomicOrder) Builder.AtomicOrdering {10802fn toLlvmAtomicOrdering(atomic_order: std.builtin.AtomicOrder) Builder.AtomicOrdering {
10803 return switch (atomic_order) {10803 return switch (atomic_order) {
10804 .Unordered => .unordered,10804 .unordered => .unordered,
10805 .Monotonic => .monotonic,10805 .monotonic => .monotonic,
10806 .Acquire => .acquire,10806 .acquire => .acquire,
10807 .Release => .release,10807 .release => .release,
10808 .AcqRel => .acq_rel,10808 .acq_rel => .acq_rel,
10809 .SeqCst => .seq_cst,10809 .seq_cst => .seq_cst,
10810 };10810 };
10811}10811}
1081210812
src/codegen/llvm/Builder.zig+1-1
...@@ -8398,7 +8398,7 @@ pub const Metadata = enum(u32) {...@@ -8398,7 +8398,7 @@ pub const Metadata = enum(u32) {
8398 fmt_str = fmt_str ++ ")\n";8398 fmt_str = fmt_str ++ ")\n";
83998399
8400 var fmt_args: @Type(.{ .Struct = .{8400 var fmt_args: @Type(.{ .Struct = .{
8401 .layout = .Auto,8401 .layout = .auto,
8402 .fields = &fields,8402 .fields = &fields,
8403 .decls = &.{},8403 .decls = &.{},
8404 .is_tuple = false,8404 .is_tuple = false,
src/codegen/llvm/bitcode_writer.zig+2-2
...@@ -415,8 +415,8 @@ fn BufType(comptime T: type, comptime min_len: usize) type {...@@ -415,8 +415,8 @@ fn BufType(comptime T: type, comptime min_len: usize) type {
415 .Enum => |info| info.tag_type,415 .Enum => |info| info.tag_type,
416 .Bool => u1,416 .Bool => u1,
417 .Struct => |info| switch (info.layout) {417 .Struct => |info| switch (info.layout) {
418 .Auto, .Extern => @compileError("Unsupported type: " ++ @typeName(T)),418 .auto, .@"extern" => @compileError("Unsupported type: " ++ @typeName(T)),
419 .Packed => std.meta.Int(.unsigned, @bitSizeOf(T)),419 .@"packed" => std.meta.Int(.unsigned, @bitSizeOf(T)),
420 },420 },
421 else => @compileError("Unsupported type: " ++ @typeName(T)),421 else => @compileError("Unsupported type: " ++ @typeName(T)),
422 })));422 })));
src/crash_report.zig+2-2
...@@ -376,7 +376,7 @@ const PanicSwitch = struct {...@@ -376,7 +376,7 @@ const PanicSwitch = struct {
376 };376 };
377 state.* = new_state;377 state.* = new_state;
378378
379 _ = panicking.fetchAdd(1, .SeqCst);379 _ = panicking.fetchAdd(1, .seq_cst);
380380
381 state.recover_stage = .release_ref_count;381 state.recover_stage = .release_ref_count;
382382
...@@ -458,7 +458,7 @@ const PanicSwitch = struct {...@@ -458,7 +458,7 @@ const PanicSwitch = struct {
458 noinline fn releaseRefCount(state: *volatile PanicState) noreturn {458 noinline fn releaseRefCount(state: *volatile PanicState) noreturn {
459 state.recover_stage = .abort;459 state.recover_stage = .abort;
460460
461 if (panicking.fetchSub(1, .SeqCst) != 1) {461 if (panicking.fetchSub(1, .seq_cst) != 1) {
462 // Another thread is panicking, wait for the last one to finish462 // Another thread is panicking, wait for the last one to finish
463 // and call abort()463 // and call abort()
464464
src/main.zig+3-3
...@@ -4145,8 +4145,8 @@ fn progressThread(progress: *std.Progress, server: *const Server, reset: *std.Th...@@ -4145,8 +4145,8 @@ fn progressThread(progress: *std.Progress, server: *const Server, reset: *std.Th
4145 buf.appendSlice("... ") catch {};4145 buf.appendSlice("... ") catch {};
4146 }4146 }
4147 need_ellipse = false;4147 need_ellipse = false;
4148 const eti = @atomicLoad(usize, &node.unprotected_estimated_total_items, .Monotonic);4148 const eti = @atomicLoad(usize, &node.unprotected_estimated_total_items, .monotonic);
4149 const completed_items = @atomicLoad(usize, &node.unprotected_completed_items, .Monotonic);4149 const completed_items = @atomicLoad(usize, &node.unprotected_completed_items, .monotonic);
4150 const current_item = completed_items + 1;4150 const current_item = completed_items + 1;
4151 if (node.name.len != 0 or eti > 0) {4151 if (node.name.len != 0 or eti > 0) {
4152 if (node.name.len != 0) {4152 if (node.name.len != 0) {
...@@ -4163,7 +4163,7 @@ fn progressThread(progress: *std.Progress, server: *const Server, reset: *std.Th...@@ -4163,7 +4163,7 @@ fn progressThread(progress: *std.Progress, server: *const Server, reset: *std.Th
4163 need_ellipse = false;4163 need_ellipse = false;
4164 }4164 }
4165 }4165 }
4166 maybe_node = @atomicLoad(?*std.Progress.Node, &node.recently_updated_child, .Acquire);4166 maybe_node = @atomicLoad(?*std.Progress.Node, &node.recently_updated_child, .acquire);
4167 }4167 }
4168 }4168 }
41694169
src/print_air.zig+4-4
...@@ -303,10 +303,10 @@ const Writer = struct {...@@ -303,10 +303,10 @@ const Writer = struct {
303 .fence => try w.writeFence(s, inst),303 .fence => try w.writeFence(s, inst),
304 .atomic_load => try w.writeAtomicLoad(s, inst),304 .atomic_load => try w.writeAtomicLoad(s, inst),
305 .prefetch => try w.writePrefetch(s, inst),305 .prefetch => try w.writePrefetch(s, inst),
306 .atomic_store_unordered => try w.writeAtomicStore(s, inst, .Unordered),306 .atomic_store_unordered => try w.writeAtomicStore(s, inst, .unordered),
307 .atomic_store_monotonic => try w.writeAtomicStore(s, inst, .Monotonic),307 .atomic_store_monotonic => try w.writeAtomicStore(s, inst, .monotonic),
308 .atomic_store_release => try w.writeAtomicStore(s, inst, .Release),308 .atomic_store_release => try w.writeAtomicStore(s, inst, .release),
309 .atomic_store_seq_cst => try w.writeAtomicStore(s, inst, .SeqCst),309 .atomic_store_seq_cst => try w.writeAtomicStore(s, inst, .seq_cst),
310 .atomic_rmw => try w.writeAtomicRmw(s, inst),310 .atomic_rmw => try w.writeAtomicRmw(s, inst),
311 .field_parent_ptr => try w.writeFieldParentPtr(s, inst),311 .field_parent_ptr => try w.writeFieldParentPtr(s, inst),
312 .wasm_memory_size => try w.writeWasmMemorySize(s, inst),312 .wasm_memory_size => try w.writeWasmMemorySize(s, inst),
test/behavior/atomics.zig+59-59
...@@ -22,18 +22,18 @@ test "cmpxchg" {...@@ -22,18 +22,18 @@ test "cmpxchg" {
2222
23fn testCmpxchg() !void {23fn testCmpxchg() !void {
24 var x: i32 = 1234;24 var x: i32 = 1234;
25 if (@cmpxchgWeak(i32, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {25 if (@cmpxchgWeak(i32, &x, 99, 5678, .seq_cst, .seq_cst)) |x1| {
26 try expect(x1 == 1234);26 try expect(x1 == 1234);
27 } else {27 } else {
28 @panic("cmpxchg should have failed");28 @panic("cmpxchg should have failed");
29 }29 }
3030
31 while (@cmpxchgWeak(i32, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {31 while (@cmpxchgWeak(i32, &x, 1234, 5678, .seq_cst, .seq_cst)) |x1| {
32 try expect(x1 == 1234);32 try expect(x1 == 1234);
33 }33 }
34 try expect(x == 5678);34 try expect(x == 5678);
3535
36 try expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null);36 try expect(@cmpxchgStrong(i32, &x, 5678, 42, .seq_cst, .seq_cst) == null);
37 try expect(x == 42);37 try expect(x == 42);
38}38}
3939
...@@ -43,7 +43,7 @@ test "fence" {...@@ -43,7 +43,7 @@ test "fence" {
43 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;43 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
4444
45 var x: i32 = 1234;45 var x: i32 = 1234;
46 @fence(.SeqCst);46 @fence(.seq_cst);
47 x = 5678;47 x = 5678;
48}48}
4949
...@@ -60,18 +60,18 @@ test "atomicrmw and atomicload" {...@@ -60,18 +60,18 @@ test "atomicrmw and atomicload" {
60}60}
6161
62fn testAtomicRmw(ptr: *u8) !void {62fn testAtomicRmw(ptr: *u8) !void {
63 const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst);63 const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .seq_cst);
64 try expect(prev_value == 200);64 try expect(prev_value == 200);
65 comptime {65 comptime {
66 var x: i32 = 1234;66 var x: i32 = 1234;
67 const y: i32 = 12345;67 const y: i32 = 12345;
68 try expect(@atomicLoad(i32, &x, .SeqCst) == 1234);68 try expect(@atomicLoad(i32, &x, .seq_cst) == 1234);
69 try expect(@atomicLoad(i32, &y, .SeqCst) == 12345);69 try expect(@atomicLoad(i32, &y, .seq_cst) == 12345);
70 }70 }
71}71}
7272
73fn testAtomicLoad(ptr: *u8) !void {73fn testAtomicLoad(ptr: *u8) !void {
74 const x = @atomicLoad(u8, ptr, .SeqCst);74 const x = @atomicLoad(u8, ptr, .seq_cst);
75 try expect(x == 42);75 try expect(x == 42);
76}76}
7777
...@@ -85,18 +85,18 @@ test "cmpxchg with ptr" {...@@ -85,18 +85,18 @@ test "cmpxchg with ptr" {
85 var data2: i32 = 5678;85 var data2: i32 = 5678;
86 var data3: i32 = 9101;86 var data3: i32 = 9101;
87 var x: *i32 = &data1;87 var x: *i32 = &data1;
88 if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| {88 if (@cmpxchgWeak(*i32, &x, &data2, &data3, .seq_cst, .seq_cst)) |x1| {
89 try expect(x1 == &data1);89 try expect(x1 == &data1);
90 } else {90 } else {
91 @panic("cmpxchg should have failed");91 @panic("cmpxchg should have failed");
92 }92 }
9393
94 while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| {94 while (@cmpxchgWeak(*i32, &x, &data1, &data3, .seq_cst, .seq_cst)) |x1| {
95 try expect(x1 == &data1);95 try expect(x1 == &data1);
96 }96 }
97 try expect(x == &data3);97 try expect(x == &data3);
9898
99 try expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null);99 try expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .seq_cst, .seq_cst) == null);
100 try expect(x == &data2);100 try expect(x == &data2);
101}101}
102102
...@@ -108,7 +108,7 @@ test "cmpxchg with ignored result" {...@@ -108,7 +108,7 @@ test "cmpxchg with ignored result" {
108108
109 var x: i32 = 1234;109 var x: i32 = 1234;
110110
111 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);111 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .monotonic, .monotonic);
112112
113 try expect(5678 == x);113 try expect(5678 == x);
114}114}
...@@ -127,18 +127,18 @@ test "128-bit cmpxchg" {...@@ -127,18 +127,18 @@ test "128-bit cmpxchg" {
127127
128fn test_u128_cmpxchg() !void {128fn test_u128_cmpxchg() !void {
129 var x: u128 align(16) = 1234;129 var x: u128 align(16) = 1234;
130 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {130 if (@cmpxchgWeak(u128, &x, 99, 5678, .seq_cst, .seq_cst)) |x1| {
131 try expect(x1 == 1234);131 try expect(x1 == 1234);
132 } else {132 } else {
133 @panic("cmpxchg should have failed");133 @panic("cmpxchg should have failed");
134 }134 }
135135
136 while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {136 while (@cmpxchgWeak(u128, &x, 1234, 5678, .seq_cst, .seq_cst)) |x1| {
137 try expect(x1 == 1234);137 try expect(x1 == 1234);
138 }138 }
139 try expect(x == 5678);139 try expect(x == 5678);
140140
141 try expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);141 try expect(@cmpxchgStrong(u128, &x, 5678, 42, .seq_cst, .seq_cst) == null);
142 try expect(x == 42);142 try expect(x == 42);
143}143}
144144
...@@ -155,7 +155,7 @@ test "cmpxchg on a global variable" {...@@ -155,7 +155,7 @@ test "cmpxchg on a global variable" {
155 return error.SkipZigTest;155 return error.SkipZigTest;
156 }156 }
157157
158 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);158 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .acquire, .monotonic);
159 try expect(a_global_variable == 42);159 try expect(a_global_variable == 42);
160}160}
161161
...@@ -168,12 +168,12 @@ test "atomic load and rmw with enum" {...@@ -168,12 +168,12 @@ test "atomic load and rmw with enum" {
168 const Value = enum(u8) { a, b, c };168 const Value = enum(u8) { a, b, c };
169 var x = Value.a;169 var x = Value.a;
170170
171 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);171 try expect(@atomicLoad(Value, &x, .seq_cst) != .b);
172172
173 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);173 _ = @atomicRmw(Value, &x, .Xchg, .c, .seq_cst);
174 try expect(@atomicLoad(Value, &x, .SeqCst) == .c);174 try expect(@atomicLoad(Value, &x, .seq_cst) == .c);
175 try expect(@atomicLoad(Value, &x, .SeqCst) != .a);175 try expect(@atomicLoad(Value, &x, .seq_cst) != .a);
176 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);176 try expect(@atomicLoad(Value, &x, .seq_cst) != .b);
177}177}
178178
179test "atomic store" {179test "atomic store" {
...@@ -183,10 +183,10 @@ test "atomic store" {...@@ -183,10 +183,10 @@ test "atomic store" {
183 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;183 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
184184
185 var x: u32 = 0;185 var x: u32 = 0;
186 @atomicStore(u32, &x, 1, .SeqCst);186 @atomicStore(u32, &x, 1, .seq_cst);
187 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);187 try expect(@atomicLoad(u32, &x, .seq_cst) == 1);
188 @atomicStore(u32, &x, 12345678, .SeqCst);188 @atomicStore(u32, &x, 12345678, .seq_cst);
189 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);189 try expect(@atomicLoad(u32, &x, .seq_cst) == 12345678);
190}190}
191191
192test "atomic store comptime" {192test "atomic store comptime" {
...@@ -201,10 +201,10 @@ test "atomic store comptime" {...@@ -201,10 +201,10 @@ test "atomic store comptime" {
201201
202fn testAtomicStore() !void {202fn testAtomicStore() !void {
203 var x: u32 = 0;203 var x: u32 = 0;
204 @atomicStore(u32, &x, 1, .SeqCst);204 @atomicStore(u32, &x, 1, .seq_cst);
205 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);205 try expect(@atomicLoad(u32, &x, .seq_cst) == 1);
206 @atomicStore(u32, &x, 12345678, .SeqCst);206 @atomicStore(u32, &x, 12345678, .seq_cst);
207 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);207 try expect(@atomicLoad(u32, &x, .seq_cst) == 12345678);
208}208}
209209
210test "atomicrmw with floats" {210test "atomicrmw with floats" {
...@@ -224,15 +224,15 @@ test "atomicrmw with floats" {...@@ -224,15 +224,15 @@ test "atomicrmw with floats" {
224fn testAtomicRmwFloat() !void {224fn testAtomicRmwFloat() !void {
225 var x: f32 = 0;225 var x: f32 = 0;
226 try expect(x == 0);226 try expect(x == 0);
227 _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst);227 _ = @atomicRmw(f32, &x, .Xchg, 1, .seq_cst);
228 try expect(x == 1);228 try expect(x == 1);
229 _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst);229 _ = @atomicRmw(f32, &x, .Add, 5, .seq_cst);
230 try expect(x == 6);230 try expect(x == 6);
231 _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);231 _ = @atomicRmw(f32, &x, .Sub, 2, .seq_cst);
232 try expect(x == 4);232 try expect(x == 4);
233 _ = @atomicRmw(f32, &x, .Max, 13, .SeqCst);233 _ = @atomicRmw(f32, &x, .Max, 13, .seq_cst);
234 try expect(x == 13);234 try expect(x == 13);
235 _ = @atomicRmw(f32, &x, .Min, 42, .SeqCst);235 _ = @atomicRmw(f32, &x, .Min, 42, .seq_cst);
236 try expect(x == 13);236 try expect(x == 13);
237}237}
238238
...@@ -266,46 +266,46 @@ fn testAtomicRmwInt(comptime signedness: std.builtin.Signedness, comptime N: usi...@@ -266,46 +266,46 @@ fn testAtomicRmwInt(comptime signedness: std.builtin.Signedness, comptime N: usi
266 const int = std.meta.Int(signedness, N);266 const int = std.meta.Int(signedness, N);
267267
268 var x: int = 1;268 var x: int = 1;
269 var res = @atomicRmw(int, &x, .Xchg, 3, .SeqCst);269 var res = @atomicRmw(int, &x, .Xchg, 3, .seq_cst);
270 try expect(x == 3 and res == 1);270 try expect(x == 3 and res == 1);
271271
272 res = @atomicRmw(int, &x, .Add, 3, .SeqCst);272 res = @atomicRmw(int, &x, .Add, 3, .seq_cst);
273 var y: int = 3;273 var y: int = 3;
274 try expect(res == y);274 try expect(res == y);
275 y = y + 3;275 y = y + 3;
276 try expect(x == y);276 try expect(x == y);
277277
278 res = @atomicRmw(int, &x, .Sub, 1, .SeqCst);278 res = @atomicRmw(int, &x, .Sub, 1, .seq_cst);
279 try expect(res == y);279 try expect(res == y);
280 y = y - 1;280 y = y - 1;
281 try expect(x == y);281 try expect(x == y);
282282
283 res = @atomicRmw(int, &x, .And, 4, .SeqCst);283 res = @atomicRmw(int, &x, .And, 4, .seq_cst);
284 try expect(res == y);284 try expect(res == y);
285 y = y & 4;285 y = y & 4;
286 try expect(x == y);286 try expect(x == y);
287287
288 res = @atomicRmw(int, &x, .Nand, 4, .SeqCst);288 res = @atomicRmw(int, &x, .Nand, 4, .seq_cst);
289 try expect(res == y);289 try expect(res == y);
290 y = ~(y & 4);290 y = ~(y & 4);
291 try expect(x == y);291 try expect(x == y);
292292
293 res = @atomicRmw(int, &x, .Or, 6, .SeqCst);293 res = @atomicRmw(int, &x, .Or, 6, .seq_cst);
294 try expect(res == y);294 try expect(res == y);
295 y = y | 6;295 y = y | 6;
296 try expect(x == y);296 try expect(x == y);
297297
298 res = @atomicRmw(int, &x, .Xor, 2, .SeqCst);298 res = @atomicRmw(int, &x, .Xor, 2, .seq_cst);
299 try expect(res == y);299 try expect(res == y);
300 y = y ^ 2;300 y = y ^ 2;
301 try expect(x == y);301 try expect(x == y);
302302
303 res = @atomicRmw(int, &x, .Max, 1, .SeqCst);303 res = @atomicRmw(int, &x, .Max, 1, .seq_cst);
304 try expect(res == y);304 try expect(res == y);
305 y = @max(y, 1);305 y = @max(y, 1);
306 try expect(x == y);306 try expect(x == y);
307307
308 res = @atomicRmw(int, &x, .Min, 1, .SeqCst);308 res = @atomicRmw(int, &x, .Min, 1, .seq_cst);
309 try expect(res == y);309 try expect(res == y);
310 y = @min(y, 1);310 y = @min(y, 1);
311 try expect(x == y);311 try expect(x == y);
...@@ -333,53 +333,53 @@ fn testAtomicRmwInt128(comptime signedness: std.builtin.Signedness) !void {...@@ -333,53 +333,53 @@ fn testAtomicRmwInt128(comptime signedness: std.builtin.Signedness) !void {
333 const replacement: int = 0x00000000_00000005_00000000_00000003;333 const replacement: int = 0x00000000_00000005_00000000_00000003;
334334
335 var x: int align(16) = initial;335 var x: int align(16) = initial;
336 var res = @atomicRmw(int, &x, .Xchg, replacement, .SeqCst);336 var res = @atomicRmw(int, &x, .Xchg, replacement, .seq_cst);
337 try expect(x == replacement and res == initial);337 try expect(x == replacement and res == initial);
338338
339 var operator: int = 0x00000001_00000000_20000000_00000000;339 var operator: int = 0x00000001_00000000_20000000_00000000;
340 res = @atomicRmw(int, &x, .Add, operator, .SeqCst);340 res = @atomicRmw(int, &x, .Add, operator, .seq_cst);
341 var y: int = replacement;341 var y: int = replacement;
342 try expect(res == y);342 try expect(res == y);
343 y = y + operator;343 y = y + operator;
344 try expect(x == y);344 try expect(x == y);
345345
346 operator = 0x00000000_10000000_00000000_20000000;346 operator = 0x00000000_10000000_00000000_20000000;
347 res = @atomicRmw(int, &x, .Sub, operator, .SeqCst);347 res = @atomicRmw(int, &x, .Sub, operator, .seq_cst);
348 try expect(res == y);348 try expect(res == y);
349 y = y - operator;349 y = y - operator;
350 try expect(x == y);350 try expect(x == y);
351351
352 operator = 0x12345678_87654321_12345678_87654321;352 operator = 0x12345678_87654321_12345678_87654321;
353 res = @atomicRmw(int, &x, .And, operator, .SeqCst);353 res = @atomicRmw(int, &x, .And, operator, .seq_cst);
354 try expect(res == y);354 try expect(res == y);
355 y = y & operator;355 y = y & operator;
356 try expect(x == y);356 try expect(x == y);
357357
358 operator = 0x00000000_10000000_00000000_20000000;358 operator = 0x00000000_10000000_00000000_20000000;
359 res = @atomicRmw(int, &x, .Nand, operator, .SeqCst);359 res = @atomicRmw(int, &x, .Nand, operator, .seq_cst);
360 try expect(res == y);360 try expect(res == y);
361 y = ~(y & operator);361 y = ~(y & operator);
362 try expect(x == y);362 try expect(x == y);
363363
364 operator = 0x12340000_56780000_67890000_98760000;364 operator = 0x12340000_56780000_67890000_98760000;
365 res = @atomicRmw(int, &x, .Or, operator, .SeqCst);365 res = @atomicRmw(int, &x, .Or, operator, .seq_cst);
366 try expect(res == y);366 try expect(res == y);
367 y = y | operator;367 y = y | operator;
368 try expect(x == y);368 try expect(x == y);
369369
370 operator = 0x0a0b0c0d_0e0f0102_03040506_0708090a;370 operator = 0x0a0b0c0d_0e0f0102_03040506_0708090a;
371 res = @atomicRmw(int, &x, .Xor, operator, .SeqCst);371 res = @atomicRmw(int, &x, .Xor, operator, .seq_cst);
372 try expect(res == y);372 try expect(res == y);
373 y = y ^ operator;373 y = y ^ operator;
374 try expect(x == y);374 try expect(x == y);
375375
376 operator = 0x00000000_10000000_00000000_20000000;376 operator = 0x00000000_10000000_00000000_20000000;
377 res = @atomicRmw(int, &x, .Max, operator, .SeqCst);377 res = @atomicRmw(int, &x, .Max, operator, .seq_cst);
378 try expect(res == y);378 try expect(res == y);
379 y = @max(y, operator);379 y = @max(y, operator);
380 try expect(x == y);380 try expect(x == y);
381381
382 res = @atomicRmw(int, &x, .Min, operator, .SeqCst);382 res = @atomicRmw(int, &x, .Min, operator, .seq_cst);
383 try expect(res == y);383 try expect(res == y);
384 y = @min(y, operator);384 y = @min(y, operator);
385 try expect(x == y);385 try expect(x == y);
...@@ -405,13 +405,13 @@ test "atomics with different types" {...@@ -405,13 +405,13 @@ test "atomics with different types" {
405405
406fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {406fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {
407 var x: T = b;407 var x: T = b;
408 @atomicStore(T, &x, a, .SeqCst);408 @atomicStore(T, &x, a, .seq_cst);
409 try expect(x == a);409 try expect(x == a);
410 try expect(@atomicLoad(T, &x, .SeqCst) == a);410 try expect(@atomicLoad(T, &x, .seq_cst) == a);
411 try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a);411 try expect(@atomicRmw(T, &x, .Xchg, b, .seq_cst) == a);
412 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null);412 try expect(@cmpxchgStrong(T, &x, b, a, .seq_cst, .seq_cst) == null);
413 if (@sizeOf(T) != 0)413 if (@sizeOf(T) != 0)
414 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a);414 try expect(@cmpxchgStrong(T, &x, b, a, .seq_cst, .seq_cst).? == a);
415}415}
416416
417test "return @atomicStore, using it as a void value" {417test "return @atomicStore, using it as a void value" {
...@@ -425,12 +425,12 @@ test "return @atomicStore, using it as a void value" {...@@ -425,12 +425,12 @@ test "return @atomicStore, using it as a void value" {
425 value: usize,425 value: usize,
426426
427 pub fn store(self: *A, value: usize) void {427 pub fn store(self: *A, value: usize) void {
428 return @atomicStore(usize, &self.value, value, .Unordered);428 return @atomicStore(usize, &self.value, value, .unordered);
429 }429 }
430430
431 pub fn store2(self: *A, value: usize) void {431 pub fn store2(self: *A, value: usize) void {
432 return switch (value) {432 return switch (value) {
433 else => @atomicStore(usize, &self.value, value, .Unordered),433 else => @atomicStore(usize, &self.value, value, .unordered),
434 };434 };
435 }435 }
436 };436 };
test/behavior/builtin_functions_returning_void_or_noreturn.zig+2-2
...@@ -14,10 +14,10 @@ test {...@@ -14,10 +14,10 @@ test {
14 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;14 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1515
16 var val: u8 = undefined;16 var val: u8 = undefined;
17 try testing.expectEqual({}, @atomicStore(u8, &val, 0, .Unordered));17 try testing.expectEqual({}, @atomicStore(u8, &val, 0, .unordered));
18 try testing.expectEqual(void, @TypeOf(@breakpoint()));18 try testing.expectEqual(void, @TypeOf(@breakpoint()));
19 try testing.expectEqual({}, @export(x, .{ .name = "x" }));19 try testing.expectEqual({}, @export(x, .{ .name = "x" }));
20 try testing.expectEqual({}, @fence(.Acquire));20 try testing.expectEqual({}, @fence(.acquire));
21 try testing.expectEqual({}, @memcpy(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0]));21 try testing.expectEqual({}, @memcpy(@as([*]u8, @ptrFromInt(1))[0..0], @as([*]u8, @ptrFromInt(1))[0..0]));
22 try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined));22 try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined));
23 try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {}));23 try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {}));
test/cases/compile_errors/atomic_orderings_of_atomicStore_Acquire_or_AcqRel.zig+2-2
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1export fn entry() void {1export fn entry() void {
2 var x: u32 = 0;2 var x: u32 = 0;
3 @atomicStore(u32, &x, 1, .Acquire);3 @atomicStore(u32, &x, 1, .acquire);
4}4}
55
6// error6// error
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :3:31: error: @atomicStore atomic ordering must not be Acquire or AcqRel10// :3:31: error: @atomicStore atomic ordering must not be acquire or acq_rel
test/cases/compile_errors/atomic_orderings_of_cmpxchg-failure_stricter_than_success.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const AtomicOrder = @import("std").builtin.AtomicOrder;1const AtomicOrder = @import("std").builtin.AtomicOrder;
2export fn f() void {2export fn f() void {
3 var x: i32 = 1234;3 var x: i32 = 1234;
4 while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}4 while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.monotonic, AtomicOrder.seq_cst)) {}
5}5}
66
7// error7// error
test/cases/compile_errors/atomic_orderings_of_cmpxchg-success_Monotonic_or_stricter.zig+2-2
...@@ -1,11 +1,11 @@...@@ -1,11 +1,11 @@
1const AtomicOrder = @import("std").builtin.AtomicOrder;1const AtomicOrder = @import("std").builtin.AtomicOrder;
2export fn f() void {2export fn f() void {
3 var x: i32 = 1234;3 var x: i32 = 1234;
4 while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}4 while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.unordered, AtomicOrder.unordered)) {}
5}5}
66
7// error7// error
8// backend=stage28// backend=stage2
9// target=native9// target=native
10//10//
11// :4:58: error: success atomic ordering must be Monotonic or stricter11// :4:58: error: success atomic ordering must be monotonic or stricter
test/cases/compile_errors/atomic_orderings_of_fence_Acquire_or_stricter.zig+2-2
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1export fn entry() void {1export fn entry() void {
2 @fence(.Monotonic);2 @fence(.monotonic);
3}3}
44
5// error5// error
6// backend=stage26// backend=stage2
7// target=native7// target=native
8//8//
9// :2:13: error: atomic ordering must be Acquire or stricter9// :2:13: error: atomic ordering must be acquire or stricter
test/cases/compile_errors/atomicrmw_with_bool_op_not_.Xchg.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1export fn entry() void {1export fn entry() void {
2 var x = false;2 var x = false;
3 _ = @atomicRmw(bool, &x, .Add, true, .SeqCst);3 _ = @atomicRmw(bool, &x, .Add, true, .seq_cst);
4}4}
55
6// error6// error
test/cases/compile_errors/atomicrmw_with_enum_op_not_.Xchg.zig+1-1
...@@ -6,7 +6,7 @@ export fn entry() void {...@@ -6,7 +6,7 @@ export fn entry() void {
6 d,6 d,
7 };7 };
8 var x: E = .a;8 var x: E = .a;
9 _ = @atomicRmw(E, &x, .Add, .b, .SeqCst);9 _ = @atomicRmw(E, &x, .Add, .b, .seq_cst);
10}10}
1111
12// error12// error
test/cases/compile_errors/atomicrmw_with_float_op_not_.Xchg_.Add_.Sub_.Max_or_.Min.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1export fn entry() void {1export fn entry() void {
2 var x: f32 = 0;2 var x: f32 = 0;
3 _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);3 _ = @atomicRmw(f32, &x, .And, 2, .seq_cst);
4}4}
55
6// error6// error
test/cases/compile_errors/cmpxchg_with_float.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1export fn entry() void {1export fn entry() void {
2 var x: f32 = 0;2 var x: f32 = 0;
3 _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);3 _ = @cmpxchgWeak(f32, &x, 1, 2, .seq_cst, .seq_cst);
4}4}
55
6// error6// error
test/cases/compile_errors/passing_a_not-aligned-enough_pointer_to_cmpxchg.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const AtomicOrder = @import("std").builtin.AtomicOrder;1const AtomicOrder = @import("std").builtin.AtomicOrder;
2export fn entry() bool {2export fn entry() bool {
3 var x: i32 align(1) = 1234;3 var x: i32 align(1) = 1234;
4 while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}4 while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.seq_cst, AtomicOrder.seq_cst)) {}
5 return x == 5678;5 return x == 5678;
6}6}
77