diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-09-13 00:26:05 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-09-13 00:26:05 +0000 |
commit | 7a042e4f8a987a50143415af690a878881d4b48f (patch) | |
tree | 338a92488326f0585d65743bd3d6ec0650fd6db1 /performance-tests/Misc/preempt.cpp | |
parent | 9b50028195a935518c2716dcdb94d5bb167a0af2 (diff) | |
download | ATCD-TAO-1_0_4.tar.gz |
This commit was manufactured by cvs2svn to create tag 'TAO-1_0_4'.TAO-1_0_4
Diffstat (limited to 'performance-tests/Misc/preempt.cpp')
-rw-r--r-- | performance-tests/Misc/preempt.cpp | 455 |
1 files changed, 0 insertions, 455 deletions
diff --git a/performance-tests/Misc/preempt.cpp b/performance-tests/Misc/preempt.cpp deleted file mode 100644 index f824ab17027..00000000000 --- a/performance-tests/Misc/preempt.cpp +++ /dev/null @@ -1,455 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// performance-tests/Misc -// -// = FILENAME -// preempt.cpp -// -// = DESCRIPTION -// This is a simple test to illustrate OS thread preemption. One -// ore more high priority threads periodically (every half -// second, by default) reads the clock. They use select () to -// block for that duration. Meanwhile, a low priority thread -// continually chews up the CPU. Without preemption, the high -// priority thread won't have a chance to read the clock in a -// timely manner. -// -// At the end of the test, the actual clock read intervals by the -// high priority task(s) are printed out. With proper -// preemption, the intervals should correspond to the requested -// clock read interval. -// -// There is a -y option for the low priority thread to periodically -// yield. It shouldn't be necessary to use that option, if preemption -// is supported. It's a handy option for testing. -// -// = AUTHOR -// David L. Levine -// -// ============================================================================ - -#include "ace/Task.h" -#include "ace/Sched_Params.h" -#include "ace/Get_Opt.h" - -ACE_RCSID(Misc, preempt, "$Id$") - -#if defined (ACE_HAS_THREADS) || ! defined (ACE_LACKS_FORK) - -#if defined (ACE_HAS_STHREADS) -# include <sys/lwp.h> /* for _lwp_self () */ -#endif /* ACE_HAS_STHREADS */ - -static const char usage [] = "[-? |\n" -#if defined (ACE_HAS_THREADS) - " [-f use fork instead of spawn]\n" -#endif /* ACE_HAS_THREADS */ - " [-h <high pri iterations, default 10>]\n" - " [-l <low pri iterations, default 25000>]\n" - " [-n <high priority threads, default 1>]\n" - " [-p <read period, default 500000 usec>]\n" - " [-y to yield the low priority thread]]\n"; - -// Configuration options. -#if defined (ACE_HAS_THREADS) -u_int use_fork = 0; -#else /* ! ACE_HAS_THREADS */ -u_int use_fork = 1; -#endif /* ! ACE_HAS_THREADS */ -u_int high_iterations = 10; -u_int high_priority_tasks = 1; -u_int low_iterations = 25000; /* Big enough to keep the low priority task - cranking for a while */ -u_long read_period = 500000; /* usec */ -u_int low_yield = 0; - -// To permit calculation of relative times. -ACE_hrtime_t starttime; - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// class High_Priority_Task -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -class High_Priority_Task : public ACE_Task<ACE_SYNCH> -{ -public: - High_Priority_Task (void); - ~High_Priority_Task (void); - - int open (void *); - int svc (void); - int done () const { return done_; } - void print_times () const; - -private: - int priority_; - int done_; - u_long *time_; -}; - -High_Priority_Task::High_Priority_Task (void) - : ACE_Task<ACE_SYNCH> (ACE_Thread_Manager::instance ()), - priority_ (ACE_Sched_Params::next_priority ( - ACE_SCHED_FIFO, - ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, - ACE_SCOPE_THREAD), - ACE_SCOPE_THREAD)), - done_ (0) -{ - ACE_NEW (time_, u_long[high_iterations]); -} - -High_Priority_Task::~High_Priority_Task (void) -{ - delete [] time_; - time_ = 0; -} - -int -High_Priority_Task::open (void *) -{ - if (use_fork == 1) - { - ACE_hthread_t thr_handle; - ACE_Thread::self (thr_handle); - - if (ACE_Thread::setprio (thr_handle, priority_) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "setprio failed"), -1); - - return svc (); - } - else - { - long flags = THR_BOUND | THR_NEW_LWP | THR_SCHED_FIFO; - - // Become an active object. - if (this->activate (flags, 1, 0, this->priority_) == -1) - { - ACE_DEBUG ((LM_ERROR, "(%P|%t) task activation failed, exiting!\n%a", - -1)); - } - - return 0; - } -} - -int -High_Priority_Task::svc (void) -{ - ACE_hthread_t thr_handle; - ACE_Thread::self (thr_handle); - int prio; - - if (ACE_Thread::getprio (thr_handle, prio) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getprio failed"), -1); - -#if defined (ACE_HAS_STHREADS) - ACE_DEBUG ((LM_DEBUG, "(%P|%u|%t) High: prio = %d, priority_ = %d\n", - _lwp_self (), prio, this->priority_)); -#else /* ! ACE_HAS_STHREADS */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) High: prio = %d, priority_ = %d\n", - prio, this->priority_)); -#endif /* ! ACE_HAS_STHREADS */ - ACE_ASSERT (this->priority_ == prio); - - ACE_Time_Value pause (0, read_period); - - for (u_int i = 0; i < high_iterations; ++i) - { - time_ [i] = (u_long) ((ACE_OS::gethrtime () - starttime)/ - (ACE_UINT32) 1000000u); - ACE_OS::select (0, 0, 0, 0, &pause); - } - - done_ = 1; - - return 0; -} - -void -High_Priority_Task::print_times () const -{ - for (u_int i = 0; i < high_iterations; ++i) - { - ACE_DEBUG ((LM_INFO, " iteration %u, time %u msec\n", - i, time_ [i])); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// class Low_Priority_Task -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -class Low_Priority_Task : public ACE_Task<ACE_SYNCH> -{ -public: - Low_Priority_Task (const High_Priority_Task &); - - int open (void *); - int svc (void); - -private: - int priority_; - const High_Priority_Task &high_priority_task_; -}; - -Low_Priority_Task::Low_Priority_Task ( - const High_Priority_Task &high_priority_task) - : ACE_Task<ACE_SYNCH> (ACE_Thread_Manager::instance ()), - priority_ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, - ACE_SCOPE_THREAD)), - high_priority_task_ (high_priority_task) -{ -} - -int -Low_Priority_Task::open (void *) -{ - if (use_fork == 1) - { - ACE_hthread_t thr_handle; - ACE_Thread::self (thr_handle); - - if (ACE_Thread::setprio (thr_handle, priority_) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "setprio failed"), -1); - - return svc (); - } - else - { - long flags = THR_BOUND | THR_NEW_LWP | THR_SCHED_FIFO; - - // Become an active object. - if (this->activate (flags, 1, 0, this->priority_) == -1) - ACE_ERROR ((LM_ERROR, - "(%P|%t) task activation failed, exiting!\n%a", - -1)); - return 0; - } -} - -int -Low_Priority_Task::svc (void) -{ - ACE_hthread_t thr_handle; - ACE_Thread::self (thr_handle); - int prio; - - if (ACE_Thread::getprio (thr_handle, prio) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getprio failed"), -1); - -#if defined (ACE_HAS_STHREADS) - ACE_DEBUG ((LM_DEBUG, "(%P|%u|%t) Low: prio = %d, priority_ = %d\n", - _lwp_self (), prio, this->priority_)); -#else /* ! ACE_HAS_STHREADS */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Low: prio = %d, priority_ = %d\n", - prio, this->priority_)); -#endif /* ! ACE_HAS_STHREADS */ - ACE_ASSERT (this->priority_ == prio); - - u_long iterations = 0; - - // Chew up CPU for the entire interval. - for (; - ! high_priority_task_.done () && iterations < low_iterations; - ++iterations) - { - u_long n = 1279ul; /* Takes about 40.2 usecs on a 168 MHz Ultra2. */ - ACE::is_prime (n, - 2ul /* min_factor */, - n/2 /* max_factor */); - - if (low_yield) - ACE_OS::thr_yield (); - } - - ACE_DEBUG ((LM_INFO, "Low completed %u iterations\n", iterations)); - - return 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// function get_options -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -static int -get_options (int argc, char *argv[]) -{ - ACE_Get_Opt get_opt (argc, argv, "fh:l:n:p:y?"); - int opt; - while ((opt = get_opt ()) != EOF) { - switch (opt) { - case 'f': - use_fork = 1; - break; - case 'h': - if (ACE_OS::atoi (get_opt.optarg) >= 2) - high_iterations = ACE_OS::atoi (get_opt.optarg); - else - ACE_ERROR_RETURN ((LM_ERROR, "%n: high iterations must be >= 2\n"), - -1); - break; - case 'l': - if (ACE_OS::atoi (get_opt.optarg) >= 2) - low_iterations = ACE_OS::atoi (get_opt.optarg); - else - ACE_ERROR_RETURN ((LM_ERROR, "%n: low iterations must be >= 2\n"), -1); - break; - case 'n': - if (ACE_OS::atoi (get_opt.optarg) >= 1) - high_priority_tasks = ACE_OS::atoi (get_opt.optarg); - else - ACE_ERROR_RETURN ((LM_ERROR, "%n: number of high priority threads " - "must be >= 1\n"), -1); - break; - case 'p': - if (ACE_OS::atoi (get_opt.optarg) > 0) - read_period = ACE_OS::atoi (get_opt.optarg); - else - ACE_ERROR_RETURN ((LM_ERROR, "%n: read period > 0\n"), -1); - break; - case 'y': - low_yield = 1; - break; - case '?': - ACE_DEBUG ((LM_ERROR, "usage: %n %s\n%a", usage, 0)); - break; - default: - ACE_ERROR_RETURN ((LM_ERROR, - "%n: unknown arg, %c\nusage: %n %s\n", opt, usage), - -1); - } - } - - switch (argc - get_opt.optind) { - case 0: - // OK, no non-flag arguments. - break; - default: - ACE_ERROR_RETURN ((LM_ERROR, - "%n: too many arguments\nusage: %n %s\n", usage), - -1); - } - - return 0; -} - -#endif /* ACE_HAS_THREADS || ! ACE_LACKS_FORK */ - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// function main -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -int -main (int argc, char *argv[]) -{ - ACE_LOG_MSG->open (argv[0] ? argv[0] : "preempt"); - -#if defined (ACE_HAS_THREADS) || !defined (ACE_LACKS_FORK) - - u_int i; - - if (get_options (argc, argv)) - ACE_OS::exit (-1); - - // Enable FIFO scheduling, e.g., RT scheduling class on Solaris. - if (ACE_OS::sched_params ( - ACE_Sched_Params ( - ACE_SCHED_FIFO, - ACE_Sched_Params::priority_min (ACE_SCHED_FIFO), - ACE_SCOPE_PROCESS)) != 0) - { - if (ACE_OS::last_error () == EPERM) - ACE_DEBUG ((LM_MAX, "preempt: user is not superuser, " - "so remain in time-sharing class\n")); - else - ACE_ERROR_RETURN ((LM_ERROR, "%n: ACE_OS::sched_params failed\n%a"), - -1); - } - - High_Priority_Task *high_priority_task; - ACE_NEW_RETURN (high_priority_task, High_Priority_Task [high_priority_tasks], - 1); - - Low_Priority_Task low_priority_task (high_priority_task[0]); - - if (! use_fork) - { - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) main (), wait for threads to exit . . .\n")); - } - - // Save the start time, so that deltas can be displayed later. - starttime = ACE_OS::gethrtime (); - - // Spawn the threads/processes . . . - pid_t child = 0; - if (use_fork == 1) - { - switch ((child = ACE_OS::fork ("preempt-low_priority_process"))) - { - case -1: - ACE_ERROR ((LM_ERROR, "%p\n%a", "fork failed")); - return -1; - case 0: // In child - { - low_priority_task.open (0); - break; - } - default: // In parent - for (i = 0; i < high_priority_tasks; ++i) - { - high_priority_task[i].open (0); - } - break; - } - } - else - { - for (i = 0; i < high_priority_tasks; ++i) - { - high_priority_task[i].open (0); - } - low_priority_task.open (0); - -#if defined (ACE_HAS_THREADS) - // Wait for all threads to exit. - ACE_Thread_Manager::instance ()->wait (); -#endif /* ACE_HAS_THREADS */ - } - - // Display the time deltas. They should be about a half second apart. - if (child || ! use_fork) - { - for (i = 0; i < high_priority_tasks; ++i) - { - ACE_DEBUG ((LM_DEBUG, "High priority task %u:\n", i + 1)); - high_priority_task[i].print_times (); - } - } - - delete [] high_priority_task; - -#else /* ! ACE_HAS_THREADS && ACE_LACKS_FORK */ - ACE_UNUSED_ARG (argc); - ACE_UNUSED_ARG (argv); - ACE_ERROR ((LM_ERROR, "threads and fork not supported on this platform\n")); -#endif /* ! ACE_HAS_THREADS && ACE_LACKS_FORK */ - - return 0; -} |