Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/Assertions.h"
6 #include "mozilla/Atomics.h"
8 #include <stdint.h>
10 using mozilla::Atomic;
11 using mozilla::MemoryOrdering;
12 using mozilla::Relaxed;
13 using mozilla::ReleaseAcquire;
14 using mozilla::SequentiallyConsistent;
16 template <typename T, MemoryOrdering Order>
17 static void
18 TestTypeWithOrdering()
19 {
20 Atomic<T, Order> atomic(5);
21 MOZ_RELEASE_ASSERT(atomic == 5, "Atomic variable did not initialize");
23 // Test atomic increment
24 MOZ_RELEASE_ASSERT(++atomic == T(6), "Atomic increment did not work");
25 MOZ_RELEASE_ASSERT(atomic++ == T(6), "Atomic post-increment did not work");
26 MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic post-increment did not work");
28 // Test atomic decrement
29 MOZ_RELEASE_ASSERT(--atomic == 6, "Atomic decrement did not work");
30 MOZ_RELEASE_ASSERT(atomic-- == 6, "Atomic post-decrement did not work");
31 MOZ_RELEASE_ASSERT(atomic == 5, "Atomic post-decrement did not work");
33 // Test other arithmetic.
34 T result;
35 result = (atomic += T(5));
36 MOZ_RELEASE_ASSERT(atomic == T(10), "Atomic += did not work");
37 MOZ_RELEASE_ASSERT(result == T(10), "Atomic += returned the wrong value");
38 result = (atomic -= T(3));
39 MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic -= did not work");
40 MOZ_RELEASE_ASSERT(result == T(7), "Atomic -= returned the wrong value");
42 // Test assignment
43 result = (atomic = T(5));
44 MOZ_RELEASE_ASSERT(atomic == T(5), "Atomic assignment failed");
45 MOZ_RELEASE_ASSERT(result == T(5), "Atomic assignment returned the wrong value");
47 // Test logical operations.
48 result = (atomic ^= T(2));
49 MOZ_RELEASE_ASSERT(atomic == T(7), "Atomic ^= did not work");
50 MOZ_RELEASE_ASSERT(result == T(7), "Atomic ^= returned the wrong value");
51 result = (atomic ^= T(4));
52 MOZ_RELEASE_ASSERT(atomic == T(3), "Atomic ^= did not work");
53 MOZ_RELEASE_ASSERT(result == T(3), "Atomic ^= returned the wrong value");
54 result = (atomic |= T(8));
55 MOZ_RELEASE_ASSERT(atomic == T(11), "Atomic |= did not work");
56 MOZ_RELEASE_ASSERT(result == T(11), "Atomic |= returned the wrong value");
57 result = (atomic |= T(8));
58 MOZ_RELEASE_ASSERT(atomic == T(11), "Atomic |= did not work");
59 MOZ_RELEASE_ASSERT(result == T(11), "Atomic |= returned the wrong value");
60 result = (atomic &= T(12));
61 MOZ_RELEASE_ASSERT(atomic == T(8), "Atomic &= did not work");
62 MOZ_RELEASE_ASSERT(result == T(8), "Atomic &= returned the wrong value");
64 // Test exchange.
65 atomic = T(30);
66 result = atomic.exchange(42);
67 MOZ_RELEASE_ASSERT(atomic == T(42), "Atomic exchange did not work");
68 MOZ_RELEASE_ASSERT(result == T(30), "Atomic exchange returned the wrong value");
70 // Test CAS.
71 atomic = T(1);
72 bool boolResult = atomic.compareExchange(0, 2);
73 MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
74 MOZ_RELEASE_ASSERT(atomic == T(1), "CAS shouldn't have done anything.");
76 boolResult = atomic.compareExchange(1, 42);
77 MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
78 MOZ_RELEASE_ASSERT(atomic == T(42), "CAS should have changed atomic's value.");
79 }
81 template<typename T, MemoryOrdering Order>
82 static void
83 TestPointerWithOrdering()
84 {
85 T array1[10];
86 Atomic<T*, Order> atomic(array1);
87 MOZ_RELEASE_ASSERT(atomic == array1, "Atomic variable did not initialize");
89 // Test atomic increment
90 MOZ_RELEASE_ASSERT(++atomic == array1 + 1, "Atomic increment did not work");
91 MOZ_RELEASE_ASSERT(atomic++ == array1 + 1, "Atomic post-increment did not work");
92 MOZ_RELEASE_ASSERT(atomic == array1 + 2, "Atomic post-increment did not work");
94 // Test atomic decrement
95 MOZ_RELEASE_ASSERT(--atomic == array1 + 1, "Atomic decrement did not work");
96 MOZ_RELEASE_ASSERT(atomic-- == array1 + 1, "Atomic post-decrement did not work");
97 MOZ_RELEASE_ASSERT(atomic == array1, "Atomic post-decrement did not work");
99 // Test other arithmetic operations
100 T* result;
101 result = (atomic += 2);
102 MOZ_RELEASE_ASSERT(atomic == array1 + 2, "Atomic += did not work");
103 MOZ_RELEASE_ASSERT(result == array1 + 2, "Atomic += returned the wrong value");
104 result = (atomic -= 1);
105 MOZ_RELEASE_ASSERT(atomic == array1 + 1, "Atomic -= did not work");
106 MOZ_RELEASE_ASSERT(result == array1 + 1, "Atomic -= returned the wrong value");
108 // Test stores
109 result = (atomic = array1);
110 MOZ_RELEASE_ASSERT(atomic == array1, "Atomic assignment did not work");
111 MOZ_RELEASE_ASSERT(result == array1, "Atomic assignment returned the wrong value");
113 // Test exchange
114 atomic = array1 + 2;
115 result = atomic.exchange(array1);
116 MOZ_RELEASE_ASSERT(atomic == array1, "Atomic exchange did not work");
117 MOZ_RELEASE_ASSERT(result == array1 + 2, "Atomic exchange returned the wrong value");
119 atomic = array1;
120 bool boolResult = atomic.compareExchange(array1 + 1, array1 + 2);
121 MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
122 MOZ_RELEASE_ASSERT(atomic == array1, "CAS shouldn't have done anything.");
124 boolResult = atomic.compareExchange(array1, array1 + 3);
125 MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
126 MOZ_RELEASE_ASSERT(atomic == array1 + 3, "CAS should have changed atomic's value.");
127 }
129 enum EnumType {
130 EnumType_0 = 0,
131 EnumType_1 = 1,
132 EnumType_2 = 2,
133 EnumType_3 = 3
134 };
136 template<MemoryOrdering Order>
137 static void
138 TestEnumWithOrdering()
139 {
140 Atomic<EnumType, Order> atomic(EnumType_2);
141 MOZ_RELEASE_ASSERT(atomic == EnumType_2, "Atomic variable did not initialize");
143 // Test assignment
144 EnumType result;
145 result = (atomic = EnumType_3);
146 MOZ_RELEASE_ASSERT(atomic == EnumType_3, "Atomic assignment failed");
147 MOZ_RELEASE_ASSERT(result == EnumType_3, "Atomic assignment returned the wrong value");
149 // Test exchange.
150 atomic = EnumType_1;
151 result = atomic.exchange(EnumType_2);
152 MOZ_RELEASE_ASSERT(atomic == EnumType_2, "Atomic exchange did not work");
153 MOZ_RELEASE_ASSERT(result == EnumType_1, "Atomic exchange returned the wrong value");
155 // Test CAS.
156 atomic = EnumType_1;
157 bool boolResult = atomic.compareExchange(EnumType_0, EnumType_2);
158 MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
159 MOZ_RELEASE_ASSERT(atomic == EnumType_1, "CAS shouldn't have done anything.");
161 boolResult = atomic.compareExchange(EnumType_1, EnumType_3);
162 MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
163 MOZ_RELEASE_ASSERT(atomic == EnumType_3, "CAS should have changed atomic's value.");
164 }
166 template <MemoryOrdering Order>
167 static void
168 TestBoolWithOrdering()
169 {
170 Atomic<bool, Order> atomic(false);
171 MOZ_RELEASE_ASSERT(atomic == false, "Atomic variable did not initialize");
173 // Test assignment
174 bool result;
175 result = (atomic = true);
176 MOZ_RELEASE_ASSERT(atomic == true, "Atomic assignment failed");
177 MOZ_RELEASE_ASSERT(result == true, "Atomic assignment returned the wrong value");
179 // Test exchange.
180 atomic = false;
181 result = atomic.exchange(true);
182 MOZ_RELEASE_ASSERT(atomic == true, "Atomic exchange did not work");
183 MOZ_RELEASE_ASSERT(result == false, "Atomic exchange returned the wrong value");
185 // Test CAS.
186 atomic = false;
187 bool boolResult = atomic.compareExchange(true, false);
188 MOZ_RELEASE_ASSERT(!boolResult, "CAS should have returned false.");
189 MOZ_RELEASE_ASSERT(atomic == false, "CAS shouldn't have done anything.");
191 boolResult = atomic.compareExchange(false, true);
192 MOZ_RELEASE_ASSERT(boolResult, "CAS should have succeeded.");
193 MOZ_RELEASE_ASSERT(atomic == true, "CAS should have changed atomic's value.");
194 }
196 template <typename T>
197 static void
198 TestType()
199 {
200 TestTypeWithOrdering<T, SequentiallyConsistent>();
201 TestTypeWithOrdering<T, ReleaseAcquire>();
202 TestTypeWithOrdering<T, Relaxed>();
203 }
205 template<typename T>
206 static void
207 TestPointer()
208 {
209 TestPointerWithOrdering<T, SequentiallyConsistent>();
210 TestPointerWithOrdering<T, ReleaseAcquire>();
211 TestPointerWithOrdering<T, Relaxed>();
212 }
214 static void
215 TestEnum()
216 {
217 TestEnumWithOrdering<SequentiallyConsistent>();
218 TestEnumWithOrdering<ReleaseAcquire>();
219 TestEnumWithOrdering<Relaxed>();
220 }
222 static void
223 TestBool()
224 {
225 TestBoolWithOrdering<SequentiallyConsistent>();
226 TestBoolWithOrdering<ReleaseAcquire>();
227 TestBoolWithOrdering<Relaxed>();
228 }
230 int main()
231 {
232 TestType<uint32_t>();
233 TestType<int32_t>();
234 TestType<intptr_t>();
235 TestType<uintptr_t>();
236 TestPointer<int>();
237 TestPointer<float>();
238 TestPointer<uint16_t*>();
239 TestPointer<uint32_t*>();
240 TestEnum();
241 TestBool();
242 }