Merge ~dirk.zimoch/epics-base:libCom/vxWorks5 into ~epics-core/epics-base/+git/epics-base:7.0
- Git
- lp:~dirk.zimoch/epics-base
- libCom/vxWorks5
- Merge into 7.0
Proposed by
Dirk Zimoch
Status: | Rejected |
---|---|
Rejected by: | Andrew Johnson |
Proposed branch: | ~dirk.zimoch/epics-base:libCom/vxWorks5 |
Merge into: | ~epics-core/epics-base/+git/epics-base:7.0 |
Diff against target: |
437 lines (+431/-0) (has conflicts) 1 file modified
test/epicsAtomicTest.cpp (+431/-0) Conflict in test/epicsAtomicTest.cpp |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
EPICS Core Developers | Pending | ||
Review via email: mp+355498@code.launchpad.net |
Commit message
Description of the change
This branch fixes a compiler problem in test code on vxWorks 5 systems.
To post a comment you must log in.
Revision history for this message
Andrew Johnson (anj) wrote : | # |
Unmerged commits
- 2de6be2... by Dirk Zimoch
-
Fix strange effects with gcc 2.96:
using <namespace::function> ; seems not to work but
using namespace <namespace>; works
Also 'add' only works with explicit namespace. Why?
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/test/epicsAtomicTest.cpp b/test/epicsAtomicTest.cpp |
2 | new file mode 100644 |
3 | index 0000000..9db79de |
4 | --- /dev/null |
5 | +++ b/test/epicsAtomicTest.cpp |
6 | @@ -0,0 +1,431 @@ |
7 | +<<<<<<< test/epicsAtomicTest.cpp |
8 | +======= |
9 | + |
10 | +#include <stdlib.h> |
11 | +#include <assert.h> |
12 | + |
13 | +#include "epicsAtomic.h" |
14 | +#include "epicsTime.h" |
15 | +#include "epicsThread.h" |
16 | +#include "epicsUnitTest.h" |
17 | +#include "testMain.h" |
18 | + |
19 | +using namespace epics::atomic; |
20 | + |
21 | +namespace { |
22 | + |
23 | +template < class T > |
24 | +struct TestDataIncrDecr { |
25 | + T m_testValue; |
26 | + size_t m_testIterations; |
27 | +}; |
28 | + |
29 | +template < class T > |
30 | +struct TestDataAddSub { |
31 | + T m_testValue; |
32 | + size_t m_testIterations; |
33 | + static const T delta = 17; |
34 | +}; |
35 | + |
36 | +template < class T > |
37 | +static void incr ( void *arg ) |
38 | +{ |
39 | + using epics::atomic::increment; |
40 | + TestDataIncrDecr < T > * const pTestData = |
41 | + reinterpret_cast < TestDataIncrDecr < T > * > ( arg ); |
42 | + increment ( pTestData->m_testValue ); |
43 | + increment ( pTestData->m_testIterations ); |
44 | +} |
45 | + |
46 | +template < class T > |
47 | +static void decr ( void *arg ) |
48 | +{ |
49 | + using epics::atomic::decrement; |
50 | + using epics::atomic::increment; |
51 | + TestDataIncrDecr < T > * const pTestData = |
52 | + reinterpret_cast < TestDataIncrDecr < T > * > ( arg ); |
53 | + decrement ( pTestData->m_testValue ); |
54 | + increment ( pTestData->m_testIterations ); |
55 | +} |
56 | + |
57 | + |
58 | +template < class T > |
59 | +static void add ( void *arg ) |
60 | +{ |
61 | + using epics::atomic::add; |
62 | + using epics::atomic::increment; |
63 | + TestDataAddSub < T > * const pTestData = |
64 | + reinterpret_cast < TestDataAddSub < T > * > ( arg ); |
65 | + epics::atomic::add ( pTestData->m_testValue, TestDataAddSub < T > :: delta ); |
66 | + increment ( pTestData->m_testIterations ); |
67 | +} |
68 | + |
69 | +template < class T > |
70 | +static void sub ( void *arg ) |
71 | +{ |
72 | + using epics::atomic::subtract; |
73 | + using epics::atomic::increment; |
74 | + TestDataAddSub < T > * const pTestData = |
75 | + reinterpret_cast < TestDataAddSub < T > * > ( arg ); |
76 | + subtract ( pTestData->m_testValue, TestDataAddSub < T > :: delta ); |
77 | + increment ( pTestData->m_testIterations ); |
78 | +} |
79 | + |
80 | +template < class T > |
81 | +struct TestDataCAS { |
82 | + T m_testValue; |
83 | + size_t m_testIterationsSet; |
84 | + size_t m_testIterationsNotSet; |
85 | +}; |
86 | + |
87 | +template < class T > |
88 | +static T trueValue (); |
89 | +template < class T > |
90 | +static T falseValue (); |
91 | + |
92 | +// int |
93 | +template <> |
94 | +inline int trueValue < int > () { return 1; } |
95 | + |
96 | +template <> |
97 | +inline int falseValue < int > () { return 0; } |
98 | + |
99 | +// size_t |
100 | +template <> |
101 | +inline size_t trueValue < size_t > () { return 1u; } |
102 | + |
103 | +template <> |
104 | +inline size_t falseValue < size_t > () { return 0u; } |
105 | + |
106 | +// EpicsAtomicPtrT |
107 | +template <> |
108 | +inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > () |
109 | +{ static char c; return & c; } |
110 | + |
111 | +template <> |
112 | +inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > () |
113 | +{ return 0u; } |
114 | + |
115 | +template < class T > |
116 | +static void cas ( void *arg ) |
117 | +{ |
118 | + using epics::atomic::set; |
119 | + using epics::atomic::increment; |
120 | + using epics::atomic::decrement; |
121 | + using epics::atomic::compareAndSwap; |
122 | + |
123 | + TestDataCAS < T > * const pTestData = |
124 | + reinterpret_cast < TestDataCAS < T > * > ( arg ); |
125 | + /* |
126 | + * intentionally waste cpu and maximize |
127 | + * contention for the shared data |
128 | + */ |
129 | + increment ( pTestData->m_testIterationsNotSet ); |
130 | + while ( ! compareAndSwap ( pTestData->m_testValue, |
131 | + falseValue < T > (), |
132 | + trueValue < T > () ) ) { |
133 | + } |
134 | + decrement ( pTestData->m_testIterationsNotSet ); |
135 | + set ( pTestData->m_testValue, falseValue < T > () ); |
136 | + increment ( pTestData->m_testIterationsSet ); |
137 | +} |
138 | + |
139 | +template < class T > |
140 | +void testIncrDecr () |
141 | +{ |
142 | + using epics::atomic::set; |
143 | + using epics::atomic::get; |
144 | + |
145 | + static const size_t N = 90; |
146 | + static const T NT = static_cast < T > ( N ); |
147 | + |
148 | + const unsigned int stackSize = |
149 | + epicsThreadGetStackSize ( epicsThreadStackSmall ); |
150 | + |
151 | + TestDataIncrDecr < T > testData = { 0, N }; |
152 | + set ( testData.m_testValue, NT ); |
153 | + testOk ( get ( testData.m_testValue ) == NT, |
154 | + "get returns initial incr/decr test data value that was set" ); |
155 | + set ( testData.m_testIterations, 0u ); |
156 | + testOk ( get ( testData.m_testIterations ) == 0u, |
157 | + "get returns initial incr/decr test thread iterations value that was set" ); |
158 | + for ( size_t i = 0u; i < N; i++ ) { |
159 | + epicsThreadMustCreate ( "incr", |
160 | + 50, stackSize, incr < T >, & testData ); |
161 | + epicsThreadMustCreate ( "decr", |
162 | + 50, stackSize, decr < T >, & testData ); |
163 | + if(i%10==0) |
164 | + testDiag("iteration %u", (unsigned)i); |
165 | + } |
166 | + while ( testData.m_testIterations < 2 * N ) { |
167 | + epicsThreadSleep ( 0.01 ); |
168 | + } |
169 | + testOk ( get ( testData.m_testIterations ) == 2 * N, |
170 | + "proper number of incr/decr test thread iterations" ); |
171 | + testOk ( get ( testData.m_testValue ) == NT, |
172 | + "proper final incr/decr test value" ); |
173 | +} |
174 | + |
175 | +template < class T > |
176 | +void testAddSub () |
177 | +{ |
178 | + using epics::atomic::set; |
179 | + using epics::atomic::get; |
180 | + |
181 | + static const size_t N = 90; |
182 | + static const T NDT = TestDataAddSub < T > :: delta * |
183 | + static_cast < T > ( N ); |
184 | + |
185 | + const unsigned int stackSize = |
186 | + epicsThreadGetStackSize ( epicsThreadStackSmall ); |
187 | + |
188 | + TestDataIncrDecr < T > testData = { 0, N }; |
189 | + set ( testData.m_testValue, NDT ); |
190 | + testOk ( get ( testData.m_testValue ) == NDT, |
191 | + "get returns initial add/sub test data value that was set" ); |
192 | + set ( testData.m_testIterations, 0u ); |
193 | + testOk ( get ( testData.m_testIterations ) == 0u, |
194 | + "get returns initial incr/decr test thread iterations value that was set" ); |
195 | + for ( size_t i = 0u; i < N; i++ ) { |
196 | + epicsThreadMustCreate ( "add", |
197 | + 50, stackSize, add < T >, & testData ); |
198 | + epicsThreadMustCreate ( "sub", |
199 | + 50, stackSize, sub < T >, & testData ); |
200 | + } |
201 | + while ( testData.m_testIterations < 2 * N ) { |
202 | + epicsThreadSleep ( 0.01 ); |
203 | + } |
204 | + testOk ( get ( testData.m_testIterations ) == 2 * N, |
205 | + "proper number of add/sub test thread iterations" ); |
206 | + testOk ( get ( testData.m_testValue ) == NDT, |
207 | + "proper final add/sub test value" ); |
208 | +} |
209 | + |
210 | +template < class T > |
211 | +void testCAS () |
212 | +{ |
213 | + using epics::atomic::set; |
214 | + using epics::atomic::get; |
215 | + |
216 | + static const size_t N = 10; |
217 | + |
218 | + const unsigned int stackSize = |
219 | + epicsThreadGetStackSize ( epicsThreadStackSmall ); |
220 | + |
221 | + TestDataCAS < T > testData = { 0, N, N }; |
222 | + set ( testData.m_testIterationsSet, 0 ); |
223 | + testOk ( get ( testData.m_testIterationsSet ) == 0u, |
224 | + "get returns initial CAS test thread " |
225 | + "iterations set value" ); |
226 | + set ( testData.m_testIterationsNotSet, 0 ); |
227 | + testOk ( get ( testData.m_testIterationsNotSet ) == 0u, |
228 | + "get returns initial CAS test thread " |
229 | + "iterations not set value" ); |
230 | + set ( testData.m_testValue, trueValue < T > () ); |
231 | + testOk ( get ( testData.m_testValue ) == trueValue < T > (), |
232 | + "set/get a true value" ); |
233 | + for ( size_t i = 0u; i < N; i++ ) { |
234 | + epicsThreadMustCreate ( "tns", |
235 | + 50, stackSize, cas < T >, & testData ); |
236 | + } |
237 | + set ( testData.m_testValue, falseValue < T > () ); |
238 | + while ( testData.m_testIterationsSet < N ) { |
239 | + epicsThreadSleep ( 0.01 ); |
240 | + } |
241 | + testOk ( get ( testData.m_testIterationsSet ) == N, |
242 | + "proper number of CAS test thread set iterations" ); |
243 | + testOk ( get ( testData.m_testIterationsNotSet ) == 0u, |
244 | + "proper number of CAS test thread not set iterations" ); |
245 | +} |
246 | + |
247 | +// template instances, needed for vxWorks 5.5.2 |
248 | + |
249 | +#ifdef _MSC_VER |
250 | +# pragma warning ( push ) |
251 | +# pragma warning ( disable:4660 ) |
252 | +#endif |
253 | + |
254 | +template void incr < int > (void *); |
255 | +template void decr < int > (void *); |
256 | +template void incr < size_t > (void *); |
257 | +template void decr < size_t > (void *); |
258 | +template void add < int > (void *); |
259 | +template void sub < int > (void *); |
260 | +template void add < size_t > (void *); |
261 | +template void sub < size_t > (void *); |
262 | +template void cas < int > (void *); |
263 | +template void cas < size_t > (void *); |
264 | +template void cas < EpicsAtomicPtrT > (void *); |
265 | + |
266 | +template void testIncrDecr < int > (void); |
267 | +template void testIncrDecr < size_t > (void); |
268 | +template void testAddSub < int > (void); |
269 | +template void testAddSub < size_t > (void); |
270 | +template void testCAS < int > (void); |
271 | +template void testCAS < size_t > (void); |
272 | +template void testCAS < EpicsAtomicPtrT > (void); |
273 | + |
274 | +#ifdef _MSC_VER |
275 | +# pragma warning ( pop ) |
276 | +#endif |
277 | + |
278 | +static void testClassify() |
279 | +{ |
280 | + testDiag("Classify Build conditions"); |
281 | +#ifdef EPICS_ATOMIC_CMPLR_NAME |
282 | + testDiag("Compiler dependent impl name %s", EPICS_ATOMIC_CMPLR_NAME); |
283 | +#else |
284 | + testDiag("Compiler dependent impl name undefined"); |
285 | +#endif |
286 | +#ifdef EPICS_ATOMIC_OS_NAME |
287 | + testDiag("OS dependent impl name %s", EPICS_ATOMIC_OS_NAME); |
288 | +#else |
289 | + testDiag("OS dependent impl name undefined"); |
290 | +#endif |
291 | + |
292 | +#ifdef __GNUC__ |
293 | +#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER |
294 | + testDiag("GCC using atomic builtin memory barrier"); |
295 | +#else |
296 | + testDiag("GCC using asm memory barrier"); |
297 | +#endif |
298 | +#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER |
299 | + testDiag("GCC use builtin for int"); |
300 | +#endif |
301 | +#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER |
302 | + testDiag("GCC use builtin for size_t"); |
303 | +#endif |
304 | + |
305 | +#ifndef EPICS_ATOMIC_INCR_INTT |
306 | + testDiag("Use default epicsAtomicIncrIntT()"); |
307 | +#endif |
308 | +#ifndef EPICS_ATOMIC_INCR_SIZET |
309 | + testDiag("Use default epicsAtomicIncrSizeT()"); |
310 | +#endif |
311 | +#ifndef EPICS_ATOMIC_DECR_INTT |
312 | + testDiag("Use default epicsAtomicDecrIntT()"); |
313 | +#endif |
314 | +#ifndef EPICS_ATOMIC_DECR_SIZET |
315 | + testDiag("Use default epicsAtomicDecrSizeT()"); |
316 | +#endif |
317 | +#ifndef EPICS_ATOMIC_ADD_INTT |
318 | + testDiag("Use default epicsAtomicAddIntT()"); |
319 | +#endif |
320 | +#ifndef EPICS_ATOMIC_ADD_SIZET |
321 | + testDiag("Use default epicsAtomicAddSizeT()"); |
322 | +#endif |
323 | +#ifndef EPICS_ATOMIC_SUB_SIZET |
324 | + testDiag("Use default epicsAtomicSubSizeT()"); |
325 | +#endif |
326 | +#ifndef EPICS_ATOMIC_SET_INTT |
327 | + testDiag("Use default epicsAtomicSetIntT()"); |
328 | +#endif |
329 | +#ifndef EPICS_ATOMIC_SET_SIZET |
330 | + testDiag("Use default epicsAtomicSetSizeT()"); |
331 | +#endif |
332 | +#ifndef EPICS_ATOMIC_SET_PTRT |
333 | + testDiag("Use default epicsAtomicSetPtrT()"); |
334 | +#endif |
335 | +#ifndef EPICS_ATOMIC_GET_INTT |
336 | + testDiag("Use default epicsAtomicGetIntT()"); |
337 | +#endif |
338 | +#ifndef EPICS_ATOMIC_GET_SIZET |
339 | + testDiag("Use default epicsAtomicGetSizeT()"); |
340 | +#endif |
341 | +#ifndef EPICS_ATOMIC_GET_PTRT |
342 | + testDiag("Use default epicsAtomicGetPtrT()"); |
343 | +#endif |
344 | +#ifndef EPICS_ATOMIC_CAS_INTT |
345 | + testDiag("Use default epicsAtomicCmpAndSwapIntT()"); |
346 | +#endif |
347 | +#ifndef EPICS_ATOMIC_CAS_SIZET |
348 | + testDiag("Use default epicsAtomicCmpAndSwapSizeT()"); |
349 | +#endif |
350 | +#ifndef EPICS_ATOMIC_CAS_PTRT |
351 | + testDiag("Use default epicsAtomicCmpAndSwapPtrT()"); |
352 | +#endif |
353 | +#endif /* __GNUC__ */ |
354 | +} |
355 | + |
356 | +static |
357 | +void testBasic() |
358 | +{ |
359 | + using epics::atomic::set; |
360 | + using epics::atomic::get; |
361 | + using epics::atomic::decrement; |
362 | + using epics::atomic::increment; |
363 | + using epics::atomic::add; |
364 | + using epics::atomic::subtract; |
365 | + using epics::atomic::compareAndSwap; |
366 | + |
367 | + testDiag("Test basic operation symantics"); |
368 | + |
369 | + int Int = 0; |
370 | + size_t Sizet = 0; |
371 | + void *voidp = NULL; |
372 | + |
373 | + set(Int, -42); |
374 | + set(Sizet, 42); |
375 | + set(voidp, (void*)&voidp); |
376 | + |
377 | + increment(Int); |
378 | + increment(Sizet); |
379 | + |
380 | + testOk1(get(Int)==-41); |
381 | + testOk1(get(Sizet)==43); |
382 | + testOk1(get(voidp)==(void*)&voidp); |
383 | + |
384 | + decrement(Int); |
385 | + decrement(Sizet); |
386 | + |
387 | + testOk1(get(Int)==-42); |
388 | + testOk1(get(Sizet)==42); |
389 | + |
390 | + add(Int, -2); |
391 | + subtract(Sizet, 2); |
392 | + |
393 | + testOk1(get(Int)==-44); |
394 | + testOk1(get(Sizet)==40); |
395 | + |
396 | + testOk1(compareAndSwap(Int, -34, -10)==-44); |
397 | + testOk1(compareAndSwap(Sizet, 34, 10)==40); |
398 | + testOk1(compareAndSwap(voidp, NULL, (void*)&Sizet)==(void*)&voidp); |
399 | + |
400 | + testOk1(get(Int)==-44); |
401 | + testOk1(get(Sizet)==40); |
402 | + testOk1(get(voidp)==(void*)&voidp); |
403 | + |
404 | + testOk1(compareAndSwap(Int, -44, -10)==-44); |
405 | + testOk1(compareAndSwap(Sizet, 40, 10)==40); |
406 | + testOk1(compareAndSwap(voidp, (void*)&voidp, (void*)&Sizet)==(void*)&voidp); |
407 | + |
408 | + testOk1(get(Int)==-10); |
409 | + testOk1(get(Sizet)==10); |
410 | + testOk1(get(voidp)==(void*)&Sizet); |
411 | +} |
412 | + |
413 | +} // namespace |
414 | + |
415 | +MAIN ( epicsAtomicTest ) |
416 | +{ |
417 | + |
418 | + testPlan ( 50 ); |
419 | + testDiag("In %s", EPICS_FUNCTION); |
420 | + testClassify (); |
421 | + testBasic(); |
422 | +#if defined(__rtems__) |
423 | + testSkip(31, "Tests assume time sliced thread scheduling"); |
424 | +#else |
425 | + testIncrDecr < int > (); |
426 | + testIncrDecr < size_t > (); |
427 | + testAddSub < int > (); |
428 | + testAddSub < size_t > (); |
429 | + testCAS < int > (); |
430 | + testCAS < size_t > (); |
431 | + testCAS < EpicsAtomicPtrT > (); |
432 | +#endif |
433 | + |
434 | + return testDone (); |
435 | +} |
436 | + |
437 | +>>>>>>> test/epicsAtomicTest.cpp |
This merge targeted a branch which no longer exists.