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"
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
>
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.
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");
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");
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");
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
>
87 TestPointerWithOrdering()
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
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");
113 result
= (atomic
= array1
);
114 A(atomic
== array1
, "Atomic assignment did not work");
115 A(result
== array1
, "Atomic assignment returned the wrong value");
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");
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.");
141 template<MemoryOrdering Order
>
143 TestEnumWithOrdering()
145 Atomic
<EnumType
, Order
> atomic(EnumType_2
);
146 A(atomic
== EnumType_2
, "Atomic variable did not initialize");
150 result
= (atomic
= EnumType_3
);
151 A(atomic
== EnumType_3
, "Atomic assignment failed");
152 A(result
== EnumType_3
, "Atomic assignment returned the wrong value");
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");
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
>
173 TestBoolWithOrdering()
175 Atomic
<bool, Order
> atomic(false);
176 A(atomic
== false, "Atomic variable did not initialize");
180 result
= (atomic
= true);
181 A(atomic
== true, "Atomic assignment failed");
182 A(result
== true, "Atomic assignment returned the wrong value");
186 result
= atomic
.exchange(true);
187 A(atomic
== true, "Atomic exchange did not work");
188 A(result
== false, "Atomic exchange returned the wrong value");
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
>
205 TestTypeWithOrdering
<T
, SequentiallyConsistent
>();
206 TestTypeWithOrdering
<T
, ReleaseAcquire
>();
207 TestTypeWithOrdering
<T
, Relaxed
>();
214 TestPointerWithOrdering
<T
, SequentiallyConsistent
>();
215 TestPointerWithOrdering
<T
, ReleaseAcquire
>();
216 TestPointerWithOrdering
<T
, Relaxed
>();
222 TestEnumWithOrdering
<SequentiallyConsistent
>();
223 TestEnumWithOrdering
<ReleaseAcquire
>();
224 TestEnumWithOrdering
<Relaxed
>();
230 TestBoolWithOrdering
<SequentiallyConsistent
>();
231 TestBoolWithOrdering
<ReleaseAcquire
>();
232 TestBoolWithOrdering
<Relaxed
>();
240 TestType
<uint32_t>();
242 TestType
<intptr_t>();
243 TestType
<uintptr_t>();
245 TestPointer
<float>();
246 TestPointer
<uint16_t*>();
247 TestPointer
<uint32_t*>();