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

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: comment cleanup 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
OLDNEW
(Empty)
1 /* crosstest.py --test=test_sync_atomic.cpp --driver=test_sync_atomic_main.cpp \
2 --prefix=Subzero_ --output=test_sync_atomic */
Jim Stichnoth 2014/07/08 04:50:19 Add --crosstest-bitcode=0 ?
jvoung (off chromium) 2014/07/08 18:14:06 Done.
3
4 #include <pthread.h>
5 #include <stdint.h>
6
7 #include <cstdlib>
8 #include <iostream>
9
10 // Include test_sync_atomic.h twice - once normally, and once within the
11 // Subzero_ namespace, corresponding to the llc and Subzero translated
12 // object files, respectively.
13 #include "test_sync_atomic.h"
14 namespace Subzero_ {
15 #include "test_sync_atomic.h"
16 }
17
18 volatile uint64_t Values[] = {
19 0, 1, 0x7e,
20 0x7f, 0x80, 0x81,
21 0xfe, 0xff, 0x7ffe,
22 0x7fff, 0x8000, 0x8001,
23 0xfffe, 0xffff,
24 0x007fffff /*Max subnormal + */,
25 0x00800000 /*Min+ */, 0x7f7fffff /*Max+ */,
26 0x7f800000 /*+Inf*/, 0xff800000 /*-Inf*/,
27 0x7fa00000 /*SNaN*/, 0x7fc00000 /*QNaN*/,
28 0x7ffffffe, 0x7fffffff, 0x80000000,
29 0x80000001, 0xfffffffe, 0xffffffff,
30 0x100000000ll, 0x100000001ll,
31 0x000fffffffffffffll /*Max subnormal + */,
32 0x0010000000000000ll /*Min+ */,
33 0x7fefffffffffffffll /*Max+ */,
34 0x7ff0000000000000ll /*+Inf*/,
35 0xfff0000000000000ll /*-Inf*/,
36 0x7ff0000000000001ll /*SNaN*/,
37 0x7ff8000000000000ll /*QNaN*/,
38 0x7ffffffffffffffell, 0x7fffffffffffffffll, 0x8000000000000000ll,
39 0x8000000000000001ll, 0xfffffffffffffffell, 0xffffffffffffffffll };
40
41 const static size_t NumValues = sizeof(Values) / sizeof(*Values);
42
43 struct AtomicLocs {
Jim Stichnoth 2014/07/08 04:50:19 Maybe change to: struct { ... } AtomicLocs; sinc
jvoung (off chromium) 2014/07/08 18:14:06 Done.
44 volatile uint8_t l8;
45 volatile uint16_t l16;
46 volatile uint32_t l32;
47 volatile uint64_t l64;
48 };
49
50 AtomicLocs AtomicLocs;
51
52 template <typename Type>
53 void testAtomicRMW(volatile Type *AtomicLoc,
54 size_t &TotalTests, size_t &Passes, size_t &Failures) {
55 typedef Type (*FuncType)(bool, volatile Type*, Type);
56 static struct {
57 const char *Name;
58 FuncType FuncLlc;
59 FuncType FuncSz;
60 } Funcs[] = {
61 #define X(inst) \
62 { \
63 STR(inst), test_##inst, Subzero_::test_##inst \
64 }, \
65 { \
66 STR(inst) "_alloca", test_alloca_##inst, Subzero_::test_alloca_##inst \
67 }, \
68 { \
69 STR(inst) "_const", test_const_##inst, Subzero_::test_const_##inst \
70 } \
Jim Stichnoth 2014/07/08 04:50:19 Put comma on the same line, as above?
jvoung (off chromium) 2014/07/08 18:14:07 Done.
71 ,
72 RMWOP_TABLE
73 #undef X
74 };
75 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
76
77 for (size_t f = 0; f < NumFuncs; ++f) {
78 for (size_t i = 0; i < NumValues; ++i) {
79 Type Value1 = static_cast<Type>(Values[i]);
80 for (size_t j = 0; j < NumValues; ++j) {
81 Type Value2 = static_cast<Type>(Values[j]);
82 for (size_t k = 0; k < 2; ++k) {
83 bool fetch_first = k;
84 ++TotalTests;
85 *AtomicLoc = Value1;
86 Type ResultSz1 = Funcs[f].FuncSz(
87 fetch_first, AtomicLoc, Value2);
88 Type ResultSz2 = *AtomicLoc;
89 *AtomicLoc = Value1;
90 Type ResultLlc1 = Funcs[f].FuncLlc(
91 fetch_first, AtomicLoc, Value2);
92 Type ResultLlc2 = *AtomicLoc;
93 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) {
94 ++Passes;
95 } else {
96 ++Failures;
97 std::cout << "test_" << Funcs[f].Name
98 << (8 * sizeof(Type)) << "("
99 << static_cast<uint64_t>(Value1) << ", "
100 << static_cast<uint64_t>(Value2)
101 << "): sz1=" << static_cast<uint64_t>(ResultSz1)
102 << " llc1=" << static_cast<uint64_t>(ResultLlc1)
103 << " sz2=" << static_cast<uint64_t>(ResultSz2)
104 << " llc2=" << static_cast<uint64_t>(ResultLlc2)
105 << std::endl;
106 }
107 }
108 }
109 }
110 }
111 }
112
113 template <typename Type>
114 void testValCompareAndSwap(volatile Type *AtomicLoc, size_t &TotalTests,
115 size_t &Passes, size_t &Failures) {
116 for (size_t i = 0; i < NumValues; ++i) {
117 Type Value1 = static_cast<Type>(Values[i]);
118 for (size_t j = 0; j < NumValues; ++j) {
119 Type Value2 = static_cast<Type>(Values[j]);
120 for (size_t f = 0; f < 2; ++f) {
121 bool flip = f;
122 ++TotalTests;
123 *AtomicLoc = Value1;
124 Type ResultSz1 = Subzero_::test_val_cmp_swap(
125 AtomicLoc, flip ? Value2 : Value1, Value2);
126 Type ResultSz2 = *AtomicLoc;
127 *AtomicLoc = Value1;
128 Type ResultLlc1 = test_val_cmp_swap(
129 AtomicLoc, flip ? Value2 : Value1, Value2);
130 Type ResultLlc2 = *AtomicLoc;
131 if (ResultSz1 == ResultLlc1 && ResultSz2 == ResultLlc2) {
132 ++Passes;
133 } else {
134 ++Failures;
135 std::cout << "test_val_cmp_swap" << (8 * sizeof(Type)) << "("
136 << static_cast<uint64_t>(Value1) << ", "
137 << static_cast<uint64_t>(Value2)
138 << "): sz1=" << static_cast<uint64_t>(ResultSz1)
139 << " llc1=" << static_cast<uint64_t>(ResultLlc1)
140 << " sz2=" << static_cast<uint64_t>(ResultSz2)
141 << " llc2=" << static_cast<uint64_t>(ResultLlc2)
142 << std::endl;
143 }
144 }
145 }
146 }
147 }
148
149 template <typename Type>
150 struct ThreadData {
151 Type (*FuncPtr)(bool, volatile Type*, Type);
152 bool Fetch;
153 volatile Type *Ptr;
154 Type Adjustment;
155 };
156
157 template <typename Type>
158 void *threadWrapper(void *Data) {
159 const size_t NumReps = 8000;
160 ThreadData<Type> *TData = reinterpret_cast<ThreadData<Type>*>(Data);
161 for (size_t i = 0; i < NumReps; ++i) {
162 (void)TData->FuncPtr(TData->Fetch, TData->Ptr, TData->Adjustment);
163 }
164 return NULL;
165 }
166
167 template <typename Type>
168 void testAtomicRMWThreads(volatile Type *AtomicLoc, size_t &TotalTests,
169 size_t &Passes, size_t &Failures) {
170 typedef Type (*FuncType)(bool, volatile Type*, Type);
171 static struct {
172 const char *Name;
173 FuncType FuncLlc;
174 FuncType FuncSz;
175 } Funcs[] = {
176 #define X(inst) \
177 { \
178 STR(inst), test_##inst, Subzero_::test_##inst \
179 }, \
180 { \
181 STR(inst) "_alloca", test_alloca_##inst, Subzero_::test_alloca_##inst \
182 },
183 RMWOP_TABLE
184 #undef X
185 };
186 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
187
188 // Just test a few values, otherwise it takes a *really* long time.
189 volatile uint64_t ValuesSubset[] = { 1, 0x7e, 0x80 };
190 const size_t NumValuesSubset = sizeof(ValuesSubset) / sizeof(*ValuesSubset);
191
192 for (size_t f = 0; f < NumFuncs; ++f) {
193 for (size_t i = 0; i < NumValuesSubset; ++i) {
194 Type Value1 = static_cast<Type>(ValuesSubset[i]);
195 for (size_t j = 0; j < NumValuesSubset; ++j) {
196 Type Value2 = static_cast<Type>(ValuesSubset[j]);
197 bool fetch_first = true;
198 ThreadData<Type> TDataSz = {
199 Funcs[f].FuncSz, fetch_first, AtomicLoc, Value2 };
200 ThreadData<Type> TDataLlc = {
201 Funcs[f].FuncLlc, fetch_first, AtomicLoc, Value2 };
202 ++TotalTests;
203 const size_t num_threads = 4;
204 pthread_t t[num_threads];
205
206 // Try N threads w/ just Llc.
207 *AtomicLoc = Value1;
208 for (size_t m = 0; m < num_threads; ++m) {
209 pthread_create(&t[m], NULL, &threadWrapper<Type>,
210 reinterpret_cast<void *>(&TDataLlc));
211 }
212 for (size_t m = 0; m < num_threads; ++m) {
213 pthread_join(t[m], NULL);
214 }
215 Type ResultLlc = *AtomicLoc;
216
217 // Try N threads w/ both Sz and Llc.
218 *AtomicLoc = Value1;
219 for (size_t m = 0; m < num_threads; ++m) {
220 pthread_create(&t[m], NULL, &threadWrapper<Type>,
221 m % 2 == 0
222 ? reinterpret_cast<void *>(&TDataLlc)
223 : reinterpret_cast<void *>(&TDataSz));
224 }
225 for (size_t m = 0; m < num_threads; ++m) {
226 pthread_join(t[m], NULL);
227 }
228 Type ResultMixed = *AtomicLoc;
229
230 if (ResultLlc == ResultMixed) {
231 ++Passes;
232 } else {
233 ++Failures;
234 std::cout << "test_with_threads_" << Funcs[f].Name
235 << (8 * sizeof(Type)) << "("
236 << static_cast<uint64_t>(Value1) << ", "
237 << static_cast<uint64_t>(Value2)
238 << "): llc=" << static_cast<uint64_t>(ResultLlc)
239 << " mixed=" << static_cast<uint64_t>(ResultMixed)
240 << std::endl;
241 }
242 }
243 }
244 }
245 }
246
247 int main(int argc, char **argv) {
248 size_t TotalTests = 0;
249 size_t Passes = 0;
250 size_t Failures = 0;
251
252 testAtomicRMW<uint8_t>(&AtomicLocs.l8, TotalTests, Passes, Failures);
253 testAtomicRMW<uint16_t>(&AtomicLocs.l16, TotalTests, Passes, Failures);
254 testAtomicRMW<uint32_t>(&AtomicLocs.l32, TotalTests, Passes, Failures);
255 testAtomicRMW<uint64_t>(&AtomicLocs.l64, TotalTests, Passes, Failures);
256 testValCompareAndSwap<uint8_t>(
257 &AtomicLocs.l8, TotalTests, Passes, Failures);
258 testValCompareAndSwap<uint16_t>(
259 &AtomicLocs.l16, TotalTests, Passes, Failures);
260 testValCompareAndSwap<uint32_t>(
261 &AtomicLocs.l32, TotalTests, Passes, Failures);
262 testValCompareAndSwap<uint64_t>(
263 &AtomicLocs.l64, TotalTests, Passes, Failures);
264 testAtomicRMWThreads<uint8_t>(
265 &AtomicLocs.l8, TotalTests, Passes, Failures);
266 testAtomicRMWThreads<uint16_t>(
267 &AtomicLocs.l16, TotalTests, Passes, Failures);
268 testAtomicRMWThreads<uint32_t>(
269 &AtomicLocs.l32, TotalTests, Passes, Failures);
270 testAtomicRMWThreads<uint64_t>(
271 &AtomicLocs.l64, TotalTests, Passes, Failures);
272
273 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
274 << " Failures=" << Failures << "\n";
275 return Failures;
276 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698