High_Res_Timer.inl

Go to the documentation of this file.
00001 // -*- C++ -*- */
00002 //
00003 // High_Res_Timer.inl,v 4.3 2005/10/28 16:14:52 ossama Exp
00004 
00005 #include "ace/Global_Macros.h"
00006 
00007 #if defined (ACE_WIN32)
00008 #  include "ace/OS_NS_sys_time.h"
00009 #endif /* ACE_WIN32 */
00010 
00011 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00012 
00013 // Be very careful before changing the calculations inside
00014 // ACE_High_Res_Timer.  The precision matters and we are using integer
00015 // calculations not floating point.  Also look closely at the emulated 64
00016 // bit int class (inside Basic_Types{h,i,cpp} before changing
00017 // anything.  It's operator/ only returns 32 bits not 64 bits, among
00018 // other things.
00019 
00020 ACE_INLINE void
00021 ACE_High_Res_Timer::hrtime_to_tv (ACE_Time_Value &tv,
00022                                   const ACE_hrtime_t hrt)
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 }
00055 
00056 
00057 ACE_INLINE ACE_Time_Value
00058 ACE_High_Res_Timer::gettimeofday (const ACE_OS::ACE_HRTimer_Op op)
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 }
00075 
00076 
00077 // Get the current high res timer as the time of day. This is intended
00078 // to be used for a gettimeofday replacement in ACE_Timer_Queue and
00079 // derived classes so the timers will bebased on high res timers rather
00080 // than wall clock time. It uses the ACE_High_Res_Timer::gettimeofday
00081 // function, which is deprecated. If it gets removed, please move the
00082 // code down here, intact.
00083 ACE_INLINE ACE_Time_Value
00084 ACE_High_Res_Timer::gettimeofday_hr (void)
00085 {
00086   return ACE_High_Res_Timer::gettimeofday ();
00087 }
00088 
00089 
00090 ACE_INLINE ACE_hrtime_t
00091 ACE_High_Res_Timer::gettime (const ACE_OS::ACE_HRTimer_Op op)
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 }
00110 
00111 ACE_INLINE ACE_hrtime_t
00112 ACE_High_Res_Timer::elapsed_hrtime (const ACE_hrtime_t end,
00113                                     const ACE_hrtime_t start)
00114 {
00115   if (end > start)
00116     return end - start;
00117   return (~start + 1 + end);     // Wrapped-around counter diff
00118 }
00119 
00120 ACE_INLINE
00121 ACE_High_Res_Timer::~ACE_High_Res_Timer (void)
00122 {
00123 }
00124 
00125 ACE_INLINE void
00126 ACE_High_Res_Timer::start (const ACE_OS::ACE_HRTimer_Op op)
00127 {
00128   ACE_TRACE ("ACE_High_Res_Timer::start");
00129   this->start_ = ACE_High_Res_Timer::gettime (op);
00130 }
00131 
00132 ACE_INLINE void
00133 ACE_High_Res_Timer::stop (const ACE_OS::ACE_HRTimer_Op op)
00134 {
00135   ACE_TRACE ("ACE_High_Res_Timer::stop");
00136   this->end_ = ACE_High_Res_Timer::gettime (op);
00137 }
00138 
00139 ACE_INLINE void
00140 ACE_High_Res_Timer::start_incr (const ACE_OS::ACE_HRTimer_Op op)
00141 {
00142   ACE_TRACE ("ACE_High_Res_Timer::start_incr");
00143   this->start_incr_ = ACE_High_Res_Timer::gettime (op);
00144 }
00145 
00146 ACE_INLINE void
00147 ACE_High_Res_Timer::stop_incr (const ACE_OS::ACE_HRTimer_Op op)
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 }
00154 
00155 ACE_INLINE void
00156 ACE_High_Res_Timer::elapsed_microseconds (ACE_hrtime_t &usecs) const
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 }
00170 
00171 ACE_INLINE void
00172 ACE_High_Res_Timer::global_scale_factor (ACE_UINT32 gsf)
00173 {
00174   global_scale_factor_ = gsf;
00175 }
00176 
00177 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:52 2006 for ACE by doxygen 1.3.6