Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Atomic_Op_Test.cpp
blobd48ef7aa9ff15ec89f4e543cbcf22db8bf552ee6
2 //=============================================================================
3 /**
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
9 * these operations.
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"
23 #include "ace/Task.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.
32 template <typename T>
33 class Exchange_Tester : public ACE_Task<ACE_NULL_SYNCH>
35 public:
36 Exchange_Tester (unsigned int thr_count);
37 int result () const;
39 private:
40 Exchange_Tester () {}
41 int svc () override;
43 ACE_Barrier barrier_;
44 ACE_Atomic_Op<ACE_SYNCH_MUTEX, T> op_;
45 ACE_Atomic_Op<ACE_SYNCH_MUTEX, int> claimed_;
48 template <typename T>
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,
53 (int)thr_count);
56 template <typename T>
57 int
58 Exchange_Tester<T>::result () const
60 return this->claimed_ == 1 ? 0 : 1;
63 template <typename T>
64 int
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;
69 ACE_DEBUG ((LM_DEBUG,
70 ACE_TEXT ("Thread %t %s claim.\n"),
71 claimed ? ACE_TEXT ("DID") : ACE_TEXT ("DID NOT")));
72 if (claimed)
73 ++this->claimed_;
74 return 0;
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));
83 int retval = 0;
84 ACE_Atomic_Op <ACE_SYNCH_MUTEX, TYPE> foo (5);
86 ACE_TEST_ASSERT (foo == 5);
88 TYPE result = ++foo;
89 ACE_TEST_ASSERT (foo == 6);
90 ACE_TEST_ASSERT (result == 6);
92 result = --foo;
93 ACE_TEST_ASSERT (foo == 5);
94 ACE_TEST_ASSERT (result == 5);
96 result = foo++;
97 ACE_TEST_ASSERT (foo == 6);
98 ACE_TEST_ASSERT (result == 5);
100 result = foo--;
101 ACE_TEST_ASSERT (foo == 5);
102 ACE_TEST_ASSERT (result == 6);
104 result = foo += 10;
105 ACE_TEST_ASSERT (foo == 15);
106 ACE_TEST_ASSERT (result == 15);
108 result = foo -= 10;
109 ACE_TEST_ASSERT (foo == 5);
110 ACE_TEST_ASSERT (result == 5);
112 foo = 7;
113 ACE_TEST_ASSERT (foo == 7);
115 ACE_Atomic_Op <ACE_SYNCH_MUTEX, TYPE> foo2 (5);
116 foo2 = foo;
117 ACE_TEST_ASSERT (foo == 7);
118 ACE_TEST_ASSERT (foo2 == 7);
120 ACE_UINT64 usec;
122 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Starting <%s> assignment %D\n"), type));
123 ACE_Time_Value diff = ACE_OS::gettimeofday ();
124 int i;
125 for (i = 0; i < iterations; ++i)
127 foo = 1;
128 foo = 2;
129 foo = 3;
130 foo = 4;
132 diff = ACE_OS::gettimeofday () - diff;
133 diff.to_usec (usec);
134 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> assignment %D, took %Q\n"), type, usec));
136 foo = 0;
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)
142 ++foo;
143 ++foo;
144 ++foo;
145 ++foo;
147 diff = ACE_OS::gettimeofday () - diff;
148 diff.to_usec (usec);
149 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> prefix increment %D, took %Q\n"), type, usec));
151 if (foo != iterations * 4)
153 ++retval;
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)
161 foo--;
162 foo--;
163 foo--;
164 foo--;
166 diff = ACE_OS::gettimeofday () - diff;
167 diff.to_usec (usec);
168 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> prefix decrement %D, took %Q\n"), type, usec));
170 if (foo != 0)
172 ++retval;
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)
180 foo++;
181 foo++;
182 foo++;
183 foo++;
185 diff = ACE_OS::gettimeofday () - diff;
186 diff.to_usec (usec);
187 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> postfix increment %D, took %Q\n"), type, usec));
189 if (foo != iterations * 4)
191 ++retval;
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)
199 --foo;
200 --foo;
201 --foo;
202 --foo;
204 diff = ACE_OS::gettimeofday () - diff;
205 diff.to_usec (usec);
206 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> postfix decrement %D, took %Q\n"), type, usec));
208 if (foo != 0)
210 ++retval;
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)
218 foo += 5;
219 foo += 5;
220 foo += 5;
221 foo += 5;
223 diff = ACE_OS::gettimeofday () - diff;
224 diff.to_usec (usec);
225 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> addition %D, took %Q\n"), type, usec));
227 if (foo != iterations * 4 * 5)
229 ++retval;
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)
237 foo -= 5;
238 foo -= 5;
239 foo -= 5;
240 foo -= 5;
242 diff = ACE_OS::gettimeofday () - diff;
243 diff.to_usec (usec);
244 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> subtraction %D, took %Q\n"), type, usec));
246 if (foo != 0)
248 ++retval;
249 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Error: Subtraction failed\n")));
252 return retval;
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));
260 ACE_UINT64 usec;
261 int retval = 0;
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 ();
266 int i;
267 for (i = 0; i < iterations; ++i)
269 foo = true;
270 foo = true;
271 foo = true;
272 foo = true;
274 diff = ACE_OS::gettimeofday () - diff;
275 diff.to_usec (usec);
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;
288 diff.to_usec (usec);
289 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ending <%s> comparison %D, took %Q\n"), type, usec));
291 return retval;
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;
303 #else
304 const int ITERATIONS = 100000;
305 #endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
307 int retval = 0;
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);
321 e1.wait ();
322 retval += e1.result ();
324 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing exchange with unsigned long\n")));
325 Exchange_Tester<unsigned long> e2 (5);
326 e2.wait ();
327 retval += e2.result ();
329 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing exchange with int\n")));
330 Exchange_Tester<int> e3 (5);
331 e3.wait ();
332 retval += e3.result ();
334 #endif /* ACE_HAS_THREADS */
336 ACE_END_TEST;
337 return retval;