2 //=============================================================================
4 * @file Atomic_Op_Test.cpp
6 * This is a simple test of the Atomic Operations Class in ACE.
7 * On platforms like Win32, ACE uses template specialization to
8 * use native implementations provided by the OS to accelarate
11 * @author Irfan Pyarali <irfan@cs.wustl.edu>
13 //=============================================================================
16 #include "test_config.h"
18 #include "ace/Atomic_Op.h"
19 #include "ace/Synch_Traits.h"
20 #include "ace/Time_Value.h"
21 #include "ace/OS_NS_sys_time.h"
22 #include "ace/Barrier.h"
27 * Exchange_Test tests the exchange() operation in ACE_Atomic_Op. It runs
28 * a number of threads and each tries to "claim" the op_ by exchanging it
29 * with '1'. Only one thread should do this. The claimed_ member counts
30 * the number of threads that actually do claim it.
33 class Exchange_Tester
: public ACE_Task
<ACE_NULL_SYNCH
>
36 Exchange_Tester (unsigned int thr_count
);
44 ACE_Atomic_Op
<ACE_SYNCH_MUTEX
, T
> op_
;
45 ACE_Atomic_Op
<ACE_SYNCH_MUTEX
, int> claimed_
;
49 Exchange_Tester
<T
>::Exchange_Tester (unsigned int thr_count
)
50 : barrier_(thr_count
), op_ (0), claimed_ (0)
52 this->activate (THR_NEW_LWP
| THR_JOINABLE
| THR_INHERIT_SCHED
,
58 Exchange_Tester
<T
>::result () const
60 return this->claimed_
== 1 ? 0 : 1;
65 Exchange_Tester
<T
>::svc ()
67 this->barrier_
.wait (); // Want all threads to try to claim "at once"
68 bool claimed
= this->op_
.exchange (1) == 0;
70 ACE_TEXT ("Thread %t %s claim.\n"),
71 claimed
? ACE_TEXT ("DID") : ACE_TEXT ("DID NOT")));
78 template <typename TYPE
, typename dummy
>
79 int test (const ACE_TCHAR
* type
, int iterations
)
81 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Measuring %d iterations for %s\n"), iterations
, type
));
84 ACE_Atomic_Op
<ACE_SYNCH_MUTEX
, TYPE
> foo (5);
86 ACE_TEST_ASSERT (foo
== 5);
89 ACE_TEST_ASSERT (foo
== 6);
90 ACE_TEST_ASSERT (result
== 6);
93 ACE_TEST_ASSERT (foo
== 5);
94 ACE_TEST_ASSERT (result
== 5);
97 ACE_TEST_ASSERT (foo
== 6);
98 ACE_TEST_ASSERT (result
== 5);
101 ACE_TEST_ASSERT (foo
== 5);
102 ACE_TEST_ASSERT (result
== 6);
105 ACE_TEST_ASSERT (foo
== 15);
106 ACE_TEST_ASSERT (result
== 15);
109 ACE_TEST_ASSERT (foo
== 5);
110 ACE_TEST_ASSERT (result
== 5);
113 ACE_TEST_ASSERT (foo
== 7);
115 ACE_Atomic_Op
<ACE_SYNCH_MUTEX
, TYPE
> foo2 (5);
117 ACE_TEST_ASSERT (foo
== 7);
118 ACE_TEST_ASSERT (foo2
== 7);
122 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> assignment %D\n"), type
));
123 ACE_Time_Value diff
= ACE_OS::gettimeofday ();
125 for (i
= 0; i
< iterations
; ++i
)
132 diff
= ACE_OS::gettimeofday () - diff
;
134 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> assignment %D, took %Q\n"), type
, usec
));
138 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> prefix increment %D\n"), type
));
139 diff
= ACE_OS::gettimeofday ();
140 for (i
= 0; i
< iterations
; ++i
)
147 diff
= ACE_OS::gettimeofday () - diff
;
149 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> prefix increment %D, took %Q\n"), type
, usec
));
151 if (foo
!= iterations
* 4)
154 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Prefix increment failed\n")));
157 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> prefix decrement %D\n"), type
));
158 diff
= ACE_OS::gettimeofday ();
159 for (i
= 0; i
< iterations
; ++i
)
166 diff
= ACE_OS::gettimeofday () - diff
;
168 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> prefix decrement %D, took %Q\n"), type
, usec
));
173 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Prefix decrement failed\n")));
176 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> postfix increment %D\n"), type
));
177 diff
= ACE_OS::gettimeofday ();
178 for (i
= 0; i
< iterations
; ++i
)
185 diff
= ACE_OS::gettimeofday () - diff
;
187 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> postfix increment %D, took %Q\n"), type
, usec
));
189 if (foo
!= iterations
* 4)
192 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Postfix increment failed\n")));
195 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> postfix decrement %D\n"), type
));
196 diff
= ACE_OS::gettimeofday ();
197 for (i
= 0; i
< iterations
; ++i
)
204 diff
= ACE_OS::gettimeofday () - diff
;
206 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> postfix decrement %D, took %Q\n"), type
, usec
));
211 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Postfix decrement failed\n")));
214 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> addition %D\n"), type
));
215 diff
= ACE_OS::gettimeofday ();
216 for (i
= 0; i
< iterations
; ++i
)
223 diff
= ACE_OS::gettimeofday () - diff
;
225 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> addition %D, took %Q\n"), type
, usec
));
227 if (foo
!= iterations
* 4 * 5)
230 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Addition failed\n")));
233 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> subtraction %D\n"), type
));
234 diff
= ACE_OS::gettimeofday ();
235 for (i
= 0; i
< iterations
; ++i
)
242 diff
= ACE_OS::gettimeofday () - diff
;
244 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> subtraction %D, took %Q\n"), type
, usec
));
249 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Subtraction failed\n")));
255 template <typename TYPE
>
256 int test (const ACE_TCHAR
* type
, int iterations
)
258 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Measuring %d iterations for %s\n"), iterations
, type
));
262 ACE_Atomic_Op
<ACE_SYNCH_MUTEX
, TYPE
> foo (true);
264 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> assignment %D\n"), type
));
265 ACE_Time_Value diff
= ACE_OS::gettimeofday ();
267 for (i
= 0; i
< iterations
; ++i
)
274 diff
= ACE_OS::gettimeofday () - diff
;
276 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> assignment %D, took %Q\n"), type
, usec
));
278 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Starting <%s> comparison %D\n"), type
));
279 diff
= ACE_OS::gettimeofday ();
280 for (i
= 0; i
< iterations
; ++i
)
282 if (foo
!= true) ++retval
;
283 if (foo
== false) ++retval
;
284 if (foo
!= true) ++retval
;
285 if (foo
== false) ++retval
;
287 diff
= ACE_OS::gettimeofday () - diff
;
289 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Ending <%s> comparison %D, took %Q\n"), type
, usec
));
295 run_main (int, ACE_TCHAR
*[])
297 ACE_START_TEST (ACE_TEXT ("Atomic_Op_Test"));
299 // Some platforms w/o builtin atomic ops time out the regression tests,
300 // so run fewer iterations there.
301 #if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
302 const int ITERATIONS
= 1000000;
304 const int ITERATIONS
= 100000;
305 #endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
309 retval
+= test
<int, int> (ACE_TEXT("int"), ITERATIONS
);
310 retval
+= test
<long, int> (ACE_TEXT("long"), ITERATIONS
);
311 retval
+= test
<unsigned int, int> (ACE_TEXT("unsigned int"), ITERATIONS
);
312 retval
+= test
<unsigned long, int> (ACE_TEXT("unsigned long"), ITERATIONS
);
313 retval
+= test
<short, int> (ACE_TEXT("short"), ITERATIONS
);
314 retval
+= test
<unsigned short, int> (ACE_TEXT("unsigned short"), ITERATIONS
);
315 retval
+= test
<bool> (ACE_TEXT("bool"), ITERATIONS
);
316 retval
+= test
<long long, int> (ACE_TEXT("long long"), ITERATIONS
);
318 #if defined (ACE_HAS_THREADS)
319 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Testing exchange with long\n")));
320 Exchange_Tester
<long> e1 (5);
322 retval
+= e1
.result ();
324 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Testing exchange with unsigned long\n")));
325 Exchange_Tester
<unsigned long> e2 (5);
327 retval
+= e2
.result ();
329 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Testing exchange with int\n")));
330 Exchange_Tester
<int> e3 (5);
332 retval
+= e3
.result ();
334 #endif /* ACE_HAS_THREADS */