ACE_High_Res_Timer Class Reference

A high resolution timer class wrapper that encapsulates OS-specific high-resolution timers, such as those found on Solaris, AIX, Win32/Pentium, and VxWorks. More...

#include <High_Res_Timer.h>

List of all members.

Public Member Functions

 ACE_High_Res_Timer (void)
 Initialize the timer.

 ~ACE_High_Res_Timer (void)
 Destructor.

void reset (void)
 Reinitialize the timer.

void start (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)
 Start timing.

void stop (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)
 Stop timing.

void elapsed_time (ACE_Time_Value &tv) const
 Set tv to the number of microseconds elapsed.

void elapsed_time (ACE_hrtime_t &nanoseconds) const
 Set nanoseconds to the number of nanoseconds elapsed.

void elapsed_microseconds (ACE_hrtime_t &usecs) const
 Sets usecs to the elapsed (stop - start) time in microseconds.

void start_incr (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)
 Start incremental timing.

void stop_incr (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)
 Stop incremental timing.

void elapsed_time_incr (ACE_Time_Value &tv) const
void elapsed_time_incr (ACE_hrtime_t &nanoseconds) const
void print_total (const ACE_TCHAR *message, const int iterations=1, ACE_HANDLE handle=ACE_STDOUT) const
void print_ave (const ACE_TCHAR *message, const int iterations=1, ACE_HANDLE handle=ACE_STDOUT) const
 Print average time.

void dump (void) const
 Dump the state of an object.


Static Public Member Functions

void global_scale_factor (ACE_UINT32 gsf)
ACE_UINT32 global_scale_factor (void)
 Returns the global_scale_factor.

int get_env_global_scale_factor (const ACE_TCHAR *env=ACE_LIB_TEXT("ACE_SCALE_FACTOR"))
ACE_UINT32 calibrate (const ACE_UINT32 usec=500000, const u_int iterations=10)
ACE_Time_Value gettimeofday_hr (void)
ACE_Time_Value gettimeofday (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)
void hrtime_to_tv (ACE_Time_Value &tv, const ACE_hrtime_t hrt)
 Converts an to using global_scale_factor_.


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Static Private Member Functions

ACE_hrtime_t gettime (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)
ACE_hrtime_t elapsed_hrtime (const ACE_hrtime_t end, const ACE_hrtime_t start)

Private Attributes

ACE_hrtime_t start_
 Starting time.

ACE_hrtime_t end_
 Ending time.

ACE_hrtime_t total_
 Total elapsed time.

ACE_hrtime_t start_incr_
 Start time of incremental timing.


Static Private Attributes

ACE_UINT32 global_scale_factor_ = 1u
int global_scale_factor_status_ = 0


Detailed Description

A high resolution timer class wrapper that encapsulates OS-specific high-resolution timers, such as those found on Solaris, AIX, Win32/Pentium, and VxWorks.

Most of the member functions don't return values. The only reason that one would fail is if high-resolution time isn't supported on the platform. To avoid impacting performance and complicating the interface, in that case, <ACE_OS::gettimeofday> is used instead. The global scale factor is required for platforms that have high-resolution timers that return units other than microseconds, such as clock ticks. It is represented as a static u_long, can only be accessed through static methods, and is used by all instances of High Res Timer. The member functions that return or print times use the global scale factor. They divide the "time" that they get from <ACE_OS::gethrtime> by global_scale_factor_ to obtain the time in microseconds. Its units are therefore 1/microsecond. On Windows the global_scale_factor_ units are 1/millisecond. There's a macro which gives the units/second. Because it's possible that the units/second changes in the future, it's recommended to use it instead of a "hard coded" solution. Dependend on the platform and used class members, there's a maximum elapsed period before overflow (which is not checked). Look at the documentation with some members functions. On some (most?) implementations it's not recommended to measure "long" timeperiods, because the error's can accumulate fast. This is probably not a problem profiling code, but could be on if the high resolution timer class is used to initiate actions after a "long" timeout. On Solaris, a scale factor of 1000 should be used because its high-resolution timer returns nanoseconds. However, on Intel platforms, we use RDTSC which returns the number of clock ticks since system boot. For a 200MHz cpu, each clock tick is 1/200 of a microsecond; the global_scale_factor_ should therefore be 200 or 200000 if it's in unit/millisecond. On Windows ::QueryPerformanceCounter() is used, which can be a different implementation depending on the used windows HAL (Hardware Abstraction Layer). On some it uses the PC "timer chip" while it uses RDTSC on others.

Note:
The elapsed time calculations in the print methods use ACE_hrtime_t values. Those methods do _not_ check for overflow!

Gabe <begeddov@proaxis.com> raises this issue regarding <ACE_OS::gethrtime>: on multi-processors, the processor that you query for your <timer.stop> value might not be the one you queried for <timer.start>. Its not clear how much divergence there would be, if any. This issue is not mentioned in the Solaris 2.5.1 gethrtime man page. A RDTSC NOTE: RDTSC is the Intel Pentium read-time stamp counter and is actualy a 64 bit clock cycle counter, which is increased with every cycle. It has a low overhead and can be read within 16 (pentium) or 32 (pentium II,III,...) cycles, but it doesn't serialize the processor, which could give wrong timings when profiling very short code fragments. Problematic is that some power sensitive devices (laptops for example, but probably also embedded devices), do change the cycle rate while running. Some pentiums can run on (at least) two clock frequency's. Another problem arises with multiprocessor computers, there are reports that the different RDTSC's are not always kept in sync. A windows "timer chip" NOTE: (8254-compatible real-time clock) When ::QueryPerformanceCounter() uses the 8254 it has a frequency off about 1.193 Mhz (or sometimes 3.579 Mhz?) and reading it requires some time (several thousand cycles).

Definition at line 100 of file High_Res_Timer.h.


Constructor & Destructor Documentation

ACE_High_Res_Timer::ACE_High_Res_Timer void   ) 
 

Initialize the timer.

Definition at line 254 of file High_Res_Timer.cpp.

References ACE_TRACE, global_scale_factor(), and reset().

00255 {
00256   ACE_TRACE ("ACE_High_Res_Timer::ACE_High_Res_Timer");
00257 
00258   this->reset ();
00259 
00260   // Make sure that the global scale factor is set.
00261   (void) global_scale_factor ();
00262 }

ACE_INLINE ACE_High_Res_Timer::~ACE_High_Res_Timer void   ) 
 

Destructor.

Definition at line 121 of file High_Res_Timer.inl.

00122 {
00123 }


Member Function Documentation

ACE_UINT32 ACE_High_Res_Timer::calibrate const ACE_UINT32  usec = 500000,
const u_int  iterations = 10
[static]
 

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. Beware for platforms that can change the cycle rate on the fly.

Definition at line 265 of file High_Res_Timer.cpp.

References ACE_HRTIME_CONVERSION, ACE_hrtime_t, ACE_OS::gethrtime(), ACE_OS::gettimeofday(), global_scale_factor(), ACE_Stats::mean(), ACE_Time_Value::msec(), ACE_Stats::sample(), ACE_OS::sleep(), and ACE_Stats_Value::whole().

Referenced by global_scale_factor().

00267 {
00268   const ACE_Time_Value sleep_time (0, usec);
00269   ACE_Stats delta_hrtime;
00270   // In units of 100 usec, to avoid overflow.
00271   ACE_Stats actual_sleeps;
00272 
00273   for (u_int i = 0;
00274        i < iterations;
00275        ++i)
00276     {
00277       const ACE_Time_Value actual_start =
00278         ACE_OS::gettimeofday ();
00279       const ACE_hrtime_t start =
00280         ACE_OS::gethrtime ();
00281       ACE_OS::sleep (sleep_time);
00282       const ACE_hrtime_t stop =
00283         ACE_OS::gethrtime ();
00284       const ACE_Time_Value actual_delta =
00285         ACE_OS::gettimeofday () - actual_start;
00286 
00287       // Store the sample.
00288       delta_hrtime.sample (ACE_HRTIME_CONVERSION (stop - start));
00289       actual_sleeps.sample (actual_delta.msec () * 100u);
00290     }
00291 
00292   // Calculate the mean value of the samples, with no fractional
00293   // precision.  Use it for the global scale factor.
00294   ACE_Stats_Value ticks (0);
00295   delta_hrtime.mean (ticks);
00296 
00297   ACE_Stats_Value actual_sleep (0);
00298   actual_sleeps.mean (actual_sleep);
00299 
00300   // The addition of 5 below rounds instead of truncates.
00301   const ACE_UINT32 scale_factor =
00302     (ticks.whole () / actual_sleep.whole () + 5) /
00303     10u /* usec/100 usec */;
00304   ACE_High_Res_Timer::global_scale_factor (scale_factor);
00305 
00306   return scale_factor;
00307 }

void ACE_High_Res_Timer::dump void   )  const
 

Dump the state of an object.

Definition at line 310 of file High_Res_Timer.cpp.

References ACE_BEGIN_DUMP, ACE_CU64_TO_CU32, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_TRACE, end_, global_scale_factor(), LM_DEBUG, start_incr_, and total_.

Referenced by ACE_Profile_Timer::dump().

00311 {
00312 #if defined (ACE_HAS_DUMP)
00313   ACE_TRACE ("ACE_High_Res_Timer::dump");
00314 
00315   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00316   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nglobal_scale_factor_: %u\n"),
00317              global_scale_factor ()));
00318 #if defined (ACE_LACKS_LONGLONG_T)
00319   ACE_DEBUG ((LM_DEBUG,
00320              ACE_LIB_TEXT (":\nstart_.hi ():     %8x; start_.lo ():      %8x;\n")
00321              ACE_LIB_TEXT ("end_.hi ():       %8x; end_.lo ():        %8x;\n")
00322              ACE_LIB_TEXT ("total_.hi ():     %8x; total_.lo ():      %8x;\n")
00323              ACE_LIB_TEXT ("start_incr_.hi () %8x; start_incr_.lo (): %8x;\n"),
00324              start_.hi (), start_.lo (),
00325              end_.hi (), end_.lo (),
00326              total_.hi (), total_.lo (),
00327              start_incr_.hi (), start_incr_.lo ()));
00328 #else  /* ! ACE_LACKS_LONGLONG_T */
00329   ACE_DEBUG ((LM_DEBUG,
00330              ACE_LIB_TEXT (":\nstart_.hi ():     %8x; start_.lo ():      %8x;\n")
00331              ACE_LIB_TEXT ("end_.hi ():       %8x; end_.lo ():        %8x;\n")
00332              ACE_LIB_TEXT ("total_.hi ():     %8x; total_.lo ():      %8x;\n")
00333              ACE_LIB_TEXT ("start_incr_.hi () %8x; start_incr_.lo (): %8x;\n"),
00334              ACE_CU64_TO_CU32 (start_ >> 32),
00335              ACE_CU64_TO_CU32 (start_ & 0xfffffffful),
00336              ACE_CU64_TO_CU32 (end_ >> 32),
00337              ACE_CU64_TO_CU32 (end_ & 0xfffffffful),
00338              ACE_CU64_TO_CU32 (total_ >> 32),
00339              ACE_CU64_TO_CU32 (total_ & 0xfffffffful),
00340              ACE_CU64_TO_CU32 (start_incr_ >> 32),
00341              ACE_CU64_TO_CU32 (start_incr_ & 0xfffffffful)));
00342 #endif /* ! ACE_LACKS_LONGLONG_T */
00343   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00344 #endif /* ACE_HAS_DUMP */
00345 }

ACE_INLINE ACE_hrtime_t ACE_High_Res_Timer::elapsed_hrtime const ACE_hrtime_t  end,
const ACE_hrtime_t  start
[static, private]
 

Calculate the difference between two ACE_hrtime_t values. It is assumed that the end time is later than start time, so if end is a smaller value, the time counter has wrapped around.

Definition at line 112 of file High_Res_Timer.inl.

References ACE_hrtime_t.

Referenced by elapsed_microseconds(), elapsed_time(), and stop_incr().

00114 {
00115   if (end > start)
00116     return end - start;
00117   return (~start + 1 + end);     // Wrapped-around counter diff
00118 }

ACE_INLINE void ACE_High_Res_Timer::elapsed_microseconds ACE_hrtime_t usecs  )  const
 

Sets usecs to the elapsed (stop - start) time in microseconds.

Will overflow on windows when measuring more than appox. 2^^54 ticks. Is still more than 48 days with a 4 Ghz counter.

Definition at line 156 of file High_Res_Timer.inl.

References ACE_hrtime_t, elapsed_hrtime(), and global_scale_factor().

00157 {
00158   ACE_hrtime_t elapsed = ACE_High_Res_Timer::elapsed_hrtime (this->end_,
00159                                                              this->start_);
00160 #if defined (ACE_WIN32)
00161   // Win32 scale factor is in msec
00162   // This could give overflow when measuring a long time with a
00163   // big global_scale_factor() (> 48 days with a 4Ghz tick freq.)
00164   // To be looked after in the future.
00165   usecs = (ACE_hrtime_t) ((elapsed * 1000) / global_scale_factor ());
00166 #else
00167   usecs = (ACE_hrtime_t) (elapsed / global_scale_factor ());
00168 #endif
00169 }

void ACE_High_Res_Timer::elapsed_time ACE_hrtime_t nanoseconds  )  const
 

Set nanoseconds to the number of nanoseconds elapsed.

Will overflow when measuring more than 194 day's.

Definition at line 402 of file High_Res_Timer.cpp.

References ACE_hrtime_t, elapsed_hrtime(), and global_scale_factor().

00403 {
00404   // Please do _not_ rearrange this equation.  It is carefully
00405   // designed and tested to avoid overflow on machines that don't have
00406   // native 64-bit ints. In particular, division can be a problem.
00407   // For more background on this, please see bugzilla #1024.
00408 #if defined (ACE_WIN32)
00409   nanoseconds = ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_)
00410             * (1024000000u / ACE_High_Res_Timer::global_scale_factor());
00411 #else
00412   nanoseconds = ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_)
00413             * (1024000u / ACE_High_Res_Timer::global_scale_factor ());
00414 #endif /* ACE_WIN32 */
00415   // Caution - Borland has a problem with >>=, so resist the temptation.
00416   nanoseconds = nanoseconds >> 10;
00417   // Right shift is implemented for non native 64-bit ints
00418   // operator/ only for a 32 bit result !
00419 }

void ACE_High_Res_Timer::elapsed_time ACE_Time_Value tv  )  const
 

Set tv to the number of microseconds elapsed.

Could overflow within hours on windows with emulated 64 bit int's and a fast counter. VC++ and Borland normaly use __int64 and so normaly don't have this problem.

Definition at line 359 of file High_Res_Timer.cpp.

References elapsed_hrtime(), and hrtime_to_tv().

Referenced by ACE_Profile_Timer::elapsed_time(), print_ave(), and print_total().

00360 {
00361   hrtime_to_tv (tv,
00362                 ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_));
00363 }

void ACE_High_Res_Timer::elapsed_time_incr ACE_hrtime_t nanoseconds  )  const
 

Set to the number of nanoseconds elapsed between all calls to start_incr and stop_incr.

Definition at line 422 of file High_Res_Timer.cpp.

References ACE_hrtime_t, global_scale_factor(), and total_.

00423 {
00424   // Same as above.
00425 #if defined (ACE_WIN32)
00426   nanoseconds = this->total_
00427             * (1024000000u / ACE_High_Res_Timer::global_scale_factor());
00428 #else
00429   nanoseconds = this->total_
00430             * (1024000u / ACE_High_Res_Timer::global_scale_factor ());
00431 #endif
00432   // Caution - Borland has a problem with >>=, so resist the temptation.
00433   nanoseconds = nanoseconds >> 10;
00434 }

void ACE_High_Res_Timer::elapsed_time_incr ACE_Time_Value tv  )  const
 

Set tv to the number of microseconds elapsed between all calls to start_incr and stop_incr.

Definition at line 396 of file High_Res_Timer.cpp.

References hrtime_to_tv(), and total_.

00397 {
00398   hrtime_to_tv (tv, total_);
00399 }

int ACE_High_Res_Timer::get_env_global_scale_factor const ACE_TCHAR env = ACE_LIB_TEXT("ACE_SCALE_FACTOR")  )  [static]
 

Sets the global_scale_factor to the value in the environment variable. Returns 0 on success, -1 on failure.

Note:
If env points to string "0" (value zero), this call will fail. This is basically a no-op on CE because there is no concept of environment variable on CE.

Definition at line 524 of file High_Res_Timer.cpp.

References ACE_TCHAR, ACE_TEXT_ALWAYS_CHAR, ACE_OS::atoi(), ACE_OS::getenv(), and global_scale_factor().

00525 {
00526 #if !defined (ACE_HAS_WINCE)
00527   if (env != 0)
00528     {
00529       const char *env_value = ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (env));
00530       if (env_value != 0)
00531         {
00532           int value = ACE_OS::atoi (env_value);
00533           if (value > 0)
00534             {
00535               ACE_High_Res_Timer::global_scale_factor (value);
00536               return 0;
00537             }
00538         }
00539     }
00540 #else
00541   ACE_UNUSED_ARG (env);
00542 #endif /* !ACE_HAS_WINCE */
00543   return -1;
00544 }

ACE_INLINE ACE_hrtime_t ACE_High_Res_Timer::gettime const ACE_OS::ACE_HRTimer_Op  = ACE_OS::ACE_HRTIMER_GETTIME  )  [static, private]
 

For internal use: gets the high-resolution time using <ACE_OS::gethrtime>. Except on platforms that require that the be set, such as ACE_WIN32, uses the low-resolution clock if the has not been set.

Definition at line 91 of file High_Res_Timer.inl.

References ACE_ONE_SECOND_IN_USECS, ACE_OS::gethrtime(), ACE_OS::gettimeofday(), global_scale_factor(), global_scale_factor_status_, ACE_Time_Value::sec(), and ACE_Time_Value::usec().

Referenced by start(), start_incr(), stop(), and stop_incr().

00092 {
00093 #if defined (ACE_WIN32)
00094   // Get the global scale factor if there isn't one yet.
00095   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00096     ACE_High_Res_Timer::global_scale_factor ();
00097 
00098   // If there isn't a high-res timer, use gettimeofday ();
00099   if (ACE_High_Res_Timer::global_scale_factor_status_ == -1)
00100     {
00101       ACE_Time_Value tv = ACE_OS::gettimeofday ();
00102       // Return the time in microseconds because the global_scale_factor_
00103       // is 1.
00104       return tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec ();
00105     }
00106 #endif /* ACE_WIN32 */
00107 
00108   return ACE_OS::gethrtime (op);
00109 }

ACE_INLINE ACE_Time_Value ACE_High_Res_Timer::gettimeofday const ACE_OS::ACE_HRTimer_Op  = ACE_OS::ACE_HRTIMER_GETTIME  )  [static]
 

Deprecated:
THIS FUNCTION IS DEPRECATED. PLEASE USE <ACE_OS::gettimeofday> INSTEAD! Calls <ACE_High_Res_Timer::hrtime_to_tv> passing <ACE_OS::gethrtime>. This function can be used to parameterize objects such as <ACE_Timer_Queue::gettimeofday>. If is not set, and we're on a platform that requires (e.g., Win32), ACE_OS::gettimeofday will be used instead of <ACE_OS::gethrtime>. This allows applications on Intel to use even when is not set. However, setting the appropriately will result in the finest resolution possible.

Definition at line 58 of file High_Res_Timer.inl.

References ACE_OS::gettimeofday(), global_scale_factor(), global_scale_factor_status_, and hrtime_to_tv().

Referenced by gettimeofday_hr().

00059 {
00060 #if defined (ACE_WIN32)
00061   // Get the global scale factor if there isn't one yet.
00062   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00063     ACE_High_Res_Timer::global_scale_factor ();
00064 
00065   // If there isn't a high-res timer, use gettimeofday ();
00066   if (ACE_High_Res_Timer::global_scale_factor_status_ == -1)
00067     return ACE_OS::gettimeofday ();
00068 #endif /* ACE_WIN32 */
00069 
00070   ACE_Time_Value tv;
00071   ACE_High_Res_Timer::hrtime_to_tv (tv,
00072                                     ACE_OS::gethrtime (op));
00073   return tv;
00074 }

ACE_INLINE ACE_Time_Value ACE_High_Res_Timer::gettimeofday_hr void   )  [static]
 

Get the current "time" as the high resolution counter at this time. This is intended to be useful for supplying to a ACE_Timer_Queue as the gettimeofday function, thereby basing the timer calculations on the high res timer rather than wall clock time.

Definition at line 84 of file High_Res_Timer.inl.

References gettimeofday().

00085 {
00086   return ACE_High_Res_Timer::gettimeofday ();
00087 }

ACE_UINT32 ACE_High_Res_Timer::global_scale_factor void   )  [static]
 

Returns the global_scale_factor.

Definition at line 192 of file High_Res_Timer.cpp.

References ACE_GUARD_RETURN, ACE_HR_SCALE_CONVERSION, ACE_ONE_SECOND_IN_USECS, ACE_UINT64, calibrate(), global_scale_factor(), global_scale_factor_, and global_scale_factor_status_.

Referenced by ACE_High_Res_Timer(), ACE_Metrics_Cache< ACE_LOCK, ALLOCATOR >::ACE_Metrics_Cache(), calibrate(), elapsed_microseconds(), elapsed_time(), elapsed_time_incr(), get_env_global_scale_factor(), gettime(), gettimeofday(), hrtime_to_tv(), and ACE_Timeprobe_Ex< ACE_LOCK, ALLOCATOR >::print_times().

00193 {
00194 #if (defined (ACE_WIN32) || defined (ACE_HAS_POWERPC_TIMER) || \
00195      defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER)) && \
00196     !defined (ACE_HAS_HI_RES_TIMER) && \
00197     ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || \
00198      defined (ghs) || defined (__GNUG__) || defined (__KCC) || \
00199      defined (__INTEL_COMPILER))
00200   // Check if the global scale factor needs to be set, and do if so.
00201   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00202     {
00203       // Grab ACE's static object lock.  This doesn't have anything to
00204       // do with static objects; it's just a convenient lock to use.
00205       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00206                                 *ACE_Static_Object_Lock::instance (), 0));
00207 
00208       // Double check
00209       if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00210         {
00211 #         if defined (ACE_WIN32)
00212             LARGE_INTEGER freq;
00213             if (::QueryPerformanceFrequency (&freq))
00214               {
00215                 // We have a high-res timer
00216 #             if defined (ACE_LACKS_LONGLONG_T)
00217                 ACE_UINT64 uint64_freq(freq.u.LowPart, (ACE_UINT32) freq.u.HighPart);
00218                 ACE_High_Res_Timer::global_scale_factor
00219                   (uint64_freq / (ACE_UINT32) ACE_ONE_SECOND_IN_USECS);
00220 #             else
00221                 ACE_High_Res_Timer::global_scale_factor
00222                   (static_cast<unsigned int> (freq.QuadPart / ACE_HR_SCALE_CONVERSION));
00223 #             endif // (ACE_LACKS_LONGLONG_T)
00224 
00225                 ACE_High_Res_Timer::global_scale_factor_status_ = 1;
00226               }
00227             else
00228               // High-Res timers not supported
00229               ACE_High_Res_Timer::global_scale_factor_status_ = -1;
00230 
00231             return ACE_High_Res_Timer::global_scale_factor_;
00232 
00233 #         elif defined (linux)
00234             ACE_High_Res_Timer::global_scale_factor (ACE_High_Res_Timer::get_cpuinfo ());
00235 #         endif /* ! ACE_WIN32 && ! (linux && __alpha__) */
00236 
00237 #         if !defined (ACE_WIN32)
00238           if (ACE_High_Res_Timer::global_scale_factor_ == 1u)
00239             // Failed to retrieve CPU speed from system, so calculate it.
00240             ACE_High_Res_Timer::calibrate ();
00241 #         endif // (ACE_WIN32)
00242         }
00243     }
00244 
00245   ACE_High_Res_Timer::global_scale_factor_status_ = 1;
00246 #endif /* (ACE_WIN32 || ACE_HAS_POWERPC_TIMER || \
00247            ACE_HAS_PENTIUM || ACE_HAS_ALPHA_TIMER) && \
00248           ! ACE_HAS_HI_RES_TIMER &&
00249           ((WIN32 && ! WINCE) || ghs || __GNUG__) */
00250 
00251   return ACE_High_Res_Timer::global_scale_factor_;
00252 }

ACE_INLINE void ACE_High_Res_Timer::global_scale_factor ACE_UINT32  gsf  )  [static]
 

global_scale_factor_ is set to gsf. All High_Res_Timers use global_scale_factor_. This allows applications to set the scale factor just once for all High_Res_Timers. Check High_Res_Timer.cpp for the default global_scale_factors for several platforms. For many platforms (e.g., Solaris), the global_scale_factor_ is set to 1000 so that need not be set. Careful, a of 0 will cause division by zero exceptions. Depending on the platform its units are 1/microsecond or 1/millisecond. Use inside calculations instead a hardcoded value.

Definition at line 172 of file High_Res_Timer.inl.

References global_scale_factor_.

Referenced by dump(), global_scale_factor(), and hrtime_to_tv().

00173 {
00174   global_scale_factor_ = gsf;
00175 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE void ACE_High_Res_Timer::hrtime_to_tv ACE_Time_Value tv,
const ACE_hrtime_t  hrt
[static]
 

Converts an to using global_scale_factor_.

Definition at line 21 of file High_Res_Timer.inl.

References ACE_HR_SCALE_CONVERSION, ACE_hrtime_t, global_scale_factor(), ACE_Time_Value::sec(), and ACE_Time_Value::usec().

Referenced by elapsed_time(), elapsed_time_incr(), gettimeofday(), ACE_Timeprobe_Ex< ACE_LOCK, ALLOCATOR >::print_absolute_times(), ACE_Metrics_Cache< ACE_LOCK, ALLOCATOR >::report_dequeue_start(), ACE_Metrics_Cache< ACE_LOCK, ALLOCATOR >::report_dequeue_stop(), ACE_Metrics_Cache< ACE_LOCK, ALLOCATOR >::report_enqueue_start(), and ACE_Metrics_Cache< ACE_LOCK, ALLOCATOR >::report_enqueue_stop().

00023 {
00024   // The following are based on the units of global_scale_factor_
00025   // being 1/microsecond.  Therefore, dividing by it converts
00026   // clock ticks to microseconds.
00027   tv.sec ((long) (hrt / (ACE_UINT32) ACE_HR_SCALE_CONVERSION /
00028                   global_scale_factor ()));
00029 
00030   // Calculate usec in a manner that's compatible with ACE_U_LongLong.
00031   // hrt = (tv.sec * ACE_ONE_SECOND_IN_USECS + tv.usec) * global_scale_factor_
00032   // tv.usec = hrt / global_scale_factor_ - tv.sec * ACE_ONE_SECOND_IN_USECS
00033   // That first term will be lossy, so factor out global_scale_factor_:
00034   // tv.usec = (hrt - tv.sec * ACE_ONE_SECOND_IN_USECS * global_scale_factor_)/
00035   //           global_scale_factor
00036   ACE_hrtime_t tmp = tv.sec ();
00037   tmp *= ((ACE_UINT32) ACE_HR_SCALE_CONVERSION * global_scale_factor ());
00038 #if defined (ACE_WIN32)
00039   // Win32's scale factor is in ticks/msec, so multiply up to usec.
00040   ACE_hrtime_t subsec = hrt - tmp;         // Remainder of ticks < 1sec
00041   ACE_UINT32 msec = (ACE_UINT32) (subsec / global_scale_factor ());  // #msec
00042   ACE_hrtime_t usec64 = subsec - (msec * global_scale_factor ());
00043 #  if defined (ACE_LACKS_LONGLONG_T)
00044   ACE_UINT32 usec = usec64.lo();
00045 #  else
00046   ACE_UINT32 usec = (ACE_UINT32) usec64;
00047 #  endif // ACE_LACKS_LONGLONG_T
00048   //     (tick * usec/msec) / tick/msec     = usec
00049   usec = (usec * 1000)      / (ACE_UINT32) global_scale_factor ();
00050   tv.usec ((msec * 1000) + usec);
00051 #else
00052   tv.usec ((long) ((hrt - tmp) / global_scale_factor ()));
00053 #endif
00054 }

void ACE_High_Res_Timer::print_ave const ACE_TCHAR message,
const int  iterations = 1,
ACE_HANDLE  handle = ACE_STDOUT
const
 

Print average time.

Definition at line 438 of file High_Res_Timer.cpp.

References ACE_hrtime_t, ACE_LIB_TEXT, ACE_ONE_SECOND_IN_NSECS, ACE_TCHAR, ACE_TRACE, elapsed_time(), ACE_OS::sprintf(), and ACE_OS::write().

00441 {
00442   ACE_TRACE ("ACE_High_Res_Timer::print_ave");
00443 
00444   // Get the total number of nanoseconds elapsed.
00445   ACE_hrtime_t total_nanoseconds;
00446   this->elapsed_time (total_nanoseconds);
00447 
00448   // Separate to seconds and nanoseconds.
00449   u_long total_secs =
00450     static_cast<u_long> (total_nanoseconds / (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00451   ACE_UINT32 extra_nsecs =
00452     static_cast<ACE_UINT32> (total_nanoseconds % (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00453 
00454   ACE_TCHAR buf[100];
00455   if (count > 1)
00456     {
00457       ACE_hrtime_t avg_nsecs = total_nanoseconds / (ACE_UINT32) count;
00458       ACE_OS::sprintf (buf,
00459                        ACE_LIB_TEXT (" count = %d, total (secs %lu, usecs %u), avg usecs = %lu\n"),
00460                        count,
00461                        total_secs,
00462                        (extra_nsecs + 500u) / 1000u,
00463                        (u_long) ((avg_nsecs + 500u) / 1000u));
00464     }
00465   else
00466     ACE_OS::sprintf (buf,
00467                      ACE_LIB_TEXT (" total %3lu.%06lu secs\n"),
00468                      total_secs,
00469                      (extra_nsecs + 500lu) / 1000lu);
00470 
00471   ACE_OS::write (handle,
00472                  str,
00473                  ACE_OS::strlen (str));
00474   ACE_OS::write (handle,
00475                  buf,
00476                  ACE_OS::strlen (buf));
00477 }

void ACE_High_Res_Timer::print_total const ACE_TCHAR message,
const int  iterations = 1,
ACE_HANDLE  handle = ACE_STDOUT
const
 

Print total time.

Note:
only use if incremental timings had been used!

Definition at line 480 of file High_Res_Timer.cpp.

References ACE_hrtime_t, ACE_LIB_TEXT, ACE_ONE_SECOND_IN_NSECS, ACE_TCHAR, ACE_TRACE, elapsed_time(), ACE_OS::sprintf(), total_, and ACE_OS::write().

00483 {
00484   ACE_TRACE ("ACE_High_Res_Timer::print_total");
00485 
00486   // Get the total number of nanoseconds elapsed.
00487   ACE_hrtime_t total_nanoseconds;
00488   this->elapsed_time (total_nanoseconds);
00489 
00490   // Separate to seconds and nanoseconds.
00491   u_long total_secs =
00492     (u_long) (total_nanoseconds / (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00493   ACE_UINT32 extra_nsecs =
00494     (ACE_UINT32) (total_nanoseconds % (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00495 
00496   ACE_TCHAR buf[100];
00497   if (count > 1)
00498     {
00499       ACE_hrtime_t avg_nsecs = this->total_ / (ACE_UINT32) count;
00500 
00501       ACE_OS::sprintf (buf,
00502                        ACE_LIB_TEXT (" count = %d, total (secs %lu, usecs %u), avg usecs = %lu\n"),
00503                        count,
00504                        total_secs,
00505                        (extra_nsecs + 500u) / 1000u,
00506                        (u_long) ((avg_nsecs + 500u) / 1000u));
00507     }
00508   else
00509     ACE_OS::sprintf (buf,
00510                      ACE_LIB_TEXT (" total %3lu.%06u secs\n"),
00511                      total_secs,
00512                      (extra_nsecs + 500u) / 1000u);
00513 
00514   ACE_OS::write (handle,
00515                  str,
00516                  ACE_OS::strlen (str));
00517   ACE_OS::write (handle,
00518                  buf,
00519                  ACE_OS::strlen (buf));
00520 }

void ACE_High_Res_Timer::reset void   ) 
 

Reinitialize the timer.

Definition at line 348 of file High_Res_Timer.cpp.

References ACE_TRACE, end_, start_incr_, and total_.

Referenced by ACE_High_Res_Timer().

00349 {
00350   ACE_TRACE ("ACE_High_Res_Timer::reset");
00351 
00352   this->start_ = 0;
00353   this->end_ = 0;
00354   this->total_ = 0;
00355   this->start_incr_ = 0;
00356 }

ACE_INLINE void ACE_High_Res_Timer::start const ACE_OS::ACE_HRTimer_Op  = ACE_OS::ACE_HRTIMER_GETTIME  ) 
 

Start timing.

Definition at line 126 of file High_Res_Timer.inl.

References ACE_TRACE, and gettime().

Referenced by ACE_Profile_Timer::start().

00127 {
00128   ACE_TRACE ("ACE_High_Res_Timer::start");
00129   this->start_ = ACE_High_Res_Timer::gettime (op);
00130 }

ACE_INLINE void ACE_High_Res_Timer::start_incr const ACE_OS::ACE_HRTimer_Op  = ACE_OS::ACE_HRTIMER_GETTIME  ) 
 

Start incremental timing.

Definition at line 140 of file High_Res_Timer.inl.

References ACE_TRACE, gettime(), and start_incr_.

00141 {
00142   ACE_TRACE ("ACE_High_Res_Timer::start_incr");
00143   this->start_incr_ = ACE_High_Res_Timer::gettime (op);
00144 }

ACE_INLINE void ACE_High_Res_Timer::stop const ACE_OS::ACE_HRTimer_Op  = ACE_OS::ACE_HRTIMER_GETTIME  ) 
 

Stop timing.

Definition at line 133 of file High_Res_Timer.inl.

References ACE_TRACE, end_, and gettime().

Referenced by ACE_Profile_Timer::stop().

00134 {
00135   ACE_TRACE ("ACE_High_Res_Timer::stop");
00136   this->end_ = ACE_High_Res_Timer::gettime (op);
00137 }

ACE_INLINE void ACE_High_Res_Timer::stop_incr const ACE_OS::ACE_HRTimer_Op  = ACE_OS::ACE_HRTIMER_GETTIME  ) 
 

Stop incremental timing.

Definition at line 147 of file High_Res_Timer.inl.

References ACE_TRACE, elapsed_hrtime(), gettime(), and total_.

00148 {
00149   ACE_TRACE ("ACE_High_Res_Timer::stop_incr");
00150   this->total_ +=
00151     ACE_High_Res_Timer::elapsed_hrtime (ACE_High_Res_Timer::gettime (op),
00152                                         this->start_incr_);
00153 }


Member Data Documentation

ACE_High_Res_Timer::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Definition at line 234 of file High_Res_Timer.h.

ACE_hrtime_t ACE_High_Res_Timer::end_ [private]
 

Ending time.

Definition at line 294 of file High_Res_Timer.h.

Referenced by dump(), reset(), and stop().

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_END_VERSIONED_NAMESPACE_DECL ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = 1u [static, private]
 

Converts ticks to microseconds. That is, ticks / global_scale_factor_ == microseconds.

Definition at line 49 of file High_Res_Timer.cpp.

Referenced by global_scale_factor().

ACE_END_VERSIONED_NAMESPACE_DECL ACE_BEGIN_VERSIONED_NAMESPACE_DECL int ACE_High_Res_Timer::global_scale_factor_status_ = 0 [static, private]
 

Indicates the status of the global scale factor, 0 = hasn't been set 1 = been set -1 = HR timer not supported

Definition at line 74 of file High_Res_Timer.cpp.

Referenced by gettime(), gettimeofday(), and global_scale_factor().

ACE_hrtime_t ACE_High_Res_Timer::start_ [private]
 

Starting time.

Definition at line 291 of file High_Res_Timer.h.

ACE_hrtime_t ACE_High_Res_Timer::start_incr_ [private]
 

Start time of incremental timing.

Definition at line 300 of file High_Res_Timer.h.

Referenced by dump(), reset(), and start_incr().

ACE_hrtime_t ACE_High_Res_Timer::total_ [private]
 

Total elapsed time.

Definition at line 297 of file High_Res_Timer.h.

Referenced by dump(), elapsed_time_incr(), print_total(), reset(), and stop_incr().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:23:24 2006 for ACE by doxygen 1.3.6