Merge ~dirk.zimoch/epics-base:libCom/vxWorks5 into ~epics-core/epics-base/+git/epics-base: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
Reviewer Review Type Date Requested Status
EPICS Core Developers Pending
Review via email: mp+355498@code.launchpad.net

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 :

This merge targeted a branch which no longer exists.

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
1diff --git a/test/epicsAtomicTest.cpp b/test/epicsAtomicTest.cpp
2new file mode 100644
3index 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

Subscribers

People subscribed via source and target branches