| OLD | NEW |
| 1 //===- subzero/crosstest/test_sync_atomic_main.cpp - Driver for tests -----===// | 1 //===- subzero/crosstest/test_sync_atomic_main.cpp - Driver for tests -----===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // Driver for cross testing atomic intrinsics, via the sync builtins. | 10 // Driver for cross testing atomic intrinsics, via the sync builtins. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include <cerrno> | 21 #include <cerrno> |
| 22 #include <climits> | 22 #include <climits> |
| 23 #include <cstdlib> | 23 #include <cstdlib> |
| 24 #include <cstring> | 24 #include <cstring> |
| 25 #include <iostream> | 25 #include <iostream> |
| 26 | 26 |
| 27 // Include test_sync_atomic.h twice - once normally, and once within the | 27 // Include test_sync_atomic.h twice - once normally, and once within the |
| 28 // Subzero_ namespace, corresponding to the llc and Subzero translated | 28 // Subzero_ namespace, corresponding to the llc and Subzero translated |
| 29 // object files, respectively. | 29 // object files, respectively. |
| 30 #include "test_sync_atomic.h" | 30 #include "test_sync_atomic.h" |
| 31 #include "xdefs.h" |
| 31 namespace Subzero_ { | 32 namespace Subzero_ { |
| 32 #include "test_sync_atomic.h" | 33 #include "test_sync_atomic.h" |
| 33 } | 34 } |
| 34 | 35 |
| 35 volatile uint64_t Values[] = { | 36 volatile uint64 Values[] = { |
| 36 0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff, 0x7ffe, 0x7fff, 0x8000, 0x8001, | 37 0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff, 0x7ffe, 0x7fff, 0x8000, 0x8001, |
| 37 0xfffe, 0xffff, 0x007fffff /*Max subnormal + */, 0x00800000 /*Min+ */, | 38 0xfffe, 0xffff, 0x007fffff /*Max subnormal + */, 0x00800000 /*Min+ */, |
| 38 0x7f7fffff /*Max+ */, 0x7f800000 /*+Inf*/, 0xff800000 /*-Inf*/, | 39 0x7f7fffff /*Max+ */, 0x7f800000 /*+Inf*/, 0xff800000 /*-Inf*/, |
| 39 0x7fa00000 /*SNaN*/, 0x7fc00000 /*QNaN*/, 0x7ffffffe, 0x7fffffff, | 40 0x7fa00000 /*SNaN*/, 0x7fc00000 /*QNaN*/, 0x7ffffffe, 0x7fffffff, |
| 40 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0x100000000ll, | 41 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0x100000000ll, |
| 41 0x100000001ll, 0x000fffffffffffffll /*Max subnormal + */, | 42 0x100000001ll, 0x000fffffffffffffll /*Max subnormal + */, |
| 42 0x0010000000000000ll /*Min+ */, 0x7fefffffffffffffll /*Max+ */, | 43 0x0010000000000000ll /*Min+ */, 0x7fefffffffffffffll /*Max+ */, |
| 43 0x7ff0000000000000ll /*+Inf*/, 0xfff0000000000000ll /*-Inf*/, | 44 0x7ff0000000000000ll /*+Inf*/, 0xfff0000000000000ll /*-Inf*/, |
| 44 0x7ff0000000000001ll /*SNaN*/, 0x7ff8000000000000ll /*QNaN*/, | 45 0x7ff0000000000001ll /*SNaN*/, 0x7ff8000000000000ll /*QNaN*/, |
| 45 0x7ffffffffffffffell, 0x7fffffffffffffffll, 0x8000000000000000ll, | 46 0x7ffffffffffffffell, 0x7fffffffffffffffll, 0x8000000000000000ll, |
| 46 0x8000000000000001ll, 0xfffffffffffffffell, 0xffffffffffffffffll}; | 47 0x8000000000000001ll, 0xfffffffffffffffell, 0xffffffffffffffffll}; |
| 47 | 48 |
| 48 const static size_t NumValues = sizeof(Values) / sizeof(*Values); | 49 const static size_t NumValues = sizeof(Values) / sizeof(*Values); |
| 49 | 50 |
| 50 struct { | 51 struct { |
| 51 volatile uint8_t l8; | 52 volatile uint8_t l8; |
| 52 volatile uint16_t l16; | 53 volatile uint16_t l16; |
| 53 volatile uint32_t l32; | 54 volatile uint32_t l32; |
| 54 volatile uint64_t l64; | 55 volatile uint64 l64; |
| 55 } AtomicLocs; | 56 } AtomicLocs; |
| 56 | 57 |
| 57 template <typename Type> | 58 template <typename Type> |
| 58 void testAtomicRMW(volatile Type *AtomicLoc, size_t &TotalTests, size_t &Passes, | 59 void testAtomicRMW(volatile Type *AtomicLoc, size_t &TotalTests, size_t &Passes, |
| 59 size_t &Failures) { | 60 size_t &Failures) { |
| 60 typedef Type (*FuncType)(bool, volatile Type *, Type); | 61 typedef Type (*FuncType)(bool, volatile Type *, Type); |
| 61 static struct { | 62 static struct { |
| 62 const char *Name; | 63 const char *Name; |
| 63 FuncType FuncLlc; | 64 FuncType FuncLlc; |
| 64 FuncType FuncSz; | 65 FuncType FuncSz; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 84 Type ResultSz1 = Funcs[f].FuncSz(fetch_first, AtomicLoc, Value2); | 85 Type ResultSz1 = Funcs[f].FuncSz(fetch_first, AtomicLoc, Value2); |
| 85 Type ResultSz2 = *AtomicLoc; | 86 Type ResultSz2 = *AtomicLoc; |
| 86 *AtomicLoc = Value1; | 87 *AtomicLoc = Value1; |
| 87 Type ResultLlc1 = Funcs[f].FuncLlc(fetch_first, AtomicLoc, Value2); | 88 Type ResultLlc1 = Funcs[f].FuncLlc(fetch_first, AtomicLoc, Value2); |
| 88 Type ResultLlc2 = *AtomicLoc; | 89 Type ResultLlc2 = *AtomicLoc; |
| 89 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) { | 90 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) { |
| 90 ++Passes; | 91 ++Passes; |
| 91 } else { | 92 } else { |
| 92 ++Failures; | 93 ++Failures; |
| 93 std::cout << "test_" << Funcs[f].Name << (CHAR_BIT * sizeof(Type)) | 94 std::cout << "test_" << Funcs[f].Name << (CHAR_BIT * sizeof(Type)) |
| 94 << "(" << static_cast<uint64_t>(Value1) << ", " | 95 << "(" << static_cast<uint64>(Value1) << ", " |
| 95 << static_cast<uint64_t>(Value2) | 96 << static_cast<uint64>(Value2) |
| 96 << "): sz1=" << static_cast<uint64_t>(ResultSz1) | 97 << "): sz1=" << static_cast<uint64>(ResultSz1) |
| 97 << " llc1=" << static_cast<uint64_t>(ResultLlc1) | 98 << " llc1=" << static_cast<uint64>(ResultLlc1) |
| 98 << " sz2=" << static_cast<uint64_t>(ResultSz2) | 99 << " sz2=" << static_cast<uint64>(ResultSz2) |
| 99 << " llc2=" << static_cast<uint64_t>(ResultLlc2) << "\n"; | 100 << " llc2=" << static_cast<uint64>(ResultLlc2) << "\n"; |
| 100 } | 101 } |
| 101 } | 102 } |
| 102 } | 103 } |
| 103 } | 104 } |
| 104 } | 105 } |
| 105 } | 106 } |
| 106 | 107 |
| 107 template <typename Type> | 108 template <typename Type> |
| 108 void testValCompareAndSwap(volatile Type *AtomicLoc, size_t &TotalTests, | 109 void testValCompareAndSwap(volatile Type *AtomicLoc, size_t &TotalTests, |
| 109 size_t &Passes, size_t &Failures) { | 110 size_t &Passes, size_t &Failures) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 130 Type ResultSz2 = *AtomicLoc; | 131 Type ResultSz2 = *AtomicLoc; |
| 131 *AtomicLoc = Value1; | 132 *AtomicLoc = Value1; |
| 132 Type ResultLlc1 = | 133 Type ResultLlc1 = |
| 133 Funcs[f].FuncLlc(AtomicLoc, flip ? Value2 : Value1, Value2); | 134 Funcs[f].FuncLlc(AtomicLoc, flip ? Value2 : Value1, Value2); |
| 134 Type ResultLlc2 = *AtomicLoc; | 135 Type ResultLlc2 = *AtomicLoc; |
| 135 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) { | 136 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) { |
| 136 ++Passes; | 137 ++Passes; |
| 137 } else { | 138 } else { |
| 138 ++Failures; | 139 ++Failures; |
| 139 std::cout << "test_" << Funcs[f].Name << (CHAR_BIT * sizeof(Type)) | 140 std::cout << "test_" << Funcs[f].Name << (CHAR_BIT * sizeof(Type)) |
| 140 << "(" << static_cast<uint64_t>(Value1) << ", " | 141 << "(" << static_cast<uint64>(Value1) << ", " |
| 141 << static_cast<uint64_t>(Value2) | 142 << static_cast<uint64>(Value2) |
| 142 << "): sz1=" << static_cast<uint64_t>(ResultSz1) | 143 << "): sz1=" << static_cast<uint64>(ResultSz1) |
| 143 << " llc1=" << static_cast<uint64_t>(ResultLlc1) | 144 << " llc1=" << static_cast<uint64>(ResultLlc1) |
| 144 << " sz2=" << static_cast<uint64_t>(ResultSz2) | 145 << " sz2=" << static_cast<uint64>(ResultSz2) |
| 145 << " llc2=" << static_cast<uint64_t>(ResultLlc2) << "\n"; | 146 << " llc2=" << static_cast<uint64>(ResultLlc2) << "\n"; |
| 146 } | 147 } |
| 147 } | 148 } |
| 148 } | 149 } |
| 149 } | 150 } |
| 150 } | 151 } |
| 151 } | 152 } |
| 152 | 153 |
| 153 template <typename Type> struct ThreadData { | 154 template <typename Type> struct ThreadData { |
| 154 Type (*FuncPtr)(bool, volatile Type *, Type); | 155 Type (*FuncPtr)(bool, volatile Type *, Type); |
| 155 bool Fetch; | 156 bool Fetch; |
| 156 volatile Type *Ptr; | 157 volatile Type *Ptr; |
| 157 Type Adjustment; | 158 Type Adjustment; |
| 158 }; | 159 }; |
| 159 | 160 |
| 160 template <typename Type> void *threadWrapper(void *Data) { | 161 template <typename Type> void *threadWrapper(void *Data) { |
| 161 const size_t NumReps = 8000; | 162 const size_t NumReps = 8000; |
| 162 ThreadData<Type> *TData = reinterpret_cast<ThreadData<Type> *>(Data); | 163 ThreadData<Type> *TData = reinterpret_cast<ThreadData<Type> *>(Data); |
| 163 for (size_t i = 0; i < NumReps; ++i) { | 164 for (size_t i = 0; i < NumReps; ++i) { |
| 164 (void)TData->FuncPtr(TData->Fetch, TData->Ptr, TData->Adjustment); | 165 (void)TData->FuncPtr(TData->Fetch, TData->Ptr, TData->Adjustment); |
| 165 } | 166 } |
| 166 return NULL; | 167 return NULL; |
| 167 } | 168 } |
| 168 | 169 |
| 170 #ifndef X8664_STACK_HACK |
| 171 void AllocStackForThread(uint32, pthread_attr_t *) {} |
| 172 #else // defined(X8664_STACK_HACK) |
| 173 void AllocStackForThread(uint32 m, pthread_attr_t *attr) { |
| 174 static const uint32_t ThreadStackBase = 0x60000000; |
| 175 static const uint32_t ThreadStackSize = 4 << 20; // 4MB. |
| 176 if (pthread_attr_setstack( |
| 177 attr, xAllocStack(ThreadStackBase - 2 * m * ThreadStackSize, |
| 178 ThreadStackSize), |
| 179 ThreadStackSize) != 0) { |
| 180 std::cout << "pthread_attr_setstack: " << strerror(errno) << "\n"; |
| 181 abort(); |
| 182 } |
| 183 } |
| 184 #endif // X8664_STACK_HACK |
| 185 |
| 169 template <typename Type> | 186 template <typename Type> |
| 170 void testAtomicRMWThreads(volatile Type *AtomicLoc, size_t &TotalTests, | 187 void testAtomicRMWThreads(volatile Type *AtomicLoc, size_t &TotalTests, |
| 171 size_t &Passes, size_t &Failures) { | 188 size_t &Passes, size_t &Failures) { |
| 172 typedef Type (*FuncType)(bool, volatile Type *, Type); | 189 typedef Type (*FuncType)(bool, volatile Type *, Type); |
| 173 static struct { | 190 static struct { |
| 174 const char *Name; | 191 const char *Name; |
| 175 FuncType FuncLlc; | 192 FuncType FuncLlc; |
| 176 FuncType FuncSz; | 193 FuncType FuncSz; |
| 177 } Funcs[] = { | 194 } Funcs[] = { |
| 178 #define X(inst) \ | 195 #define X(inst) \ |
| 179 { STR(inst), test_##inst, Subzero_::test_##inst } \ | 196 { STR(inst), test_##inst, Subzero_::test_##inst } \ |
| 180 , {STR(inst) "_alloca", test_alloca_##inst, Subzero_::test_alloca_##inst}, | 197 , {STR(inst) "_alloca", test_alloca_##inst, Subzero_::test_alloca_##inst}, |
| 181 RMWOP_TABLE | 198 RMWOP_TABLE |
| 182 #undef X | 199 #undef X |
| 183 }; | 200 }; |
| 184 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); | 201 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); |
| 185 | 202 |
| 186 // Just test a few values, otherwise it takes a *really* long time. | 203 // Just test a few values, otherwise it takes a *really* long time. |
| 187 volatile uint64_t ValuesSubset[] = {1, 0x7e, 0x000fffffffffffffffll}; | 204 volatile uint64 ValuesSubset[] = {1, 0x7e, 0x000fffffffffffffffll}; |
| 188 const size_t NumValuesSubset = sizeof(ValuesSubset) / sizeof(*ValuesSubset); | 205 const size_t NumValuesSubset = sizeof(ValuesSubset) / sizeof(*ValuesSubset); |
| 189 | 206 |
| 190 for (size_t f = 0; f < NumFuncs; ++f) { | 207 for (size_t f = 0; f < NumFuncs; ++f) { |
| 191 for (size_t i = 0; i < NumValuesSubset; ++i) { | 208 for (size_t i = 0; i < NumValuesSubset; ++i) { |
| 192 Type Value1 = static_cast<Type>(ValuesSubset[i]); | 209 Type Value1 = static_cast<Type>(ValuesSubset[i]); |
| 193 for (size_t j = 0; j < NumValuesSubset; ++j) { | 210 for (size_t j = 0; j < NumValuesSubset; ++j) { |
| 194 Type Value2 = static_cast<Type>(ValuesSubset[j]); | 211 Type Value2 = static_cast<Type>(ValuesSubset[j]); |
| 195 bool fetch_first = true; | 212 bool fetch_first = true; |
| 196 ThreadData<Type> TDataSz = {Funcs[f].FuncSz, fetch_first, AtomicLoc, | 213 ThreadData<Type> TDataSz = {Funcs[f].FuncSz, fetch_first, AtomicLoc, |
| 197 Value2}; | 214 Value2}; |
| 198 ThreadData<Type> TDataLlc = {Funcs[f].FuncLlc, fetch_first, AtomicLoc, | 215 ThreadData<Type> TDataLlc = {Funcs[f].FuncLlc, fetch_first, AtomicLoc, |
| 199 Value2}; | 216 Value2}; |
| 200 ++TotalTests; | 217 ++TotalTests; |
| 201 const size_t NumThreads = 4; | 218 const size_t NumThreads = 4; |
| 202 pthread_t t[NumThreads]; | 219 pthread_t t[NumThreads]; |
| 220 pthread_attr_t attr[NumThreads]; |
| 203 | 221 |
| 204 // Try N threads w/ just Llc. | 222 // Try N threads w/ just Llc. |
| 205 *AtomicLoc = Value1; | 223 *AtomicLoc = Value1; |
| 206 for (size_t m = 0; m < NumThreads; ++m) { | 224 for (size_t m = 0; m < NumThreads; ++m) { |
| 207 pthread_create(&t[m], NULL, &threadWrapper<Type>, | 225 pthread_attr_init(&attr[m]); |
| 208 reinterpret_cast<void *>(&TDataLlc)); | 226 AllocStackForThread(m, &attr[m]); |
| 227 if (pthread_create(&t[m], &attr[m], &threadWrapper<Type>, |
| 228 reinterpret_cast<void *>(&TDataLlc)) != 0) { |
| 229 std::cout << "pthread_create failed w/ " << strerror(errno) << "\n"; |
| 230 abort(); |
| 231 } |
| 209 } | 232 } |
| 210 for (size_t m = 0; m < NumThreads; ++m) { | 233 for (size_t m = 0; m < NumThreads; ++m) { |
| 211 pthread_join(t[m], NULL); | 234 pthread_join(t[m], NULL); |
| 212 } | 235 } |
| 213 Type ResultLlc = *AtomicLoc; | 236 Type ResultLlc = *AtomicLoc; |
| 214 | 237 |
| 215 // Try N threads w/ both Sz and Llc. | 238 // Try N threads w/ both Sz and Llc. |
| 216 *AtomicLoc = Value1; | 239 *AtomicLoc = Value1; |
| 217 for (size_t m = 0; m < NumThreads; ++m) { | 240 for (size_t m = 0; m < NumThreads; ++m) { |
| 218 if (pthread_create(&t[m], NULL, &threadWrapper<Type>, | 241 pthread_attr_init(&attr[m]); |
| 242 AllocStackForThread(m, &attr[m]); |
| 243 if (pthread_create(&t[m], &attr[m], &threadWrapper<Type>, |
| 219 m % 2 == 0 | 244 m % 2 == 0 |
| 220 ? reinterpret_cast<void *>(&TDataLlc) | 245 ? reinterpret_cast<void *>(&TDataLlc) |
| 221 : reinterpret_cast<void *>(&TDataSz)) != 0) { | 246 : reinterpret_cast<void *>(&TDataSz)) != 0) { |
| 222 ++Failures; | 247 ++Failures; |
| 223 std::cout << "pthread_create failed w/ " << strerror(errno) << "\n"; | 248 std::cout << "pthread_create failed w/ " << strerror(errno) << "\n"; |
| 224 abort(); | 249 abort(); |
| 225 } | 250 } |
| 226 } | 251 } |
| 227 for (size_t m = 0; m < NumThreads; ++m) { | 252 for (size_t m = 0; m < NumThreads; ++m) { |
| 228 if (pthread_join(t[m], NULL) != 0) { | 253 if (pthread_join(t[m], NULL) != 0) { |
| 229 ++Failures; | 254 ++Failures; |
| 230 std::cout << "pthread_join failed w/ " << strerror(errno) << "\n"; | 255 std::cout << "pthread_join failed w/ " << strerror(errno) << "\n"; |
| 231 abort(); | 256 abort(); |
| 232 } | 257 } |
| 233 } | 258 } |
| 234 Type ResultMixed = *AtomicLoc; | 259 Type ResultMixed = *AtomicLoc; |
| 235 | 260 |
| 236 if (ResultLlc == ResultMixed) { | 261 if (ResultLlc == ResultMixed) { |
| 237 ++Passes; | 262 ++Passes; |
| 238 } else { | 263 } else { |
| 239 ++Failures; | 264 ++Failures; |
| 240 std::cout << "test_with_threads_" << Funcs[f].Name | 265 std::cout << "test_with_threads_" << Funcs[f].Name |
| 241 << (8 * sizeof(Type)) << "(" | 266 << (8 * sizeof(Type)) << "(" << static_cast<uint64>(Value1) |
| 242 << static_cast<uint64_t>(Value1) << ", " | 267 << ", " << static_cast<uint64>(Value2) |
| 243 << static_cast<uint64_t>(Value2) | 268 << "): llc=" << static_cast<uint64>(ResultLlc) |
| 244 << "): llc=" << static_cast<uint64_t>(ResultLlc) | 269 << " mixed=" << static_cast<uint64>(ResultMixed) << "\n"; |
| 245 << " mixed=" << static_cast<uint64_t>(ResultMixed) << "\n"; | |
| 246 } | 270 } |
| 247 } | 271 } |
| 248 } | 272 } |
| 249 } | 273 } |
| 250 } | 274 } |
| 251 | 275 |
| 252 int main(int argc, char **argv) { | 276 #ifdef X8664_STACK_HACK |
| 277 extern "C" int wrapped_main(int argc, char *argv[]) { |
| 278 #else // !defined(X8664_STACK_HACK) |
| 279 int main(int argc, char *argv[]) { |
| 280 #endif // X8664_STACK_HACK |
| 253 size_t TotalTests = 0; | 281 size_t TotalTests = 0; |
| 254 size_t Passes = 0; | 282 size_t Passes = 0; |
| 255 size_t Failures = 0; | 283 size_t Failures = 0; |
| 256 | 284 |
| 257 testAtomicRMW<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures); | 285 testAtomicRMW<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures); |
| 258 testAtomicRMW<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, Failures); | 286 testAtomicRMW<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, Failures); |
| 259 testAtomicRMW<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, Failures); | 287 testAtomicRMW<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, Failures); |
| 260 testAtomicRMW<uint64_t>(&AtomicLocs.l64, TotalTests, Passes, Failures); | 288 testAtomicRMW<uint64>(&AtomicLocs.l64, TotalTests, Passes, Failures); |
| 261 testValCompareAndSwap<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures); | 289 testValCompareAndSwap<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures); |
| 262 testValCompareAndSwap<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, | 290 testValCompareAndSwap<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, |
| 263 Failures); | 291 Failures); |
| 264 testValCompareAndSwap<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, | 292 testValCompareAndSwap<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, |
| 265 Failures); | 293 Failures); |
| 266 testValCompareAndSwap<uint64_t>(&AtomicLocs.l64, TotalTests, Passes, | 294 testValCompareAndSwap<uint64>(&AtomicLocs.l64, TotalTests, Passes, Failures); |
| 267 Failures); | |
| 268 testAtomicRMWThreads<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures); | 295 testAtomicRMWThreads<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures); |
| 269 testAtomicRMWThreads<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, Failures); | 296 testAtomicRMWThreads<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, Failures); |
| 270 testAtomicRMWThreads<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, Failures); | 297 testAtomicRMWThreads<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, Failures); |
| 271 testAtomicRMWThreads<uint64_t>(&AtomicLocs.l64, TotalTests, Passes, Failures); | 298 testAtomicRMWThreads<uint64>(&AtomicLocs.l64, TotalTests, Passes, Failures); |
| 272 | 299 |
| 273 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes | 300 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes |
| 274 << " Failures=" << Failures << "\n"; | 301 << " Failures=" << Failures << "\n"; |
| 275 return Failures; | 302 return Failures; |
| 276 } | 303 } |
| OLD | NEW |