diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-05-27 17:59:53 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-05-27 17:59:53 +0000 |
commit | 8da0c916b311baa3adcbf34185091a48b1b427c6 (patch) | |
tree | dc98ba6bcdfba6e8f375872d384c7e2d252cdc23 | |
parent | ae469647c6f3c7b5ac7ee9a7b9d549e2c50e8070 (diff) | |
download | ATCD-8da0c916b311baa3adcbf34185091a48b1b427c6.tar.gz |
added calibrate ()
-rw-r--r-- | ace/High_Res_Timer.cpp | 89 | ||||
-rw-r--r-- | ace/High_Res_Timer.h | 11 | ||||
-rw-r--r-- | ace/High_Res_Timer.i | 8 |
3 files changed, 97 insertions, 11 deletions
diff --git a/ace/High_Res_Timer.cpp b/ace/High_Res_Timer.cpp index 6fd84db99ae..0f648c3e090 100644 --- a/ace/High_Res_Timer.cpp +++ b/ace/High_Res_Timer.cpp @@ -7,12 +7,19 @@ #include "ace/High_Res_Timer.i" #endif /* __ACE_INLINE__ */ +#include "ace/Stats.h" + ACE_ALLOC_HOOK_DEFINE(ACE_High_Res_Timer) // For Intel platforms, a scale factor is required for // ACE_OS::gethrtime. We'll still set this to one to prevent division // by zero errors. -#if defined (ACE_WIN32) && ! defined (ACE_HAS_WINCE) +#if defined (ACE_HAS_PENTIUM) + +# include "ace/Object_Manager.h" +# include "ace/Synch.h" + +# if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) u_long ACE_High_Res_Timer::get_registry_scale_factor (void) @@ -49,8 +56,16 @@ ACE_High_Res_Timer::get_registry_scale_factor (void) } /* static */ -ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = ACE_High_Res_Timer::get_registry_scale_factor (); - + // Initialize the global_scale_factor_ to 1. The first + // ACE_High_Res_Timer instance construction will override this + // value. + ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = 1; +# elif defined (ghs) || defined (__GNUG__) + // Initialize the global_scale_factor_ to 1. The first + // ACE_High_Res_Timer instance construction will override this + // value. + ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = 1; +# endif /* ! ACE_WIN32 && ! ghs && ! __GNUG__ */ #elif defined (ACE_HAS_HI_RES_TIMER) || defined (ACE_HAS_AIX_HI_RES_TIMER) || \ defined (ACE_HAS_CLOCK_GETTIME) || defined (ACE_PSOS) || \ defined (CHORUS) || defined (linux) @@ -64,6 +79,74 @@ ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = ACE_High_Res_Timer::get_re ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = 1; #endif /* ACE_WIN32 */ +ACE_High_Res_Timer::ACE_High_Res_Timer (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::ACE_High_Res_Timer"); + + this->reset (); + +#if defined (ACE_HAS_PENTIUM) && \ + ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || \ + defined (ghs) || defined (__GNUG__)) + // Check if the global scale factor needs to be set, and do if so. + if (ACE_High_Res_Timer::global_scale_factor_ == 1) + { + // Grab ACE's static object lock. This doesn't have anything to + // do with static objects; it's just a convenient lock to use. + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, + *ACE_Static_Object_Lock::instance ())); + + // Double check + if (ACE_High_Res_Timer::global_scale_factor_ == 1) + { +# if defined (ACE_WIN32) + ACE_High_Res_Timer::global_scale_factor ( + ACE_High_Res_Timer::get_registry_scale_factor ()); +# else /* ! ACE_WIN32 */ + ACE_High_Res_Timer::calibrate (); +# endif /* ! ACE_WIN32 */ + } + } +#endif /* ACE_HAS_PENTIUM && ((WIN32 && ! WINCE) || ghs || __GNUG__) */ +} + +ACE_UINT32 +ACE_High_Res_Timer::calibrate (const ACE_UINT32 usec, + const u_int iterations) +{ + const ACE_Time_Value sleep_time (0, usec); + ACE_Stats delta_hrtime; + ACE_Stats actual_sleeps; /* In units of 100 usec, to avoid overflow. */ + + for (u_int i = 0; i < iterations; ++i) + { + const ACE_Time_Value actual_start = ACE_OS::gettimeofday (); + const ACE_hrtime_t start = ACE_OS::gethrtime (); + ACE_OS::sleep (sleep_time); + const ACE_hrtime_t stop = ACE_OS::gethrtime (); + const ACE_Time_Value actual_delta = + ACE_OS::gettimeofday () - actual_start; + + // Store the sample. + delta_hrtime.sample ((stop - start) / ACE_static_cast (ACE_UINT32, 1u)); + actual_sleeps.sample (actual_delta.msec () * 100u); + } + + // Calculate the mean value of the samples, with no fractional + // precision. Use it for the global scale factor. + ACE_Stats_Value ticks (0); + delta_hrtime.mean (ticks); + + ACE_Stats_Value actual_sleep (0); + actual_sleeps.mean (actual_sleep); + + const ACE_UINT32 scale_factor = ticks.whole () / actual_sleep.whole () / + 10u /* usec/100 usec */; + ACE_High_Res_Timer::global_scale_factor (scale_factor); + + return scale_factor; +} + void ACE_High_Res_Timer::dump (void) const { diff --git a/ace/High_Res_Timer.h b/ace/High_Res_Timer.h index 84933d0eff7..d3b4d1a3566 100644 --- a/ace/High_Res_Timer.h +++ b/ace/High_Res_Timer.h @@ -83,6 +83,17 @@ public: // This is basically a no-op on CE because there is no concept of // environment variable on CE. + static ACE_UINT32 calibrate (const ACE_UINT32 usec = 500000, + const u_int iterations = 10); + // Set (and return, for info) the global scale factor by sleeping + // for <usec> and counting the number of intervening clock cycles. + // Average over <iterations> of <usec> each. On some platforms, + // such as Pentiums, this is called automatically during the first + // ACE_High_Res_Timer construction with the default parameter + // values. An application can override that by calling calibrate + // with any desired parameter values _prior_ to constructing the + // first ACE_High_Res_Timer instance. + ACE_High_Res_Timer (void); // Initialize the timer. diff --git a/ace/High_Res_Timer.i b/ace/High_Res_Timer.i index 44b991509c6..8883c189434 100644 --- a/ace/High_Res_Timer.i +++ b/ace/High_Res_Timer.i @@ -61,14 +61,6 @@ ACE_High_Res_Timer::gettime (const ACE_OS::ACE_HRTimer_Op op) } ACE_INLINE -ACE_High_Res_Timer::ACE_High_Res_Timer (void) -{ - ACE_TRACE ("ACE_High_Res_Timer::ACE_High_Res_Timer"); - - this->reset (); -} - -ACE_INLINE ACE_High_Res_Timer::~ACE_High_Res_Timer (void) { } |