diff options
Diffstat (limited to 'ACE/tests/Manual_Event_Test.cpp')
-rw-r--r-- | ACE/tests/Manual_Event_Test.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/ACE/tests/Manual_Event_Test.cpp b/ACE/tests/Manual_Event_Test.cpp new file mode 100644 index 00000000000..1b28d846a71 --- /dev/null +++ b/ACE/tests/Manual_Event_Test.cpp @@ -0,0 +1,205 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Manual_Event Test +// +// = DESCRIPTION +// This test verifies the functionality of the <ACE_Manual_Event> +// implementation. +// +// = AUTHOR +// Martin Corino <mcorino@remedy.nl> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Manual_Event.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_sys_time.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Atomic_Op.h" + +ACE_RCSID(tests, Manual_Event_Test, "$Id$") + +// msec that times are allowed to differ before test fails. +#if defined (ACE_HAS_HI_RES_TIMER) || defined (ACE_HAS_AIX_HI_RES_TIMER) || \ + defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER) || \ + defined (ACE_HAS_POWERPC_TIMER) +# define ACE_ALLOWED_SLACK 100 +#else /* don't have a high-res timer */ +# define ACE_ALLOWED_SLACK 1100 +#endif /* don't have a high-res timer */ + +// Test results, 'success' is 0 +static int test_result = 0; + +#if defined (ACE_HAS_THREADS) + +// Event used in the tests. Start it "unsignalled" (i.e., its initial +// state is 0). +static ACE_Manual_Event evt ((unsigned int) 0); + +// Default number of iterations. +static int n_iterations = 10; + +// Number of worker threads. +static long n_workers = 10; + +// Number of wakeups. +#if defined (ACE_HAS_BUILTIN_ATOMIC_OP) +static ACE_Atomic_Op<ACE_Thread_Mutex, long> n_awoken; +static ACE_Atomic_Op<ACE_Thread_Mutex, long> n_awoken2; +#else +static long n_awoken; +static long n_awoken2; +#endif + +// Explain usage and exit. +static void +print_usage_and_die (void) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("usage: %n [-w n_workers] [-n iteration_count]\n"))); + ACE_OS::exit (1); +} + +static void +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("w:n:")); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'w': + n_workers = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'n': + n_iterations = ACE_OS::atoi (get_opt.opt_arg ()); + break; + default: + print_usage_and_die (); + break; + } +} + +// Worker tries to acquire the semaphore, hold it for a while, and +// then manually releases it. + +static void * +worker (void *) +{ + if (evt.wait() == -1) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Failed waiting for pulse()\n"))); + return 0; + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) awake\n"))); + + if (++n_awoken < n_workers) + { + ACE_Time_Value wait (1, 0); // Wait 10 sec + ACE_Time_Value tv = ACE_OS::gettimeofday () + wait; + + if (evt.wait (&tv) == -1) + { + // verify that we have ETIME + ACE_ASSERT(ACE_OS::last_error() == ETIME); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) timeout\n"))); + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) awake in time\n"))); + + if (++n_awoken2 >= (n_workers/2)) + evt.reset(); // reset signal (rest times out) + } + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) last awake; send signal\n"))); + // last one wakes others + evt.signal(); + + ACE_OS::sleep (ACE_Time_Value(0, 200 * 1000 * 100)); // 200 msec + } + + if (evt.wait() == -1) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%P|%t) Failed waiting for signal()\n"))); + } + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) worker finished\n"))); + + return 0; +} + +#endif /* ACE_HAS_THREADS */ + +// Test event functionality. + +int run_main (int argc, ACE_TCHAR *argv[]) +{ + ACE_START_TEST (ACE_TEXT ("Manual_Event_Test")); + +#if defined (ACE_HAS_THREADS) + parse_args (argc, argv); + + if (ACE_Thread_Manager::instance ()->spawn_n + (static_cast<size_t> (n_workers), + ACE_THR_FUNC (worker), + 0, + THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("spawn_n")), + 1); + + // gives all workers chance to start + ACE_OS::sleep (5); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("sending pulse()\n"))); + + // Release the all workers. + evt.pulse (); + + // Wait 2 sec + ACE_OS::sleep (2); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("sending signal()\n"))); + + // Signal + evt.signal(); + + ACE_Thread_Manager::instance ()->wait (); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Manual_Event Test successful\n"))); +#else + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + ACE_ERROR ((LM_INFO, + ACE_TEXT ("Threads not supported on this platform\n"))); +#endif /* ACE_HAS_THREADS */ + ACE_END_TEST; + return test_result; +} |