Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Monotonic_Manual_Event_Test.cpp
blobc0c71a048ea46b483dc10073270302b0f4cd3200
2 //=============================================================================
3 /**
4 * @file Monotonic_Manual_Event_Test.cpp
6 * This test verifies the functionality of the time policy support
7 * for the <ACE_Manual_Event> implementation.
9 * @author Martin Corino <mcorino@remedy.nl>
11 //=============================================================================
14 #include "test_config.h"
15 #include "ace/Manual_Event.h"
16 #include "ace/Thread.h"
17 #include "ace/Thread_Manager.h"
18 #include "ace/Get_Opt.h"
19 #include "ace/OS_NS_sys_time.h"
20 #include "ace/OS_NS_time.h"
21 #include "ace/OS_NS_unistd.h"
22 #include "ace/Atomic_Op.h"
24 #if defined (ACE_HAS_MONOTONIC_TIME_POLICY) && defined (ACE_HAS_MONOTONIC_CONDITIONS)
25 # include "ace/Monotonic_Time_Policy.h"
26 # if defined (ACE_WIN32)
27 # include "ace/Date_Time.h"
28 # include "ace/Truncate.h"
29 # endif
31 // Test results, 'success' is 0
32 static int test_result = 0;
34 # if defined (ACE_HAS_THREADS)
36 // Event used in the tests. Start it "unsignalled" (i.e., its initial
37 // state is 0).
38 static ACE_Event_Base *evt = 0;
40 // use monotonic or system time policy
41 static bool use_monotonic = true;
43 // Number of worker threads.
44 static long n_workers = 10;
46 // Absolute timeout for initial wait of workers
47 static ACE_Time_Value *initial_timeout;
49 // Number of wakeups.
50 # if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
51 static ACE_Atomic_Op<ACE_Thread_Mutex, long> n_awoken;
52 static ACE_Atomic_Op<ACE_Thread_Mutex, long> n_awoken2;
53 # else
54 static long n_awoken;
55 static long n_awoken2;
56 # endif
58 // Explain usage and exit.
59 static void
60 print_usage_and_die ()
62 ACE_DEBUG ((LM_DEBUG,
63 ACE_TEXT ("usage: %n [-w n_workers] [-s]\n")));
64 ACE_OS::exit (1);
67 static void
68 parse_args (int argc, ACE_TCHAR *argv[])
70 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("w:s"));
72 int c;
74 while ((c = get_opt ()) != -1)
75 switch (c)
77 case 'w':
78 n_workers = ACE_OS::atoi (get_opt.opt_arg ());
79 break;
80 case 's':
81 use_monotonic = false;
82 break;
83 default:
84 print_usage_and_die ();
85 break;
89 void set_system_time(const ACE_Time_Value& tv)
91 # if defined (ACE_WIN32)
92 ACE_Date_Time curdt (tv);
93 SYSTEMTIME sys_time;
94 sys_time.wDay = ACE_Utils::truncate_cast <WORD> (curdt.day ());
95 sys_time.wMonth = ACE_Utils::truncate_cast <WORD> (curdt.month ());
96 sys_time.wYear = ACE_Utils::truncate_cast <WORD> (curdt.year ());
97 sys_time.wHour = ACE_Utils::truncate_cast <WORD> (curdt.hour ());
98 sys_time.wMinute = ACE_Utils::truncate_cast <WORD> (curdt.minute ());
99 sys_time.wSecond = ACE_Utils::truncate_cast <WORD> (curdt.second ());
100 sys_time.wMilliseconds = ACE_Utils::truncate_cast <WORD> (curdt.microsec () / 1000);
101 if (!::SetLocalTime (&sys_time))
102 # else
103 timespec_t curts;
104 curts = tv;
105 if (ACE_OS::clock_settime (CLOCK_REALTIME, &curts) != 0)
106 # endif
108 ACE_DEBUG((LM_INFO,
109 "(%P|%t) Unable to reset OS time. Insufficient privileges or not supported.\n"));
113 // Worker tries to acquire the semaphore, hold it for a while, and
114 // then manually releases it.
116 static void *
117 worker (void *)
119 if (evt->wait (initial_timeout) == -1)
121 if (ACE_OS::last_error () == ETIME)
123 ACE_Time_Value tm_now = initial_timeout->now ();
124 ACE_ERROR_RETURN ((LM_ERROR,
125 ACE_TEXT (" (%P|%t) Timed out waiting for start pulse at %#T\n"),
126 &tm_now),
129 else
130 ACE_ERROR_RETURN ((LM_ERROR,
131 ACE_TEXT (" (%P|%t) %p\n"),
132 ACE_TEXT ("Failed waiting for pulse ()")),
136 ACE_Time_Value tm_now = initial_timeout->now ();
137 ACE_DEBUG ((LM_DEBUG,
138 ACE_TEXT (" (%P|%t) awake at %#T\n"), &tm_now));
140 if (++n_awoken < n_workers)
142 ACE_Time_Value *tv;
143 ACE_Time_Value_T<ACE_Monotonic_Time_Policy> tm_mono;
144 ACE_Time_Value tm_sys;
146 //FUZZ: disable check_for_lack_ACE_OS
147 ACE_Time_Value wait (1, 0); // Wait 1 sec
148 //FUZZ: enable check_for_lack_ACE_OS
150 if (use_monotonic)
152 tm_mono = tm_mono.now () + wait;
153 tv = &tm_mono;
155 else
157 tm_sys = ACE_OS::gettimeofday () + wait;
158 tv = &tm_sys;
161 if (evt->wait (tv) == -1)
163 // verify that we have ETIME
164 if (ACE_OS::last_error () == ETIME)
165 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%P|%t) timeout\n")));
166 else
167 ACE_ERROR ((LM_ERROR,
168 ACE_TEXT (" (%P|%t) wait failed %p\n"),
169 ACE_TEXT ("but not with ETIME")));
171 else
173 ACE_DEBUG ((LM_DEBUG,
174 ACE_TEXT (" (%P|%t) awake in time\n")));
176 if (++n_awoken2 >= (n_workers/2))
177 evt->reset (); // reset signal (rest times out)
180 // Check to ensure that an "infinite timeout" will work.
181 if (evt->wait (0) == -1)
183 //FUZZ: disable check_for_lack_ACE_OS
184 ACE_ERROR ((LM_ERROR,
185 ACE_TEXT (" (%P|%t) %p\n"),
186 ACE_TEXT ("Failed waiting for signal ()\n")));
187 //FUZZ: enable check_for_lack_ACE_OS
190 else
192 ACE_DEBUG ((LM_DEBUG,
193 ACE_TEXT (" (%P|%t) last awake; send signal\n")));
194 // last one wakes others
195 if (evt->signal () == -1)
196 ACE_ERROR ((LM_ERROR, ACE_TEXT (" (%P|%t) %p\n"), ACE_TEXT ("signal")));
198 ACE_OS::sleep (ACE_Time_Value (0, 200 * 1000 * 100)); // 200 msec
201 if (evt->wait () == -1)
203 //FUZZ: disable check_for_lack_ACE_OS
204 ACE_ERROR ((LM_ERROR,
205 ACE_TEXT (" (%P|%t) %p\n"),
206 ACE_TEXT ("Failed waiting for signal ()\n")));
207 //FUZZ: enable check_for_lack_ACE_OS
210 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%P|%t) worker finished\n")));
212 return 0;
215 # endif /* ACE_HAS_THREADS */
217 // Test event functionality.
219 int run_main (int argc, ACE_TCHAR *argv[])
221 ACE_START_TEST (ACE_TEXT ("Monotonic_Manual_Event_Test"));
223 # if defined (ACE_HAS_THREADS)
224 ACE_Manual_Event_T<ACE_Monotonic_Time_Policy> monotonic_event (0);
225 ACE_Manual_Event systime_event (0);
226 ACE_Time_Value_T<ACE_Monotonic_Time_Policy> tm_mono;
227 ACE_Time_Value tm_sys;
229 parse_args (argc, argv);
231 //FUZZ: disable check_for_lack_ACE_OS
232 ACE_Time_Value wait (7, 0); // Wait 7 sec
233 //FUZZ: enable check_for_lack_ACE_OS
235 if (use_monotonic)
237 evt = &monotonic_event;
238 tm_mono = tm_mono.now () + wait;
239 initial_timeout = &tm_mono;
241 else
243 evt = &systime_event;
244 tm_sys = ACE_OS::gettimeofday () + wait;
245 initial_timeout = &tm_sys;
248 // shift forward in time 3 sec; this will mess up timeouts if
249 // monotonic timer is not used
250 ACE_Time_Value tv_shift (3, 0);
251 set_system_time (ACE_OS::gettimeofday () + tv_shift);
253 ACE_DEBUG ((LM_DEBUG,
254 ACE_TEXT ("spawning workers - initial timeout till %#T\n"), initial_timeout));
256 if (ACE_Thread_Manager::instance ()->spawn_n
257 (static_cast<size_t> (n_workers),
258 ACE_THR_FUNC (worker),
260 THR_NEW_LWP) == -1)
261 ACE_ERROR_RETURN ((LM_ERROR,
262 ACE_TEXT ("%p\n"),
263 ACE_TEXT ("spawn_n")),
266 // gives all workers chance to start
267 ACE_OS::sleep (5);
269 ACE_DEBUG ((LM_DEBUG,
270 ACE_TEXT ("finished waiting for workers to start\n")));
272 // restore time (workers will already have failed without monotonic timer)
273 set_system_time (ACE_OS::gettimeofday () - tv_shift);
275 ACE_DEBUG ((LM_DEBUG,
276 ACE_TEXT ("sending pulse ()\n")));
278 // Release the all workers.
279 if (evt->pulse () == -1)
280 ACE_ERROR_RETURN ((LM_ERROR,
281 ACE_TEXT ("%p\n"),
282 ACE_TEXT ("pulse")),
285 // Wait 2 sec
286 ACE_OS::sleep (2);
288 //FUZZ: disable check_for_lack_ACE_OS
289 ACE_DEBUG ((LM_DEBUG,
290 ACE_TEXT ("sending signal ()\n")));
291 //FUZZ: enable check_for_lack_ACE_OS
293 // Signal
294 if (evt->signal () == -1)
295 ACE_ERROR_RETURN ((LM_ERROR,
296 ACE_TEXT ("%p\n"),
297 ACE_TEXT ("signal")),
300 ACE_Thread_Manager::instance ()->wait ();
301 # else
302 ACE_UNUSED_ARG (argc);
303 ACE_UNUSED_ARG (argv);
304 ACE_ERROR ((LM_INFO,
305 ACE_TEXT ("Threads not supported on this platform\n")));
306 # endif /* ACE_HAS_THREADS */
307 ACE_END_TEST;
308 return test_result;
311 #else
314 run_main (int , ACE_TCHAR *[])
316 ACE_START_TEST (ACE_TEXT ("Monotonic_Manual_Event_Test"));
317 ACE_DEBUG((LM_INFO,
318 "(%P|%t) ACE not compiled with monotonic time.\n"));
319 ACE_END_TEST;
320 return 0;
323 #endif