authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-13 22:01:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-13 22:01:40-07:00
log264acfdf3caef663cddc39c2bf83818abb0e0073
tree26f3019c76b210d3c501745298991d2c8cea18f2
parent97d69e3352ab50f88580c383b5f375b0edadacfd

stage2: fix incorrect spelling of AtomicOrder


8 files changed, 256 insertions(+), 251 deletions(-)

src/AstGen.zig+8-8
......@@ -7322,7 +7322,7 @@ fn builtinCall(
73227322 },
73237323 } });
73247324 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
7325 const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[2]);
7325 const ordering = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[2]);
73267326 const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.Bin{
73277327 .lhs = ptr,
73287328 .rhs = ordering,
......@@ -7343,7 +7343,7 @@ fn builtinCall(
73437343 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
73447344 const operation = try expr(gz, scope, .{ .ty = .atomic_rmw_op_type }, params[2]);
73457345 const operand = try expr(gz, scope, .{ .ty = int_type }, params[3]);
7346 const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[4]);
7346 const ordering = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[4]);
73477347 const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{
73487348 .ptr = ptr,
73497349 .operation = operation,
......@@ -7365,7 +7365,7 @@ fn builtinCall(
73657365 } });
73667366 const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]);
73677367 const operand = try expr(gz, scope, .{ .ty = int_type }, params[2]);
7368 const ordering = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[3]);
7368 const ordering = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[3]);
73697369 const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{
73707370 .ptr = ptr,
73717371 .operand = operand,
......@@ -7553,11 +7553,11 @@ fn cmpxchg(
75537553 } });
75547554 const result = try gz.addPlNode(tag, node, Zir.Inst.Cmpxchg{
75557555 // zig fmt: off
7556 .ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]),
7557 .expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]),
7558 .new_value = try expr(gz, scope, .{ .ty = int_type }, params[3]),
7559 .success_order = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[4]),
7560 .fail_order = try expr(gz, scope, .{ .ty = .atomic_ordering_type }, params[5]),
7556 .ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[1]),
7557 .expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]),
7558 .new_value = try expr(gz, scope, .{ .ty = int_type }, params[3]),
7559 .success_order = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[4]),
7560 .fail_order = try expr(gz, scope, .{ .ty = .atomic_order_type }, params[5]),
75617561 // zig fmt: on
75627562 });
75637563 return rvalue(gz, rl, result, node);
src/Sema.zig+3-3
......@@ -9702,7 +9702,7 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type
97029702 .type_info => return sema.resolveBuiltinTypeFields(block, src, "TypeInfo"),
97039703 .extern_options => return sema.resolveBuiltinTypeFields(block, src, "ExternOptions"),
97049704 .export_options => return sema.resolveBuiltinTypeFields(block, src, "ExportOptions"),
9705 .atomic_ordering => return sema.resolveBuiltinTypeFields(block, src, "AtomicOrdering"),
9705 .atomic_order => return sema.resolveBuiltinTypeFields(block, src, "AtomicOrder"),
97069706 .atomic_rmw_op => return sema.resolveBuiltinTypeFields(block, src, "AtomicRmwOp"),
97079707 .calling_convention => return sema.resolveBuiltinTypeFields(block, src, "CallingConvention"),
97089708 .float_mode => return sema.resolveBuiltinTypeFields(block, src, "FloatMode"),
......@@ -10096,7 +10096,7 @@ fn typeHasOnePossibleValue(
1009610096 .var_args_param,
1009710097 .manyptr_u8,
1009810098 .manyptr_const_u8,
10099 .atomic_ordering,
10099 .atomic_order,
1010010100 .atomic_rmw_op,
1010110101 .calling_convention,
1010210102 .float_mode,
......@@ -10281,7 +10281,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
1028110281 .@"null" => return .null_type,
1028210282 .@"undefined" => return .undefined_type,
1028310283 .enum_literal => return .enum_literal_type,
10284 .atomic_ordering => return .atomic_ordering_type,
10284 .atomic_order => return .atomic_order_type,
1028510285 .atomic_rmw_op => return .atomic_rmw_op_type,
1028610286 .calling_convention => return .calling_convention_type,
1028710287 .float_mode => return .float_mode_type,
src/Zir.zig+3-3
......@@ -1714,7 +1714,7 @@ pub const Inst = struct {
17141714 null_type,
17151715 undefined_type,
17161716 enum_literal_type,
1717 atomic_ordering_type,
1717 atomic_order_type,
17181718 atomic_rmw_op_type,
17191719 calling_convention_type,
17201720 float_mode_type,
......@@ -1961,9 +1961,9 @@ pub const Inst = struct {
19611961 .ty = Type.initTag(.type),
19621962 .val = Value.initTag(.manyptr_const_u8_type),
19631963 },
1964 .atomic_ordering_type = .{
1964 .atomic_order_type = .{
19651965 .ty = Type.initTag(.type),
1966 .val = Value.initTag(.atomic_ordering_type),
1966 .val = Value.initTag(.atomic_order_type),
19671967 },
19681968 .atomic_rmw_op_type = .{
19691969 .ty = Type.initTag(.type),
src/type.zig+19-19
......@@ -124,7 +124,7 @@ pub const Type = extern union {
124124 .enum_full,
125125 .enum_nonexhaustive,
126126 .enum_simple,
127 .atomic_ordering,
127 .atomic_order,
128128 .atomic_rmw_op,
129129 .calling_convention,
130130 .float_mode,
......@@ -743,7 +743,7 @@ pub const Type = extern union {
743743 .empty_struct_literal,
744744 .manyptr_u8,
745745 .manyptr_const_u8,
746 .atomic_ordering,
746 .atomic_order,
747747 .atomic_rmw_op,
748748 .calling_convention,
749749 .float_mode,
......@@ -955,7 +955,7 @@ pub const Type = extern union {
955955 .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),
956956 .manyptr_u8 => return writer.writeAll("[*]u8"),
957957 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),
958 .atomic_ordering => return writer.writeAll("std.builtin.AtomicOrdering"),
958 .atomic_order => return writer.writeAll("std.builtin.AtomicOrder"),
959959 .atomic_rmw_op => return writer.writeAll("std.builtin.AtomicRmwOp"),
960960 .calling_convention => return writer.writeAll("std.builtin.CallingConvention"),
961961 .float_mode => return writer.writeAll("std.builtin.FloatMode"),
......@@ -1183,7 +1183,7 @@ pub const Type = extern union {
11831183 .@"anyframe",
11841184 .@"null",
11851185 .@"undefined",
1186 .atomic_ordering,
1186 .atomic_order,
11871187 .atomic_rmw_op,
11881188 .calling_convention,
11891189 .float_mode,
......@@ -1298,7 +1298,7 @@ pub const Type = extern union {
12981298 .enum_literal => return Value.initTag(.enum_literal_type),
12991299 .manyptr_u8 => return Value.initTag(.manyptr_u8_type),
13001300 .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),
1301 .atomic_ordering => return Value.initTag(.atomic_ordering_type),
1301 .atomic_order => return Value.initTag(.atomic_order_type),
13021302 .atomic_rmw_op => return Value.initTag(.atomic_rmw_op_type),
13031303 .calling_convention => return Value.initTag(.calling_convention_type),
13041304 .float_mode => return Value.initTag(.float_mode_type),
......@@ -1359,7 +1359,7 @@ pub const Type = extern union {
13591359 .error_set_inferred,
13601360 .manyptr_u8,
13611361 .manyptr_const_u8,
1362 .atomic_ordering,
1362 .atomic_order,
13631363 .atomic_rmw_op,
13641364 .calling_convention,
13651365 .float_mode,
......@@ -1505,7 +1505,7 @@ pub const Type = extern union {
15051505 .bool,
15061506 .array_u8_sentinel_0,
15071507 .array_u8,
1508 .atomic_ordering,
1508 .atomic_order,
15091509 .atomic_rmw_op,
15101510 .calling_convention,
15111511 .float_mode,
......@@ -1727,7 +1727,7 @@ pub const Type = extern union {
17271727 .u8,
17281728 .i8,
17291729 .bool,
1730 .atomic_ordering,
1730 .atomic_order,
17311731 .atomic_rmw_op,
17321732 .calling_convention,
17331733 .float_mode,
......@@ -2011,7 +2011,7 @@ pub const Type = extern union {
20112011 @panic("TODO bitSize error union");
20122012 },
20132013
2014 .atomic_ordering,
2014 .atomic_order,
20152015 .atomic_rmw_op,
20162016 .calling_convention,
20172017 .float_mode,
......@@ -2725,7 +2725,7 @@ pub const Type = extern union {
27252725 .var_args_param,
27262726 .manyptr_u8,
27272727 .manyptr_const_u8,
2728 .atomic_ordering,
2728 .atomic_order,
27292729 .atomic_rmw_op,
27302730 .calling_convention,
27312731 .float_mode,
......@@ -2903,7 +2903,7 @@ pub const Type = extern union {
29032903 const enum_simple = ty.castTag(.enum_simple).?.data;
29042904 return enum_simple.fields.count();
29052905 },
2906 .atomic_ordering,
2906 .atomic_order,
29072907 .atomic_rmw_op,
29082908 .calling_convention,
29092909 .float_mode,
......@@ -2927,7 +2927,7 @@ pub const Type = extern union {
29272927 const enum_simple = ty.castTag(.enum_simple).?.data;
29282928 return enum_simple.fields.keys()[field_index];
29292929 },
2930 .atomic_ordering,
2930 .atomic_order,
29312931 .atomic_rmw_op,
29322932 .calling_convention,
29332933 .float_mode,
......@@ -2950,7 +2950,7 @@ pub const Type = extern union {
29502950 const enum_simple = ty.castTag(.enum_simple).?.data;
29512951 return enum_simple.fields.getIndex(field_name);
29522952 },
2953 .atomic_ordering,
2953 .atomic_order,
29542954 .atomic_rmw_op,
29552955 .calling_convention,
29562956 .float_mode,
......@@ -3003,7 +3003,7 @@ pub const Type = extern union {
30033003 const tag_ty = Type.initPayload(&buffer.base);
30043004 return S.fieldWithRange(tag_ty, enum_tag, fields_len);
30053005 },
3006 .atomic_ordering,
3006 .atomic_order,
30073007 .atomic_rmw_op,
30083008 .calling_convention,
30093009 .float_mode,
......@@ -3058,7 +3058,7 @@ pub const Type = extern union {
30583058 const union_obj = ty.cast(Payload.Union).?.data;
30593059 return union_obj.srcLoc();
30603060 },
3061 .atomic_ordering,
3061 .atomic_order,
30623062 .atomic_rmw_op,
30633063 .calling_convention,
30643064 .float_mode,
......@@ -3095,7 +3095,7 @@ pub const Type = extern union {
30953095 return union_obj.owner_decl;
30963096 },
30973097 .@"opaque" => @panic("TODO"),
3098 .atomic_ordering,
3098 .atomic_order,
30993099 .atomic_rmw_op,
31003100 .calling_convention,
31013101 .float_mode,
......@@ -3145,7 +3145,7 @@ pub const Type = extern union {
31453145 const tag_ty = Type.initPayload(&buffer.base);
31463146 return S.intInRange(tag_ty, int, fields_len);
31473147 },
3148 .atomic_ordering,
3148 .atomic_order,
31493149 .atomic_rmw_op,
31503150 .calling_convention,
31513151 .float_mode,
......@@ -3205,7 +3205,7 @@ pub const Type = extern union {
32053205 @"null",
32063206 @"undefined",
32073207 enum_literal,
3208 atomic_ordering,
3208 atomic_order,
32093209 atomic_rmw_op,
32103210 calling_convention,
32113211 float_mode,
......@@ -3328,7 +3328,7 @@ pub const Type = extern union {
33283328 .empty_struct_literal,
33293329 .manyptr_u8,
33303330 .manyptr_const_u8,
3331 .atomic_ordering,
3331 .atomic_order,
33323332 .atomic_rmw_op,
33333333 .calling_convention,
33343334 .float_mode,
src/value.zig+5-5
......@@ -60,7 +60,7 @@ pub const Value = extern union {
6060 null_type,
6161 undefined_type,
6262 enum_literal_type,
63 atomic_ordering_type,
63 atomic_order_type,
6464 atomic_rmw_op_type,
6565 calling_convention_type,
6666 float_mode_type,
......@@ -223,7 +223,7 @@ pub const Value = extern union {
223223 .abi_align_default,
224224 .manyptr_u8_type,
225225 .manyptr_const_u8_type,
226 .atomic_ordering_type,
226 .atomic_order_type,
227227 .atomic_rmw_op_type,
228228 .calling_convention_type,
229229 .float_mode_type,
......@@ -409,7 +409,7 @@ pub const Value = extern union {
409409 .abi_align_default,
410410 .manyptr_u8_type,
411411 .manyptr_const_u8_type,
412 .atomic_ordering_type,
412 .atomic_order_type,
413413 .atomic_rmw_op_type,
414414 .calling_convention_type,
415415 .float_mode_type,
......@@ -622,7 +622,7 @@ pub const Value = extern union {
622622 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
623623 .manyptr_u8_type => return out_stream.writeAll("[*]u8"),
624624 .manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"),
625 .atomic_ordering_type => return out_stream.writeAll("std.builtin.AtomicOrdering"),
625 .atomic_order_type => return out_stream.writeAll("std.builtin.AtomicOrder"),
626626 .atomic_rmw_op_type => return out_stream.writeAll("std.builtin.AtomicRmwOp"),
627627 .calling_convention_type => return out_stream.writeAll("std.builtin.CallingConvention"),
628628 .float_mode_type => return out_stream.writeAll("std.builtin.FloatMode"),
......@@ -789,7 +789,7 @@ pub const Value = extern union {
789789 .enum_literal_type => Type.initTag(.enum_literal),
790790 .manyptr_u8_type => Type.initTag(.manyptr_u8),
791791 .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),
792 .atomic_ordering_type => Type.initTag(.atomic_ordering),
792 .atomic_order_type => Type.initTag(.atomic_order),
793793 .atomic_rmw_op_type => Type.initTag(.atomic_rmw_op),
794794 .calling_convention_type => Type.initTag(.calling_convention),
795795 .float_mode_type => Type.initTag(.float_mode),
test/behavior.zig+2-1
......@@ -11,6 +11,7 @@ test {
1111 _ = @import("behavior/cast.zig");
1212 _ = @import("behavior/array.zig");
1313 _ = @import("behavior/usingnamespace.zig");
14 _ = @import("behavior/atomics.zig");
1415
1516 if (!builtin.zig_is_stage2) {
1617 // Tests that only pass for stage1.
......@@ -21,7 +22,7 @@ test {
2122 _ = @import("behavior/asm.zig");
2223 _ = @import("behavior/async_fn.zig");
2324 }
24 _ = @import("behavior/atomics.zig");
25 _ = @import("behavior/atomics_stage1.zig");
2526 _ = @import("behavior/await_struct.zig");
2627 _ = @import("behavior/bit_shifting.zig");
2728 _ = @import("behavior/bitcast.zig");
test/behavior/atomics.zig-212
......@@ -2,215 +2,3 @@ const std = @import("std");
22const expect = std.testing.expect;
33const expectEqual = std.testing.expectEqual;
44const builtin = @import("builtin");
5
6test "cmpxchg" {
7 try testCmpxchg();
8 comptime try testCmpxchg();
9}
10
11fn testCmpxchg() !void {
12 var x: i32 = 1234;
13 if (@cmpxchgWeak(i32, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
14 try expect(x1 == 1234);
15 } else {
16 @panic("cmpxchg should have failed");
17 }
18
19 while (@cmpxchgWeak(i32, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
20 try expect(x1 == 1234);
21 }
22 try expect(x == 5678);
23
24 try expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null);
25 try expect(x == 42);
26}
27
28test "fence" {
29 var x: i32 = 1234;
30 @fence(.SeqCst);
31 x = 5678;
32}
33
34test "atomicrmw and atomicload" {
35 var data: u8 = 200;
36 try testAtomicRmw(&data);
37 try expect(data == 42);
38 try testAtomicLoad(&data);
39}
40
41fn testAtomicRmw(ptr: *u8) !void {
42 const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst);
43 try expect(prev_value == 200);
44 comptime {
45 var x: i32 = 1234;
46 const y: i32 = 12345;
47 try expect(@atomicLoad(i32, &x, .SeqCst) == 1234);
48 try expect(@atomicLoad(i32, &y, .SeqCst) == 12345);
49 }
50}
51
52fn testAtomicLoad(ptr: *u8) !void {
53 const x = @atomicLoad(u8, ptr, .SeqCst);
54 try expect(x == 42);
55}
56
57test "cmpxchg with ptr" {
58 var data1: i32 = 1234;
59 var data2: i32 = 5678;
60 var data3: i32 = 9101;
61 var x: *i32 = &data1;
62 if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| {
63 try expect(x1 == &data1);
64 } else {
65 @panic("cmpxchg should have failed");
66 }
67
68 while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| {
69 try expect(x1 == &data1);
70 }
71 try expect(x == &data3);
72
73 try expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null);
74 try expect(x == &data2);
75}
76
77test "128-bit cmpxchg" {
78 try test_u128_cmpxchg();
79 comptime try test_u128_cmpxchg();
80}
81
82fn test_u128_cmpxchg() !void {
83 if (std.Target.current.cpu.arch != .x86_64) return error.SkipZigTest;
84 if (comptime !std.Target.x86.featureSetHas(std.Target.current.cpu.features, .cx16)) return error.SkipZigTest;
85
86 var x: u128 = 1234;
87 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
88 try expect(x1 == 1234);
89 } else {
90 @panic("cmpxchg should have failed");
91 }
92
93 while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
94 try expect(x1 == 1234);
95 }
96 try expect(x == 5678);
97
98 try expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
99 try expect(x == 42);
100}
101
102test "cmpxchg with ignored result" {
103 var x: i32 = 1234;
104
105 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
106
107 try expectEqual(@as(i32, 5678), x);
108}
109
110var a_global_variable = @as(u32, 1234);
111
112test "cmpxchg on a global variable" {
113 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
114 try expectEqual(@as(u32, 42), a_global_variable);
115}
116
117test "atomic load and rmw with enum" {
118 const Value = enum(u8) {
119 a,
120 b,
121 c,
122 };
123 var x = Value.a;
124
125 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
126
127 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
128 try expect(@atomicLoad(Value, &x, .SeqCst) == .c);
129 try expect(@atomicLoad(Value, &x, .SeqCst) != .a);
130 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
131}
132
133test "atomic store" {
134 var x: u32 = 0;
135 @atomicStore(u32, &x, 1, .SeqCst);
136 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
137 @atomicStore(u32, &x, 12345678, .SeqCst);
138 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
139}
140
141test "atomic store comptime" {
142 comptime try testAtomicStore();
143 try testAtomicStore();
144}
145
146fn testAtomicStore() !void {
147 var x: u32 = 0;
148 @atomicStore(u32, &x, 1, .SeqCst);
149 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
150 @atomicStore(u32, &x, 12345678, .SeqCst);
151 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
152}
153
154test "atomicrmw with floats" {
155 try testAtomicRmwFloat();
156 comptime try testAtomicRmwFloat();
157}
158
159fn testAtomicRmwFloat() !void {
160 var x: f32 = 0;
161 try expect(x == 0);
162 _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst);
163 try expect(x == 1);
164 _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst);
165 try expect(x == 6);
166 _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);
167 try expect(x == 4);
168}
169
170test "atomicrmw with ints" {
171 try testAtomicRmwInt();
172 comptime try testAtomicRmwInt();
173}
174
175fn testAtomicRmwInt() !void {
176 var x: u8 = 1;
177 var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst);
178 try expect(x == 3 and res == 1);
179 _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst);
180 try expect(x == 6);
181 _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst);
182 try expect(x == 5);
183 _ = @atomicRmw(u8, &x, .And, 4, .SeqCst);
184 try expect(x == 4);
185 _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst);
186 try expect(x == 0xfb);
187 _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst);
188 try expect(x == 0xff);
189 _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst);
190 try expect(x == 0xfd);
191
192 _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst);
193 try expect(x == 0xfd);
194 _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
195 try expect(x == 1);
196}
197
198test "atomics with different types" {
199 try testAtomicsWithType(bool, true, false);
200 inline for (.{ u1, i4, u5, i15, u24 }) |T| {
201 try testAtomicsWithType(T, 0, 1);
202 }
203 try testAtomicsWithType(u0, 0, 0);
204 try testAtomicsWithType(i0, 0, 0);
205}
206
207fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {
208 var x: T = b;
209 @atomicStore(T, &x, a, .SeqCst);
210 try expect(x == a);
211 try expect(@atomicLoad(T, &x, .SeqCst) == a);
212 try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a);
213 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null);
214 if (@sizeOf(T) != 0)
215 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a);
216}
test/behavior/atomics_stage1.zig created+216
......@@ -0,0 +1,216 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4const builtin = @import("builtin");
5
6test "cmpxchg" {
7 try testCmpxchg();
8 comptime try testCmpxchg();
9}
10
11fn testCmpxchg() !void {
12 var x: i32 = 1234;
13 if (@cmpxchgWeak(i32, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
14 try expect(x1 == 1234);
15 } else {
16 @panic("cmpxchg should have failed");
17 }
18
19 while (@cmpxchgWeak(i32, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
20 try expect(x1 == 1234);
21 }
22 try expect(x == 5678);
23
24 try expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null);
25 try expect(x == 42);
26}
27
28test "fence" {
29 var x: i32 = 1234;
30 @fence(.SeqCst);
31 x = 5678;
32}
33
34test "atomicrmw and atomicload" {
35 var data: u8 = 200;
36 try testAtomicRmw(&data);
37 try expect(data == 42);
38 try testAtomicLoad(&data);
39}
40
41fn testAtomicRmw(ptr: *u8) !void {
42 const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst);
43 try expect(prev_value == 200);
44 comptime {
45 var x: i32 = 1234;
46 const y: i32 = 12345;
47 try expect(@atomicLoad(i32, &x, .SeqCst) == 1234);
48 try expect(@atomicLoad(i32, &y, .SeqCst) == 12345);
49 }
50}
51
52fn testAtomicLoad(ptr: *u8) !void {
53 const x = @atomicLoad(u8, ptr, .SeqCst);
54 try expect(x == 42);
55}
56
57test "cmpxchg with ptr" {
58 var data1: i32 = 1234;
59 var data2: i32 = 5678;
60 var data3: i32 = 9101;
61 var x: *i32 = &data1;
62 if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| {
63 try expect(x1 == &data1);
64 } else {
65 @panic("cmpxchg should have failed");
66 }
67
68 while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| {
69 try expect(x1 == &data1);
70 }
71 try expect(x == &data3);
72
73 try expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null);
74 try expect(x == &data2);
75}
76
77test "128-bit cmpxchg" {
78 try test_u128_cmpxchg();
79 comptime try test_u128_cmpxchg();
80}
81
82fn test_u128_cmpxchg() !void {
83 if (std.Target.current.cpu.arch != .x86_64) return error.SkipZigTest;
84 if (comptime !std.Target.x86.featureSetHas(std.Target.current.cpu.features, .cx16)) return error.SkipZigTest;
85
86 var x: u128 = 1234;
87 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
88 try expect(x1 == 1234);
89 } else {
90 @panic("cmpxchg should have failed");
91 }
92
93 while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
94 try expect(x1 == 1234);
95 }
96 try expect(x == 5678);
97
98 try expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
99 try expect(x == 42);
100}
101
102test "cmpxchg with ignored result" {
103 var x: i32 = 1234;
104
105 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
106
107 try expectEqual(@as(i32, 5678), x);
108}
109
110var a_global_variable = @as(u32, 1234);
111
112test "cmpxchg on a global variable" {
113 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
114 try expectEqual(@as(u32, 42), a_global_variable);
115}
116
117test "atomic load and rmw with enum" {
118 const Value = enum(u8) {
119 a,
120 b,
121 c,
122 };
123 var x = Value.a;
124
125 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
126
127 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
128 try expect(@atomicLoad(Value, &x, .SeqCst) == .c);
129 try expect(@atomicLoad(Value, &x, .SeqCst) != .a);
130 try expect(@atomicLoad(Value, &x, .SeqCst) != .b);
131}
132
133test "atomic store" {
134 var x: u32 = 0;
135 @atomicStore(u32, &x, 1, .SeqCst);
136 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
137 @atomicStore(u32, &x, 12345678, .SeqCst);
138 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
139}
140
141test "atomic store comptime" {
142 comptime try testAtomicStore();
143 try testAtomicStore();
144}
145
146fn testAtomicStore() !void {
147 var x: u32 = 0;
148 @atomicStore(u32, &x, 1, .SeqCst);
149 try expect(@atomicLoad(u32, &x, .SeqCst) == 1);
150 @atomicStore(u32, &x, 12345678, .SeqCst);
151 try expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
152}
153
154test "atomicrmw with floats" {
155 try testAtomicRmwFloat();
156 comptime try testAtomicRmwFloat();
157}
158
159fn testAtomicRmwFloat() !void {
160 var x: f32 = 0;
161 try expect(x == 0);
162 _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst);
163 try expect(x == 1);
164 _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst);
165 try expect(x == 6);
166 _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);
167 try expect(x == 4);
168}
169
170test "atomicrmw with ints" {
171 try testAtomicRmwInt();
172 comptime try testAtomicRmwInt();
173}
174
175fn testAtomicRmwInt() !void {
176 var x: u8 = 1;
177 var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst);
178 try expect(x == 3 and res == 1);
179 _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst);
180 try expect(x == 6);
181 _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst);
182 try expect(x == 5);
183 _ = @atomicRmw(u8, &x, .And, 4, .SeqCst);
184 try expect(x == 4);
185 _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst);
186 try expect(x == 0xfb);
187 _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst);
188 try expect(x == 0xff);
189 _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst);
190 try expect(x == 0xfd);
191
192 _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst);
193 try expect(x == 0xfd);
194 _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
195 try expect(x == 1);
196}
197
198test "atomics with different types" {
199 try testAtomicsWithType(bool, true, false);
200 inline for (.{ u1, i4, u5, i15, u24 }) |T| {
201 try testAtomicsWithType(T, 0, 1);
202 }
203 try testAtomicsWithType(u0, 0, 0);
204 try testAtomicsWithType(i0, 0, 0);
205}
206
207fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {
208 var x: T = b;
209 @atomicStore(T, &x, a, .SeqCst);
210 try expect(x == a);
211 try expect(@atomicLoad(T, &x, .SeqCst) == a);
212 try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a);
213 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null);
214 if (@sizeOf(T) != 0)
215 try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a);
216}