00001 /* -*- C++ -*- */
00002 // $Id: High_Res_Timer.i,v 1.1.1.3 2003/02/21 18:36:32 chad Exp $
00003
00004 // Be very carefull before changing the calculations inside
00005 // ACE_High_Res_Timer. The precision matters and we are using integer
00006 // calculations not floating point. Also look good at the emulated 64
00007 // bit int class (inside Basic_Types{h,i,cpp} before changing
00008 // anything. It's operator/ only returns 32 bits not 64 bits, among
00009 // other things.
00010
00011 ACE_INLINE void
00012 ACE_High_Res_Timer::hrtime_to_tv (ACE_Time_Value &tv,
00013 const ACE_hrtime_t hrt)
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 }
00046
00047
00048 ACE_INLINE ACE_Time_Value
00049 ACE_High_Res_Timer::gettimeofday (const ACE_OS::ACE_HRTimer_Op op)
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 }
00066
00067
00068 // Get the current high res timer as the time of day. This is intended
00069 // to be used for a gettimeofday replacement in ACE_Timer_Queue and
00070 // derived classes so the timers will bebased on high res timers rather
00071 // than wall clock time. It uses the ACE_High_Res_Timer::gettimeofday
00072 // function, which is deprecated. If it gets removed, please move the
00073 // code down here, intact.
00074 ACE_INLINE ACE_Time_Value
00075 ACE_High_Res_Timer::gettimeofday_hr (void)
00076 {
00077 return ACE_High_Res_Timer::gettimeofday ();
00078 }
00079
00080
00081 ACE_INLINE ACE_hrtime_t
00082 ACE_High_Res_Timer::gettime (const ACE_OS::ACE_HRTimer_Op op)
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 }
00101
00102 ACE_INLINE
00103 ACE_High_Res_Timer::~ACE_High_Res_Timer (void)
00104 {
00105 }
00106
00107 ACE_INLINE void
00108 ACE_High_Res_Timer::start (const ACE_OS::ACE_HRTimer_Op op)
00109 {
00110 ACE_TRACE ("ACE_High_Res_Timer::start");
00111 this->start_ = ACE_High_Res_Timer::gettime (op);
00112 }
00113
00114 ACE_INLINE void
00115 ACE_High_Res_Timer::stop (const ACE_OS::ACE_HRTimer_Op op)
00116 {
00117 ACE_TRACE ("ACE_High_Res_Timer::stop");
00118 this->end_ = ACE_High_Res_Timer::gettime (op);
00119 }
00120
00121 ACE_INLINE void
00122 ACE_High_Res_Timer::start_incr (const ACE_OS::ACE_HRTimer_Op op)
00123 {
00124 ACE_TRACE ("ACE_High_Res_Timer::start_incr");
00125 this->start_incr_ = ACE_High_Res_Timer::gettime (op);
00126 }
00127
00128 ACE_INLINE void
00129 ACE_High_Res_Timer::stop_incr (const ACE_OS::ACE_HRTimer_Op op)
00130 {
00131 ACE_TRACE ("ACE_High_Res_Timer::stop_incr");
00132 this->total_ += ACE_High_Res_Timer::gettime (op) - this->start_incr_;
00133 }
00134
00135 ACE_INLINE void
00136 ACE_High_Res_Timer::elapsed_microseconds (ACE_hrtime_t &usecs) const
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 }
00153
00154 ACE_INLINE void
00155 ACE_High_Res_Timer::global_scale_factor (ACE_UINT32 gsf)
00156 {
00157 global_scale_factor_ = gsf;
00158 }
1.2.14 written by Dimitri van Heesch,
© 1997-2002