Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(402)

Side by Side Diff: crosstest/test_sync_atomic_main.cpp

Issue 362463002: Subzero: lower the rest of the atomic operations. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: rebase Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « crosstest/test_sync_atomic.def ('k') | src/IceInstX8632.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- subzero/crosstest/test_sync_atomic_main.cpp - Driver for tests -----===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Driver for cross testing atomic intrinsics, via the sync builtins.
11 //
12 //===----------------------------------------------------------------------===//
13
14 /* crosstest.py --test=test_sync_atomic.cpp --crosstest-bitcode=0 \
15 --driver=test_sync_atomic_main.cpp --prefix=Subzero_ \
16 --output=test_sync_atomic */
17
18 #include <pthread.h>
19 #include <stdint.h>
20
21 #include <cerrno>
22 #include <climits>
23 #include <cstdlib>
24 #include <cstring>
25 #include <iostream>
26
27 // Include test_sync_atomic.h twice - once normally, and once within the
28 // Subzero_ namespace, corresponding to the llc and Subzero translated
29 // object files, respectively.
30 #include "test_sync_atomic.h"
31 namespace Subzero_ {
32 #include "test_sync_atomic.h"
33 }
34
35 volatile uint64_t Values[] = {
36 0, 1, 0x7e,
37 0x7f, 0x80, 0x81,
38 0xfe, 0xff, 0x7ffe,
39 0x7fff, 0x8000, 0x8001,
40 0xfffe, 0xffff,
41 0x007fffff /*Max subnormal + */,
42 0x00800000 /*Min+ */, 0x7f7fffff /*Max+ */,
43 0x7f800000 /*+Inf*/, 0xff800000 /*-Inf*/,
44 0x7fa00000 /*SNaN*/, 0x7fc00000 /*QNaN*/,
45 0x7ffffffe, 0x7fffffff, 0x80000000,
46 0x80000001, 0xfffffffe, 0xffffffff,
47 0x100000000ll, 0x100000001ll,
48 0x000fffffffffffffll /*Max subnormal + */,
49 0x0010000000000000ll /*Min+ */,
50 0x7fefffffffffffffll /*Max+ */,
51 0x7ff0000000000000ll /*+Inf*/,
52 0xfff0000000000000ll /*-Inf*/,
53 0x7ff0000000000001ll /*SNaN*/,
54 0x7ff8000000000000ll /*QNaN*/,
55 0x7ffffffffffffffell, 0x7fffffffffffffffll, 0x8000000000000000ll,
56 0x8000000000000001ll, 0xfffffffffffffffell, 0xffffffffffffffffll };
57
58 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
59
60 struct {
61 volatile uint8_t l8;
62 volatile uint16_t l16;
63 volatile uint32_t l32;
64 volatile uint64_t l64;
65 } AtomicLocs;
66
67 template <typename Type>
68 void testAtomicRMW(volatile Type *AtomicLoc,
69 size_t &TotalTests, size_t &Passes, size_t &Failures) {
70 typedef Type (*FuncType)(bool, volatile Type*, Type);
71 static struct {
72 const char *Name;
73 FuncType FuncLlc;
74 FuncType FuncSz;
75 } Funcs[] = {
76 #define X(inst) \
77 { \
78 STR(inst), test_##inst, Subzero_::test_##inst \
79 }, \
80 { \
81 STR(inst) "_alloca", test_alloca_##inst, Subzero_::test_alloca_##inst \
82 }, \
83 { \
84 STR(inst) "_const", test_const_##inst, Subzero_::test_const_##inst \
85 },
86 RMWOP_TABLE
87 #undef X
88 };
89 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
90
91 for (size_t f = 0; f < NumFuncs; ++f) {
92 for (size_t i = 0; i < NumValues; ++i) {
93 Type Value1 = static_cast<Type>(Values[i]);
94 for (size_t j = 0; j < NumValues; ++j) {
95 Type Value2 = static_cast<Type>(Values[j]);
96 for (size_t k = 0; k < 2; ++k) {
97 bool fetch_first = k;
98 ++TotalTests;
99 *AtomicLoc = Value1;
100 Type ResultSz1 = Funcs[f].FuncSz(
101 fetch_first, AtomicLoc, Value2);
102 Type ResultSz2 = *AtomicLoc;
103 *AtomicLoc = Value1;
104 Type ResultLlc1 = Funcs[f].FuncLlc(
105 fetch_first, AtomicLoc, Value2);
106 Type ResultLlc2 = *AtomicLoc;
107 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) {
108 ++Passes;
109 } else {
110 ++Failures;
111 std::cout << "test_" << Funcs[f].Name
112 << (CHAR_BIT * sizeof(Type)) << "("
113 << static_cast<uint64_t>(Value1) << ", "
114 << static_cast<uint64_t>(Value2)
115 << "): sz1=" << static_cast<uint64_t>(ResultSz1)
116 << " llc1=" << static_cast<uint64_t>(ResultLlc1)
117 << " sz2=" << static_cast<uint64_t>(ResultSz2)
118 << " llc2=" << static_cast<uint64_t>(ResultLlc2)
119 << "\n";
120 }
121 }
122 }
123 }
124 }
125 }
126
127 template <typename Type>
128 void testValCompareAndSwap(volatile Type *AtomicLoc, size_t &TotalTests,
129 size_t &Passes, size_t &Failures) {
130 for (size_t i = 0; i < NumValues; ++i) {
131 Type Value1 = static_cast<Type>(Values[i]);
132 for (size_t j = 0; j < NumValues; ++j) {
133 Type Value2 = static_cast<Type>(Values[j]);
134 for (size_t f = 0; f < 2; ++f) {
135 bool flip = f;
136 ++TotalTests;
137 *AtomicLoc = Value1;
138 Type ResultSz1 = Subzero_::test_val_cmp_swap(
139 AtomicLoc, flip ? Value2 : Value1, Value2);
140 Type ResultSz2 = *AtomicLoc;
141 *AtomicLoc = Value1;
142 Type ResultLlc1 = test_val_cmp_swap(
143 AtomicLoc, flip ? Value2 : Value1, Value2);
144 Type ResultLlc2 = *AtomicLoc;
145 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) {
146 ++Passes;
147 } else {
148 ++Failures;
149 std::cout << "test_val_cmp_swap" << (CHAR_BIT * sizeof(Type)) << "("
150 << static_cast<uint64_t>(Value1) << ", "
151 << static_cast<uint64_t>(Value2)
152 << "): sz1=" << static_cast<uint64_t>(ResultSz1)
153 << " llc1=" << static_cast<uint64_t>(ResultLlc1)
154 << " sz2=" << static_cast<uint64_t>(ResultSz2)
155 << " llc2=" << static_cast<uint64_t>(ResultLlc2)
156 << "\n";
157 }
158 }
159 }
160 }
161 }
162
163 template <typename Type>
164 struct ThreadData {
165 Type (*FuncPtr)(bool, volatile Type*, Type);
166 bool Fetch;
167 volatile Type *Ptr;
168 Type Adjustment;
169 };
170
171 template <typename Type>
172 void *threadWrapper(void *Data) {
173 const size_t NumReps = 8000;
174 ThreadData<Type> *TData = reinterpret_cast<ThreadData<Type>*>(Data);
175 for (size_t i = 0; i < NumReps; ++i) {
176 (void)TData->FuncPtr(TData->Fetch, TData->Ptr, TData->Adjustment);
177 }
178 return NULL;
179 }
180
181 template <typename Type>
182 void testAtomicRMWThreads(volatile Type *AtomicLoc, size_t &TotalTests,
183 size_t &Passes, size_t &Failures) {
184 typedef Type (*FuncType)(bool, volatile Type*, Type);
185 static struct {
186 const char *Name;
187 FuncType FuncLlc;
188 FuncType FuncSz;
189 } Funcs[] = {
190 #define X(inst) \
191 { \
192 STR(inst), test_##inst, Subzero_::test_##inst \
193 }, \
194 { \
195 STR(inst) "_alloca", test_alloca_##inst, Subzero_::test_alloca_##inst \
196 },
197 RMWOP_TABLE
198 #undef X
199 };
200 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
201
202 // Just test a few values, otherwise it takes a *really* long time.
203 volatile uint64_t ValuesSubset[] = { 1, 0x7e, 0x000fffffffffffffffll };
204 const size_t NumValuesSubset = sizeof(ValuesSubset) / sizeof(*ValuesSubset);
205
206 for (size_t f = 0; f < NumFuncs; ++f) {
207 for (size_t i = 0; i < NumValuesSubset; ++i) {
208 Type Value1 = static_cast<Type>(ValuesSubset[i]);
209 for (size_t j = 0; j < NumValuesSubset; ++j) {
210 Type Value2 = static_cast<Type>(ValuesSubset[j]);
211 bool fetch_first = true;
212 ThreadData<Type> TDataSz = {
213 Funcs[f].FuncSz, fetch_first, AtomicLoc, Value2 };
214 ThreadData<Type> TDataLlc = {
215 Funcs[f].FuncLlc, fetch_first, AtomicLoc, Value2 };
216 ++TotalTests;
217 const size_t NumThreads = 4;
218 pthread_t t[NumThreads];
219
220 // Try N threads w/ just Llc.
221 *AtomicLoc = Value1;
222 for (size_t m = 0; m < NumThreads; ++m) {
223 pthread_create(&t[m], NULL, &threadWrapper<Type>,
224 reinterpret_cast<void *>(&TDataLlc));
225 }
226 for (size_t m = 0; m < NumThreads; ++m) {
227 pthread_join(t[m], NULL);
228 }
229 Type ResultLlc = *AtomicLoc;
230
231 // Try N threads w/ both Sz and Llc.
232 *AtomicLoc = Value1;
233 for (size_t m = 0; m < NumThreads; ++m) {
234 if (pthread_create(&t[m], NULL, &threadWrapper<Type>,
235 m % 2 == 0
236 ? reinterpret_cast<void *>(&TDataLlc)
237 : reinterpret_cast<void *>(&TDataSz)) != 0) {
238 ++Failures;
239 std::cout << "pthread_create failed w/ " << strerror(errno) << "\n";
240 abort();
241 }
242 }
243 for (size_t m = 0; m < NumThreads; ++m) {
244 if (pthread_join(t[m], NULL) != 0) {
245 ++Failures;
246 std::cout << "pthread_join failed w/ " << strerror(errno) << "\n";
247 abort();
248 }
249 }
250 Type ResultMixed = *AtomicLoc;
251
252 if (ResultLlc == ResultMixed) {
253 ++Passes;
254 } else {
255 ++Failures;
256 std::cout << "test_with_threads_" << Funcs[f].Name
257 << (8 * sizeof(Type)) << "("
258 << static_cast<uint64_t>(Value1) << ", "
259 << static_cast<uint64_t>(Value2)
260 << "): llc=" << static_cast<uint64_t>(ResultLlc)
261 << " mixed=" << static_cast<uint64_t>(ResultMixed)
262 << "\n";
263 }
264 }
265 }
266 }
267 }
268
269 int main(int argc, char **argv) {
270 size_t TotalTests = 0;
271 size_t Passes = 0;
272 size_t Failures = 0;
273
274 testAtomicRMW<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures);
275 testAtomicRMW<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, Failures);
276 testAtomicRMW<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, Failures);
277 testAtomicRMW<uint64_t>(&AtomicLocs.l64, TotalTests, Passes, Failures);
278 testValCompareAndSwap<uint8_t>(
279 &AtomicLocs.l8, TotalTests, Passes, Failures);
280 testValCompareAndSwap<uint16_t>(
281 &AtomicLocs.l16, TotalTests, Passes, Failures);
282 testValCompareAndSwap<uint32_t>(
283 &AtomicLocs.l32, TotalTests, Passes, Failures);
284 testValCompareAndSwap<uint64_t>(
285 &AtomicLocs.l64, TotalTests, Passes, Failures);
286 testAtomicRMWThreads<uint8_t>(
287 &AtomicLocs.l8, TotalTests, Passes, Failures);
288 testAtomicRMWThreads<uint16_t>(
289 &AtomicLocs.l16, TotalTests, Passes, Failures);
290 testAtomicRMWThreads<uint32_t>(
291 &AtomicLocs.l32, TotalTests, Passes, Failures);
292 testAtomicRMWThreads<uint64_t>(
293 &AtomicLocs.l64, TotalTests, Passes, Failures);
294
295 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
296 << " Failures=" << Failures << "\n";
297 return Failures;
298 }
OLDNEW
« no previous file with comments | « crosstest/test_sync_atomic.def ('k') | src/IceInstX8632.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698