Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / tests / Semaphore_Test.cpp
blob6818f969d347a40aca6ff8aa9e30415a5492db10
2 //=============================================================================
3 /**
4 * @file Semaphore_Test.cpp
6 * This test verifies the functionality of the <ACE_Thread_Semaphore>
7 * implementation.
9 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
11 //=============================================================================
13 #include "test_config.h"
14 #include "ace/Thread_Semaphore.h"
15 #include "ace/Thread.h"
16 #include "ace/Thread_Manager.h"
17 #include "ace/Get_Opt.h"
18 #include "ace/OS_NS_sys_time.h"
19 #include "ace/OS_NS_time.h"
20 #include "ace/OS_NS_unistd.h"
22 // msec that times are allowed to differ before test fails.
23 #if defined (ACE_HAS_HI_RES_TIMER) || \
24 defined (ACE_HAS_PENTIUM) || \
25 defined (ACE_HAS_POWERPC_TIMER)
26 # define ACE_ALLOWED_SLACK 100
27 #else /* don't have a high-res timer */
28 # define ACE_ALLOWED_SLACK 1100
29 #endif /* don't have a high-res timer */
31 // Test results, 'success' is 0
32 static int test_result = 0;
34 #if defined (ACE_HAS_THREADS)
36 // Semaphore used in the tests. Start it "locked" (i.e., its initial
37 // count is 0).
38 static ACE_Thread_Semaphore s ((unsigned int) 0);
40 // Default number of iterations.
41 static int n_iterations = 10;
43 // Number of worker threads.
44 static size_t n_workers = 10;
46 // Amount to release the semaphore.
47 static u_int n_release_count = 3;
49 // Number of timeouts.
50 static size_t timeouts = 0;
52 // Number of times to call test_timeout ().
53 static size_t test_timeout_count = 3;
55 // Tests the amount of time spent in a timed wait.
56 static int
57 test_timeout ()
59 int status = 0;
61 // milliseconds...
62 long msecs_expected;
63 long msecs_waited;
64 long msecs_diff;
66 // Wait a little longer each time
67 static long wait_secs = 3;
69 ACE_Time_Value wait = ACE_OS::gettimeofday ();
71 ACE_Time_Value begin = wait;
73 wait.sec (wait.sec () + wait_secs);
75 if (s.acquire (wait) == -1)
77 if (errno != ETIME)
79 ACE_ERROR ((LM_ERROR,
80 ACE_TEXT ("%p\n"),
81 ACE_TEXT ("test_timeout should be ETIME but is")));
82 status = -1;
86 ACE_Time_Value wait_diff = ACE_OS::gettimeofday () - begin;
88 msecs_waited = wait_diff.msec ();
89 msecs_expected = wait_secs * 1000;
90 msecs_diff = labs (msecs_expected - msecs_waited);
92 if (msecs_diff > ACE_ALLOWED_SLACK)
94 ACE_ERROR ((LM_ERROR,
95 ACE_TEXT ("Timed wait fails length test\n")));
96 ACE_ERROR ((LM_ERROR,
97 ACE_TEXT ("Expected %d ms, actual %d ms; %d allowed\n"),
98 (int)msecs_expected,
99 (int)msecs_waited,
100 (int)ACE_ALLOWED_SLACK));
101 status = -1;
104 ++wait_secs;
105 return status;
108 // Explain usage and exit.
109 static void
110 print_usage_and_die ()
112 ACE_DEBUG ((LM_DEBUG,
113 ACE_TEXT ("usage: %n [-s n_release_count] [-w n_workers] [-n iteration_count]\n")));
114 ACE_OS::exit (1);
117 static void
118 parse_args (int argc, ACE_TCHAR *argv[])
120 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("s:w:n:"));
122 int c;
124 while ((c = get_opt ()) != -1)
125 switch (c)
127 case 's':
128 n_release_count = ACE_OS::atoi (get_opt.opt_arg ());
129 break;
130 case 'w':
131 n_workers = ACE_OS::atoi (get_opt.opt_arg ());
132 break;
133 case 'n':
134 n_iterations = ACE_OS::atoi (get_opt.opt_arg ());
135 break;
136 default:
137 print_usage_and_die ();
138 break;
142 // Worker tries to acquire the semaphore, hold it for a while, and
143 // then releases it.
145 static void *
146 worker (void *)
148 for (int iterations = 1;
149 iterations <= n_iterations;
150 iterations++)
152 //FUZZ: disable check_for_lack_ACE_OS
153 ACE_Time_Value wait (0,
154 iterations * 1000 * 100); // Wait 'iter' msec
155 //FUZZ: enable check_for_lack_ACE_OS
157 ACE_Time_Value tv = ACE_OS::gettimeofday () + wait;
158 if (s.acquire (tv) == -1)
160 // verify that we have ETIME
161 if (ACE_OS::last_error() != ETIME)
163 ACE_ERROR ((LM_ERROR,
164 ACE_TEXT ("%p\n"),
165 ACE_TEXT ("Worker should be ETIME but is")));
167 else
168 ++timeouts;
169 ACE_Time_Value diff = ACE_OS::gettimeofday ();
170 diff = diff - tv; // tv should have been reset to time acquired
171 long diff_msec = diff.msec ();
173 if (diff_msec > ACE_ALLOWED_SLACK)
175 ACE_ERROR ((LM_ERROR,
176 ACE_TEXT ("Acquire fails time reset test\n")));
177 ACE_ERROR ((LM_ERROR,
178 ACE_TEXT ("Diff btw now and returned time: %d ms; ")
179 ACE_TEXT ("%d allowed\n"),
180 (int)diff_msec,
181 (int)ACE_ALLOWED_SLACK));
182 test_result = 1;
184 // Hold the lock for a while.
185 ACE_OS::sleep (ACE_Time_Value (0,
186 (ACE_OS::rand () % 1000) * 1000));
187 s.release ();
189 ACE_Thread::yield ();
192 return 0;
195 #endif /* ACE_HAS_THREADS */
197 // Test semaphore functionality.
199 int run_main (int argc, ACE_TCHAR *argv[])
201 ACE_START_TEST (ACE_TEXT ("Semaphore_Test"));
203 #if defined (ACE_HAS_THREADS)
204 parse_args (argc, argv);
205 ACE_OS::srand ((u_int) ACE_OS::time (0L));
207 //Test timed waits.
208 for (size_t i = 0; i < test_timeout_count; i++)
209 if (test_timeout () != 0)
210 test_result = 1;
212 // Release the semaphore a certain number of times.
213 s.release (n_release_count);
215 if (ACE_Thread_Manager::instance ()->spawn_n
216 (static_cast<size_t> (n_workers),
217 ACE_THR_FUNC (worker),
219 THR_NEW_LWP) == -1)
220 ACE_ERROR_RETURN ((LM_ERROR,
221 ACE_TEXT ("%p\n"),
222 ACE_TEXT ("spawn_n")),
225 ACE_Thread_Manager::instance ()->wait ();
227 size_t percent = (timeouts * 100) / (n_workers * n_iterations);
229 ACE_DEBUG ((LM_DEBUG,
230 ACE_TEXT ("Worker threads timed out %d percent of the time\n"),
231 (int)percent));
233 if (test_result == 0)
234 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Semaphore Test successful\n")));
235 #else
236 ACE_UNUSED_ARG (argc);
237 ACE_UNUSED_ARG (argv);
238 ACE_ERROR ((LM_INFO,
239 ACE_TEXT ("Threads not supported on this platform\n")));
240 #endif /* ACE_HAS_THREADS */
241 ACE_END_TEST;
242 return test_result;