2 //=============================================================================
4 * @file Semaphore_Test.cpp
6 * This test verifies the functionality of the <ACE_Thread_Semaphore>
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
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.
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)
81 ACE_TEXT ("test_timeout should be ETIME but is")));
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
)
95 ACE_TEXT ("Timed wait fails length test\n")));
97 ACE_TEXT ("Expected %d ms, actual %d ms; %d allowed\n"),
100 (int)ACE_ALLOWED_SLACK
));
108 // Explain usage and exit.
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")));
118 parse_args (int argc
, ACE_TCHAR
*argv
[])
120 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("s:w:n:"));
124 while ((c
= get_opt ()) != -1)
128 n_release_count
= ACE_OS::atoi (get_opt
.opt_arg ());
131 n_workers
= ACE_OS::atoi (get_opt
.opt_arg ());
134 n_iterations
= ACE_OS::atoi (get_opt
.opt_arg ());
137 print_usage_and_die ();
142 // Worker tries to acquire the semaphore, hold it for a while, and
148 for (int iterations
= 1;
149 iterations
<= n_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
,
165 ACE_TEXT ("Worker should be ETIME but is")));
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"),
181 (int)ACE_ALLOWED_SLACK
));
184 // Hold the lock for a while.
185 ACE_OS::sleep (ACE_Time_Value (0,
186 (ACE_OS::rand () % 1000) * 1000));
189 ACE_Thread::yield ();
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));
208 for (size_t i
= 0; i
< test_timeout_count
; i
++)
209 if (test_timeout () != 0)
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
),
220 ACE_ERROR_RETURN ((LM_ERROR
,
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"),
233 if (test_result
== 0)
234 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("Semaphore Test successful\n")));
236 ACE_UNUSED_ARG (argc
);
237 ACE_UNUSED_ARG (argv
);
239 ACE_TEXT ("Threads not supported on this platform\n")));
240 #endif /* ACE_HAS_THREADS */