Bumping gaia.json for 3 gaia revision(s) a=gaia-bump
[gecko.git] / mfbt / tests / TestAtomics.cpp
blob45156a12824ec1a63870d0af32443fe947a4efc1
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Assertions.h"
8 #include "mozilla/Atomics.h"
10 #include <stdint.h>
12 using mozilla::Atomic;
13 using mozilla::MemoryOrdering;
14 using mozilla::Relaxed;
15 using mozilla::ReleaseAcquire;
16 using mozilla::SequentiallyConsistent;
18 #define A(a,b) MOZ_RELEASE_ASSERT(a,b)
20 template <typename T, MemoryOrdering Order>
21 static void
22 TestTypeWithOrdering()
24 Atomic<T, Order> atomic(5);
25 A(atomic == 5, "Atomic variable did not initialize");
27 // Test atomic increment
28 A(++atomic == T(6), "Atomic increment did not work");
29 A(atomic++ == T(6), "Atomic post-increment did not work");
30 A(atomic == T(7), "Atomic post-increment did not work");
32 // Test atomic decrement
33 A(--atomic == 6, "Atomic decrement did not work");
34 A(atomic-- == 6, "Atomic post-decrement did not work");
35 A(atomic == 5, "Atomic post-decrement did not work");
37 // Test other arithmetic.
38 T result;
39 result = (atomic += T(5));
40 A(atomic == T(10), "Atomic += did not work");
41 A(result == T(10), "Atomic += returned the wrong value");
42 result = (atomic -= T(3));
43 A(atomic == T(7), "Atomic -= did not work");
44 A(result == T(7), "Atomic -= returned the wrong value");
46 // Test assignment
47 result = (atomic = T(5));
48 A(atomic == T(5), "Atomic assignment failed");
49 A(result == T(5), "Atomic assignment returned the wrong value");
51 // Test logical operations.
52 result = (atomic ^= T(2));
53 A(atomic == T(7), "Atomic ^= did not work");
54 A(result == T(7), "Atomic ^= returned the wrong value");
55 result = (atomic ^= T(4));
56 A(atomic == T(3), "Atomic ^= did not work");
57 A(result == T(3), "Atomic ^= returned the wrong value");
58 result = (atomic |= T(8));
59 A(atomic == T(11), "Atomic |= did not work");
60 A(result == T(11), "Atomic |= returned the wrong value");
61 result = (atomic |= T(8));
62 A(atomic == T(11), "Atomic |= did not work");
63 A(result == T(11), "Atomic |= returned the wrong value");
64 result = (atomic &= T(12));
65 A(atomic == T(8), "Atomic &= did not work");
66 A(result == T(8), "Atomic &= returned the wrong value");
68 // Test exchange.
69 atomic = T(30);
70 result = atomic.exchange(42);
71 A(atomic == T(42), "Atomic exchange did not work");
72 A(result == T(30), "Atomic exchange returned the wrong value");
74 // Test CAS.
75 atomic = T(1);
76 bool boolResult = atomic.compareExchange(0, 2);
77 A(!boolResult, "CAS should have returned false.");
78 A(atomic == T(1), "CAS shouldn't have done anything.");
80 boolResult = atomic.compareExchange(1, 42);
81 A(boolResult, "CAS should have succeeded.");
82 A(atomic == T(42), "CAS should have changed atomic's value.");
85 template<typename T, MemoryOrdering Order>
86 static void
87 TestPointerWithOrdering()
89 T array1[10];
90 Atomic<T*, Order> atomic(array1);
91 A(atomic == array1, "Atomic variable did not initialize");
93 // Test atomic increment
94 A(++atomic == array1 + 1, "Atomic increment did not work");
95 A(atomic++ == array1 + 1, "Atomic post-increment did not work");
96 A(atomic == array1 + 2, "Atomic post-increment did not work");
98 // Test atomic decrement
99 A(--atomic == array1 + 1, "Atomic decrement did not work");
100 A(atomic-- == array1 + 1, "Atomic post-decrement did not work");
101 A(atomic == array1, "Atomic post-decrement did not work");
103 // Test other arithmetic operations
104 T* result;
105 result = (atomic += 2);
106 A(atomic == array1 + 2, "Atomic += did not work");
107 A(result == array1 + 2, "Atomic += returned the wrong value");
108 result = (atomic -= 1);
109 A(atomic == array1 + 1, "Atomic -= did not work");
110 A(result == array1 + 1, "Atomic -= returned the wrong value");
112 // Test stores
113 result = (atomic = array1);
114 A(atomic == array1, "Atomic assignment did not work");
115 A(result == array1, "Atomic assignment returned the wrong value");
117 // Test exchange
118 atomic = array1 + 2;
119 result = atomic.exchange(array1);
120 A(atomic == array1, "Atomic exchange did not work");
121 A(result == array1 + 2, "Atomic exchange returned the wrong value");
123 atomic = array1;
124 bool boolResult = atomic.compareExchange(array1 + 1, array1 + 2);
125 A(!boolResult, "CAS should have returned false.");
126 A(atomic == array1, "CAS shouldn't have done anything.");
128 boolResult = atomic.compareExchange(array1, array1 + 3);
129 A(boolResult, "CAS should have succeeded.");
130 A(atomic == array1 + 3, "CAS should have changed atomic's value.");
133 enum EnumType
135 EnumType_0 = 0,
136 EnumType_1 = 1,
137 EnumType_2 = 2,
138 EnumType_3 = 3
141 template<MemoryOrdering Order>
142 static void
143 TestEnumWithOrdering()
145 Atomic<EnumType, Order> atomic(EnumType_2);
146 A(atomic == EnumType_2, "Atomic variable did not initialize");
148 // Test assignment
149 EnumType result;
150 result = (atomic = EnumType_3);
151 A(atomic == EnumType_3, "Atomic assignment failed");
152 A(result == EnumType_3, "Atomic assignment returned the wrong value");
154 // Test exchange.
155 atomic = EnumType_1;
156 result = atomic.exchange(EnumType_2);
157 A(atomic == EnumType_2, "Atomic exchange did not work");
158 A(result == EnumType_1, "Atomic exchange returned the wrong value");
160 // Test CAS.
161 atomic = EnumType_1;
162 bool boolResult = atomic.compareExchange(EnumType_0, EnumType_2);
163 A(!boolResult, "CAS should have returned false.");
164 A(atomic == EnumType_1, "CAS shouldn't have done anything.");
166 boolResult = atomic.compareExchange(EnumType_1, EnumType_3);
167 A(boolResult, "CAS should have succeeded.");
168 A(atomic == EnumType_3, "CAS should have changed atomic's value.");
171 template <MemoryOrdering Order>
172 static void
173 TestBoolWithOrdering()
175 Atomic<bool, Order> atomic(false);
176 A(atomic == false, "Atomic variable did not initialize");
178 // Test assignment
179 bool result;
180 result = (atomic = true);
181 A(atomic == true, "Atomic assignment failed");
182 A(result == true, "Atomic assignment returned the wrong value");
184 // Test exchange.
185 atomic = false;
186 result = atomic.exchange(true);
187 A(atomic == true, "Atomic exchange did not work");
188 A(result == false, "Atomic exchange returned the wrong value");
190 // Test CAS.
191 atomic = false;
192 bool boolResult = atomic.compareExchange(true, false);
193 A(!boolResult, "CAS should have returned false.");
194 A(atomic == false, "CAS shouldn't have done anything.");
196 boolResult = atomic.compareExchange(false, true);
197 A(boolResult, "CAS should have succeeded.");
198 A(atomic == true, "CAS should have changed atomic's value.");
201 template <typename T>
202 static void
203 TestType()
205 TestTypeWithOrdering<T, SequentiallyConsistent>();
206 TestTypeWithOrdering<T, ReleaseAcquire>();
207 TestTypeWithOrdering<T, Relaxed>();
210 template<typename T>
211 static void
212 TestPointer()
214 TestPointerWithOrdering<T, SequentiallyConsistent>();
215 TestPointerWithOrdering<T, ReleaseAcquire>();
216 TestPointerWithOrdering<T, Relaxed>();
219 static void
220 TestEnum()
222 TestEnumWithOrdering<SequentiallyConsistent>();
223 TestEnumWithOrdering<ReleaseAcquire>();
224 TestEnumWithOrdering<Relaxed>();
227 static void
228 TestBool()
230 TestBoolWithOrdering<SequentiallyConsistent>();
231 TestBoolWithOrdering<ReleaseAcquire>();
232 TestBoolWithOrdering<Relaxed>();
235 #undef A
238 main()
240 TestType<uint32_t>();
241 TestType<int32_t>();
242 TestType<intptr_t>();
243 TestType<uintptr_t>();
244 TestPointer<int>();
245 TestPointer<float>();
246 TestPointer<uint16_t*>();
247 TestPointer<uint32_t*>();
248 TestEnum();
249 TestBool();
250 return 0;