Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

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 Methods

 ACE_High_Res_Timer (void)
 Initialize the timer. More...

 ~ACE_High_Res_Timer (void)
 dtor. More...

void reset (void)
 Reinitialize the timer. More...

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

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

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

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

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

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

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

void 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. More...

void elapsed_time_incr (ACE_hrtime_t &nanoseconds) const
 Set <nsec> to the number of nanoseconds elapsed between all calls to start_incr and stop_incr. More...

void print_total (const ACE_TCHAR *message, const int iterations=1, ACE_HANDLE handle=ACE_STDOUT) const
 Print total time. NOTE: only use <print_total> if incremental timings had been used! More...

void print_ave (const ACE_TCHAR *message, const int iterations=1, ACE_HANDLE handle=ACE_STDOUT) const
 Print average time. More...

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


Static Public Methods

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

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 <hrt> to <tv> using global_scale_factor_. More...


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks. More...


Static Private Methods

ACE_hrtime_t gettime (const ACE_OS::ACE_HRTimer_Op=ACE_OS::ACE_HRTIMER_GETTIME)

Private Attributes

ACE_hrtime_t start_
 Starting time. More...

ACE_hrtime_t end_
 Ending time. More...

ACE_hrtime_t total_
 Total elapsed time. More...

ACE_hrtime_t start_incr_
 Start time of incremental timing. More...


Static Private Attributes

ACE_UINT32 global_scale_factor_ = 1u
 Converts ticks to microseconds. That is, ticks / global_scale_factor_ == microseconds. More...

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 <ACE_HR_SCALE_CONVERSION> 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! NOTE: 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 96 of file High_Res_Timer.h.


Constructor & Destructor Documentation

ACE_High_Res_Timer::ACE_High_Res_Timer void   
 

Initialize the timer.

Definition at line 233 of file High_Res_Timer.cpp.

References ACE_TRACE, global_scale_factor, and reset.

00234 {
00235   ACE_TRACE ("ACE_High_Res_Timer::ACE_High_Res_Timer");
00236 
00237   this->reset ();
00238 
00239   // Make sure that the global scale factor is set.
00240   (void) global_scale_factor ();
00241 }

ACE_INLINE ACE_High_Res_Timer::~ACE_High_Res_Timer void   
 

dtor.

Definition at line 103 of file High_Res_Timer.i.

00104 {
00105 }


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 244 of file High_Res_Timer.cpp.

References ACE_hrtime_t, ACE_U64_TO_U32, ACE_OS::gethrtime, ACE_OS::gettimeofday, global_scale_factor, ACE_Stats::mean, ACE_Time_Value::msec, ACE_Stats::sample, ACE_OS::sleep, start, stop, and ACE_Stats_Value::whole.

Referenced by global_scale_factor.

00246 {
00247   const ACE_Time_Value sleep_time (0, usec);
00248   ACE_Stats delta_hrtime;
00249   // In units of 100 usec, to avoid overflow.
00250   ACE_Stats actual_sleeps;
00251 
00252   for (u_int i = 0;
00253        i < iterations;
00254        ++i)
00255     {
00256       const ACE_Time_Value actual_start =
00257         ACE_OS::gettimeofday ();
00258       const ACE_hrtime_t start =
00259         ACE_OS::gethrtime ();
00260       ACE_OS::sleep (sleep_time);
00261       const ACE_hrtime_t stop =
00262         ACE_OS::gethrtime ();
00263       const ACE_Time_Value actual_delta =
00264         ACE_OS::gettimeofday () - actual_start;
00265 
00266       // Store the sample.
00267       delta_hrtime.sample (ACE_U64_TO_U32 (stop - start));
00268       actual_sleeps.sample (actual_delta.msec () * 100u);
00269     }
00270 
00271   // Calculate the mean value of the samples, with no fractional
00272   // precision.  Use it for the global scale factor.
00273   ACE_Stats_Value ticks (0);
00274   delta_hrtime.mean (ticks);
00275 
00276   ACE_Stats_Value actual_sleep (0);
00277   actual_sleeps.mean (actual_sleep);
00278 
00279   // The addition of 5 below rounds instead of truncates.
00280   const ACE_UINT32 scale_factor =
00281     (ticks.whole () / actual_sleep.whole () + 5) /
00282     10u /* usec/100 usec */;
00283   ACE_High_Res_Timer::global_scale_factor (scale_factor);
00284 
00285   return scale_factor;
00286 }

void ACE_High_Res_Timer::dump void    const
 

Dump the state of an object.

Definition at line 289 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_, start_incr_, and total_.

Referenced by ACE_Profile_Timer::dump.

00290 {
00291   ACE_TRACE ("ACE_High_Res_Timer::dump");
00292 
00293   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00294   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nglobal_scale_factor_: %u\n"),
00295              global_scale_factor ()));
00296 #if defined (ACE_LACKS_LONGLONG_T)
00297   ACE_DEBUG ((LM_DEBUG,
00298              ACE_LIB_TEXT (":\nstart_.hi ():     %8x; start_.lo ():      %8x;\n")
00299              ACE_LIB_TEXT ("end_.hi ():       %8x; end_.lo ():        %8x;\n")
00300              ACE_LIB_TEXT ("total_.hi ():     %8x; total_.lo ():      %8x;\n")
00301              ACE_LIB_TEXT ("start_incr_.hi () %8x; start_incr_.lo (): %8x;\n"),
00302              start_.hi (), start_.lo (),
00303              end_.hi (), end_.lo (),
00304              total_.hi (), total_.lo (),
00305              start_incr_.hi (), start_incr_.lo ()));
00306 #else  /* ! ACE_LACKS_LONGLONG_T */
00307   ACE_DEBUG ((LM_DEBUG,
00308              ACE_LIB_TEXT (":\nstart_.hi ():     %8x; start_.lo ():      %8x;\n")
00309              ACE_LIB_TEXT ("end_.hi ():       %8x; end_.lo ():        %8x;\n")
00310              ACE_LIB_TEXT ("total_.hi ():     %8x; total_.lo ():      %8x;\n")
00311              ACE_LIB_TEXT ("start_incr_.hi () %8x; start_incr_.lo (): %8x;\n"),
00312              ACE_CU64_TO_CU32 (start_ >> 32),
00313              ACE_CU64_TO_CU32 (start_ & 0xfffffffful),
00314              ACE_CU64_TO_CU32 (end_ >> 32),
00315              ACE_CU64_TO_CU32 (end_ & 0xfffffffful),
00316              ACE_CU64_TO_CU32 (total_ >> 32),
00317              ACE_CU64_TO_CU32 (total_ & 0xfffffffful),
00318              ACE_CU64_TO_CU32 (start_incr_ >> 32),
00319              ACE_CU64_TO_CU32 (start_incr_ & 0xfffffffful)));
00320 #endif /* ! ACE_LACKS_LONGLONG_T */
00321   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00322 }

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 136 of file High_Res_Timer.i.

References ACE_hrtime_t, end_, global_scale_factor, and start_.

00137 {
00138 #if defined (ACE_WIN32)
00139   // Win32 scale factor is in msec
00140   // This could give overflow when measuring a long time with a
00141   // big global_scale_factor() (> 48 days with a 4Ghz tick freq.)
00142   // To be looked after in the future.
00143   usecs = (ACE_hrtime_t) (((this->end_ - this->start_) * 1000) /
00144                           global_scale_factor ());
00145 #else
00146   usecs =
00147     (ACE_hrtime_t) ((this->end_ - this->start_) / global_scale_factor ());
00148 #endif
00149 
00150 
00151 
00152 }

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 383 of file High_Res_Timer.cpp.

References ACE_hrtime_t, end_, global_scale_factor, and start_.

00384 {
00385   // Please do _not_ rearrange this equation.  It is carefully
00386   // designed and tested to avoid overflow on machines that don't have
00387   // native 64-bit ints. In particular, division can be a problem.
00388   // For more background on this, please see bugzilla #1024.
00389 #if defined (ACE_WIN32)
00390   nanoseconds = (this->end_ - this->start_)
00391             * (1024000000u / ACE_High_Res_Timer::global_scale_factor());
00392 #else
00393   nanoseconds = (this->end_ - this->start_)
00394             * (1024000u / ACE_High_Res_Timer::global_scale_factor ());
00395 #endif /* ACE_WIN32 */
00396   // Caution - Borland has a problem with >>=, so resist the temptation.
00397   nanoseconds = nanoseconds >> 10;
00398   // Right shift is implemented for non native 64-bit ints
00399   // operator/ only for a 32 bit result !
00400 }

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 336 of file High_Res_Timer.cpp.

References end_, hrtime_to_tv, and start_.

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

00337 {
00338   hrtime_to_tv (tv, end_ - start_);
00339 }

void ACE_High_Res_Timer::elapsed_time_incr ACE_hrtime_t   nanoseconds const
 

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

Definition at line 403 of file High_Res_Timer.cpp.

References ACE_hrtime_t, global_scale_factor, and total_.

00404 {
00405   // Same as above.
00406 #if defined (ACE_WIN32)
00407   nanoseconds = this->total_
00408             * (1024000000u / ACE_High_Res_Timer::global_scale_factor());
00409 #else
00410   nanoseconds = this->total_
00411             * (1024000u / ACE_High_Res_Timer::global_scale_factor ());
00412 #endif
00413   // Caution - Borland has a problem with >>=, so resist the temptation.
00414   nanoseconds = nanoseconds >> 10;
00415 }

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 377 of file High_Res_Timer.cpp.

References hrtime_to_tv, and total_.

00378 {
00379   hrtime_to_tv (tv, total_);
00380 }

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 <env> 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 507 of file High_Res_Timer.cpp.

References ACE_TCHAR, ACE_OS::atoi, ACE_OS::getenv, and global_scale_factor.

00508 {
00509 #if !defined (ACE_HAS_WINCE)
00510   if (env != 0)
00511     {
00512       const ACE_TCHAR *env_value = ACE_OS::getenv (env);
00513       if (env_value != 0)
00514         {
00515           int value = ACE_OS::atoi (env_value);
00516           if (value > 0)
00517             {
00518               ACE_High_Res_Timer::global_scale_factor (value);
00519               return 0;
00520             }
00521         }
00522     }
00523 #else
00524   ACE_UNUSED_ARG (env);
00525 #endif /* !ACE_HAS_WINCE */
00526   return -1;
00527 }

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 <global_scale_factor_> be set, such as ACE_WIN32, uses the low-resolution clock if the <global_scale_factor_> has not been set.

Definition at line 82 of file High_Res_Timer.i.

References ACE_OS::ACE_HRTimer_Op, 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.

00083 {
00084 #if defined (ACE_WIN32)
00085   // Get the global scale factor if there isn't one yet.
00086   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00087     ACE_High_Res_Timer::global_scale_factor ();
00088 
00089   // If there isn't a high-res timer, use gettimeofday ();
00090   if (ACE_High_Res_Timer::global_scale_factor_status_ == -1)
00091     {
00092       ACE_Time_Value tv = ACE_OS::gettimeofday ();
00093       // Return the time in microseconds because the global_scale_factor_
00094       // is 1.
00095       return tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec ();
00096     }
00097 #endif /* ACE_WIN32 */
00098 
00099   return ACE_OS::gethrtime (op);
00100 }

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 <global_scale_factor_> is not set, and we're on a platform that requires <global_scale_factor_> (e.g., Win32), ACE_OS::gettimeofday will be used instead of <ACE_OS::gethrtime>. This allows applications on Intel to use <High_Res_Timer> even when <global_scale_factor> is not set. However, setting the <global_scale_factor_> appropriately will result in the finest resolution possible.

Definition at line 49 of file High_Res_Timer.i.

References ACE_OS::ACE_HRTimer_Op, ACE_OS::gethrtime, ACE_OS::gettimeofday, global_scale_factor, global_scale_factor_status_, and hrtime_to_tv.

Referenced by gettimeofday_hr.

00050 {
00051 #if defined (ACE_WIN32)
00052   // Get the global scale factor if there isn't one yet.
00053   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00054     ACE_High_Res_Timer::global_scale_factor ();
00055 
00056   // If there isn't a high-res timer, use gettimeofday ();
00057   if (ACE_High_Res_Timer::global_scale_factor_status_ == -1)
00058     return ACE_OS::gettimeofday ();
00059 #endif /* ACE_WIN32 */
00060 
00061   ACE_Time_Value tv;
00062   ACE_High_Res_Timer::hrtime_to_tv (tv,
00063                                     ACE_OS::gethrtime (op));
00064   return tv;
00065 }

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 75 of file High_Res_Timer.i.

References gettimeofday.

00076 {
00077   return ACE_High_Res_Timer::gettimeofday ();
00078 }

ACE_UINT32 ACE_High_Res_Timer::global_scale_factor void    [static]
 

Returns the global_scale_factor.

Definition at line 170 of file High_Res_Timer.cpp.

References ACE_GUARD_RETURN, ACE_HR_SCALE_CONVERSION, ACE_MT, ACE_ONE_SECOND_IN_USECS, ACE_UINT64, calibrate, global_scale_factor, global_scale_factor_, global_scale_factor_status_, and ACE_Static_Object_Lock::instance.

Referenced by ACE_High_Res_Timer, calibrate, elapsed_microseconds, elapsed_time, elapsed_time_incr, get_env_global_scale_factor, gettime, gettimeofday, hrtime_to_tv, and ACE_Timeprobe::print_times.

00171 {
00172 #if (defined (ACE_WIN32) || defined (ACE_HAS_POWERPC_TIMER) || \
00173      defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER)) && \
00174     !defined (ACE_HAS_HI_RES_TIMER) && \
00175     ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || \
00176      defined (ghs) || defined (__GNUG__) || defined (__KCC) || \
00177      defined (__INTEL_COMPILER))
00178   // Check if the global scale factor needs to be set, and do if so.
00179   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00180     {
00181       // Grab ACE's static object lock.  This doesn't have anything to
00182       // do with static objects; it's just a convenient lock to use.
00183       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00184                                 *ACE_Static_Object_Lock::instance (), 0));
00185 
00186       // Double check
00187       if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00188         {
00189 #         if defined (ACE_WIN32)
00190             LARGE_INTEGER freq;
00191             if (::QueryPerformanceFrequency (&freq))
00192               {
00193                 // We have a high-res timer
00194 #             if defined (ACE_LACKS_LONGLONG_T)
00195                 ACE_UINT64 uint64_freq(freq.u.LowPart, (ACE_UINT32) freq.u.HighPart);
00196                 ACE_High_Res_Timer::global_scale_factor
00197                   (uint64_freq / (ACE_UINT32) ACE_ONE_SECOND_IN_USECS);
00198 #             else
00199                 ACE_High_Res_Timer::global_scale_factor
00200                   (ACE_static_cast (unsigned int,
00201                                     freq.QuadPart / ACE_HR_SCALE_CONVERSION));
00202 #             endif // (ACE_LACKS_LONGLONG_T)
00203 
00204                 ACE_High_Res_Timer::global_scale_factor_status_ = 1;
00205               }
00206             else
00207               // High-Res timers not supported
00208               ACE_High_Res_Timer::global_scale_factor_status_ = -1;
00209 
00210             return ACE_High_Res_Timer::global_scale_factor_;
00211 
00212 #         elif defined (linux)
00213             ACE_High_Res_Timer::global_scale_factor (ACE_High_Res_Timer::get_cpuinfo ());
00214 #         endif /* ! ACE_WIN32 && ! (linux && __alpha__) */
00215 
00216 #         if !defined (ACE_WIN32)
00217           if (ACE_High_Res_Timer::global_scale_factor_ == 1u)
00218             // Failed to retrieve CPU speed from system, so calculate it.
00219             ACE_High_Res_Timer::calibrate ();
00220 #         endif // (ACE_WIN32)
00221         }
00222     }
00223 
00224   ACE_High_Res_Timer::global_scale_factor_status_ = 1;
00225 #endif /* (ACE_WIN32 || ACE_HAS_POWERPC_TIMER || \
00226            ACE_HAS_PENTIUM || ACE_HAS_ALPHA_TIMER) && \
00227           ! ACE_HAS_HIGH_RES_TIMER &&
00228           ((WIN32 && ! WINCE) || ghs || __GNUG__) */
00229 
00230   return ACE_High_Res_Timer::global_scale_factor_;
00231 }

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 <scale_factor> need not be set. Careful, a <scale_factor> of 0 will cause division by zero exceptions. Depending on the platform its units are 1/microsecond or 1/millisecond. Use <ACE_HR_SCALE_CONVERSION> inside calculations instead a hardcoded value.

Definition at line 155 of file High_Res_Timer.i.

References global_scale_factor_.

Referenced by dump, global_scale_factor, and hrtime_to_tv.

00156 {
00157   global_scale_factor_ = gsf;
00158 }

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

Converts an <hrt> to <tv> using global_scale_factor_.

Definition at line 12 of file High_Res_Timer.i.

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, and gettimeofday.

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

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 419 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, ACE_OS_String::strlen, and ACE_OS::write.

00422 {
00423   ACE_TRACE ("ACE_High_Res_Timer::print_ave");
00424 
00425   // Get the total number of nanoseconds elapsed.
00426   ACE_hrtime_t total_nanoseconds;
00427   this->elapsed_time (total_nanoseconds);
00428 
00429   // Separate to seconds and nanoseconds.
00430   u_long total_secs =
00431     ACE_static_cast (u_long,
00432                      total_nanoseconds / (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00433   ACE_UINT32 extra_nsecs =
00434     ACE_static_cast (ACE_UINT32,
00435                      total_nanoseconds % (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00436 
00437   ACE_TCHAR buf[100];
00438   if (count > 1)
00439     {
00440       ACE_hrtime_t avg_nsecs = total_nanoseconds / (ACE_UINT32) count;
00441       ACE_OS::sprintf (buf,
00442                        ACE_LIB_TEXT (" count = %d, total (secs %lu, usecs %u), avg usecs = %lu\n"),
00443                        count,
00444                        total_secs,
00445                        (extra_nsecs + 500u) / 1000u,
00446                        (u_long) ((avg_nsecs + 500u) / 1000u));
00447     }
00448   else
00449     ACE_OS::sprintf (buf,
00450                      ACE_LIB_TEXT (" total %3lu.%06lu secs\n"),
00451                      total_secs,
00452                      (extra_nsecs + 500lu) / 1000lu);
00453 
00454   ACE_OS::write (handle,
00455                  str,
00456                  ACE_OS::strlen (str));
00457   ACE_OS::write (handle,
00458                  buf,
00459                  ACE_OS::strlen (buf));
00460 }

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 <print_total> if incremental timings had been used!

Definition at line 463 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, ACE_OS_String::strlen, total_, and ACE_OS::write.

00466 {
00467   ACE_TRACE ("ACE_High_Res_Timer::print_total");
00468 
00469   // Get the total number of nanoseconds elapsed.
00470   ACE_hrtime_t total_nanoseconds;
00471   this->elapsed_time (total_nanoseconds);
00472 
00473   // Separate to seconds and nanoseconds.
00474   u_long total_secs =
00475     (u_long) (total_nanoseconds / (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00476   ACE_UINT32 extra_nsecs =
00477     (ACE_UINT32) (total_nanoseconds % (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00478 
00479   ACE_TCHAR buf[100];
00480   if (count > 1)
00481     {
00482       ACE_hrtime_t avg_nsecs = this->total_ / (ACE_UINT32) count;
00483 
00484       ACE_OS::sprintf (buf,
00485                        ACE_LIB_TEXT (" count = %d, total (secs %lu, usecs %u), avg usecs = %lu\n"),
00486                        count,
00487                        total_secs,
00488                        (extra_nsecs + 500u) / 1000u,
00489                        (u_long) ((avg_nsecs + 500u) / 1000u));
00490     }
00491   else
00492     ACE_OS::sprintf (buf,
00493                      ACE_LIB_TEXT (" total %3lu.%06u secs\n"),
00494                      total_secs,
00495                      (extra_nsecs + 500u) / 1000u);
00496 
00497   ACE_OS::write (handle,
00498                  str,
00499                  ACE_OS::strlen (str));
00500   ACE_OS::write (handle,
00501                  buf,
00502                  ACE_OS::strlen (buf));
00503 }

void ACE_High_Res_Timer::reset void   
 

Reinitialize the timer.

Definition at line 325 of file High_Res_Timer.cpp.

References ACE_TRACE, end_, start_, start_incr_, and total_.

Referenced by ACE_High_Res_Timer.

00326 {
00327   ACE_TRACE ("ACE_High_Res_Timer::reset");
00328 
00329   start_ = 0;
00330   end_ = 0;
00331   total_ = 0;
00332   start_incr_ = 0;
00333 }

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

Start timing.

Definition at line 108 of file High_Res_Timer.i.

References ACE_OS::ACE_HRTimer_Op, ACE_TRACE, gettime, and start_.

Referenced by calibrate, and ACE_Profile_Timer::start.

00109 {
00110   ACE_TRACE ("ACE_High_Res_Timer::start");
00111   this->start_ = ACE_High_Res_Timer::gettime (op);
00112 }

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 122 of file High_Res_Timer.i.

References ACE_OS::ACE_HRTimer_Op, ACE_TRACE, gettime, and start_incr_.

00123 {
00124   ACE_TRACE ("ACE_High_Res_Timer::start_incr");
00125   this->start_incr_ = ACE_High_Res_Timer::gettime (op);
00126 }

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

Stop timing.

Definition at line 115 of file High_Res_Timer.i.

References ACE_OS::ACE_HRTimer_Op, ACE_TRACE, end_, and gettime.

Referenced by calibrate, and ACE_Profile_Timer::stop.

00116 {
00117   ACE_TRACE ("ACE_High_Res_Timer::stop");
00118   this->end_ = ACE_High_Res_Timer::gettime (op);
00119 }

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 129 of file High_Res_Timer.i.

References ACE_OS::ACE_HRTimer_Op, ACE_TRACE, gettime, start_incr_, and total_.

00130 {
00131   ACE_TRACE ("ACE_High_Res_Timer::stop_incr");
00132   this->total_ += ACE_High_Res_Timer::gettime (op) - this->start_incr_;
00133 }


Member Data Documentation

ACE_High_Res_Timer::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Definition at line 230 of file High_Res_Timer.h.

ACE_hrtime_t ACE_High_Res_Timer::end_ [private]
 

Ending time.

Definition at line 284 of file High_Res_Timer.h.

Referenced by dump, elapsed_microseconds, elapsed_time, reset, and stop.

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 37 of file High_Res_Timer.cpp.

Referenced by global_scale_factor.

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 53 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 281 of file High_Res_Timer.h.

Referenced by dump, elapsed_microseconds, elapsed_time, reset, and start.

ACE_hrtime_t ACE_High_Res_Timer::start_incr_ [private]
 

Start time of incremental timing.

Definition at line 290 of file High_Res_Timer.h.

Referenced by dump, reset, start_incr, and stop_incr.

ACE_hrtime_t ACE_High_Res_Timer::total_ [private]
 

Total elapsed time.

Definition at line 287 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 Mon Jun 16 12:48:58 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002