Time_Value.cpp

Go to the documentation of this file.
00001 #include "ace/Time_Value.h"
00002 
00003 ACE_RCSID (ace,
00004            Time_Value,
00005            "Time_Value.cpp,v 4.31 2006/02/28 00:23:12 shuston Exp")
00006 
00007 
00008 #if !defined (__ACE_INLINE__)
00009 #include "ace/Time_Value.inl"
00010 #endif /* __ACE_INLINE__ */
00011 
00012 #if !defined(ACE_LACKS_NUMERIC_LIMITS)
00013 // some platforms pollute the namespace by defining max() and min() macros
00014 #ifdef max
00015 #undef max
00016 #endif
00017 #ifdef min
00018 #undef min
00019 #endif
00020 #include <limits>
00021 #endif /* ACE_LACKS_NUMERIC_LIMITS */
00022 
00023 
00024 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 // Static constant representing `zero-time'.
00027 // Note: this object requires static construction.
00028 const ACE_Time_Value ACE_Time_Value::zero;
00029 
00030 // Constant for maximum time representable.  Note that this time
00031 // is not intended for use with select () or other calls that may
00032 // have *their own* implementation-specific maximum time representations.
00033 // Its primary use is in time computations such as those used by the
00034 // dynamic subpriority strategies in the ACE_Dynamic_Message_Queue class.
00035 // Note: this object requires static construction.
00036 // Note: on platforms without std::numeric_limits<>, we assume time_t is
00037 // a long, the historical type used for time.
00038 const ACE_Time_Value ACE_Time_Value::max_time (
00039 #if !defined(ACE_LACKS_NUMERIC_LIMITS) && !defined (ACE_WIN64)
00040                                                std::numeric_limits<time_t>::max (),
00041 #else
00042                                                LONG_MAX,
00043 #endif
00044                                                ACE_ONE_SECOND_IN_USECS - 1);
00045 
00046 ACE_ALLOC_HOOK_DEFINE (ACE_Time_Value)
00047 
00048 // Increment microseconds (the only reason this is here is to allow
00049 // the use of ACE_Atomic_Op with ACE_Time_Value).
00050 
00051 ACE_Time_Value
00052 ACE_Time_Value::operator ++ (int)
00053 {
00054   // ACE_OS_TRACE ("ACE_Time_Value::operator ++ (int)");
00055   ACE_Time_Value tv (*this);
00056   ++*this;
00057   return tv;
00058 }
00059 
00060 ACE_Time_Value &
00061 ACE_Time_Value::operator ++ (void)
00062 {
00063   // ACE_OS_TRACE ("ACE_Time_Value::operator ++ (void)");
00064   this->usec (this->usec () + 1);
00065   this->normalize ();
00066   return *this;
00067 }
00068 
00069 // Decrement microseconds (the only reason this is here is / to allow
00070 // the use of ACE_Atomic_Op with ACE_Time_Value).
00071 
00072 ACE_Time_Value
00073 ACE_Time_Value::operator -- (int)
00074 {
00075   // ACE_OS_TRACE ("ACE_Time_Value::operator -- (int)");
00076   ACE_Time_Value tv (*this);
00077   --*this;
00078   return tv;
00079 }
00080 
00081 ACE_Time_Value &
00082 ACE_Time_Value::operator -- (void)
00083 {
00084   // ACE_OS_TRACE ("ACE_Time_Value::operator -- (void)");
00085   this->usec (this->usec () - 1);
00086   this->normalize ();
00087   return *this;
00088 }
00089 
00090 #if defined (ACE_WIN32)
00091 // Static constant to remove time skew between FILETIME and POSIX
00092 // time.  POSIX and Win32 use different epochs (Jan. 1, 1970 v.s.
00093 // Jan. 1, 1601).  The following constant defines the difference
00094 // in 100ns ticks.
00095 //
00096 // In the beginning (Jan. 1, 1601), there was no time and no computer.
00097 // And Bill said: "Let there be time," and there was time....
00098 # if defined (ACE_LACKS_LONGLONG_T)
00099 const ACE_U_LongLong ACE_Time_Value::FILETIME_to_timval_skew =
00100 ACE_U_LongLong (0xd53e8000, 0x19db1de);
00101 # else
00102 const DWORDLONG ACE_Time_Value::FILETIME_to_timval_skew =
00103 ACE_INT64_LITERAL (0x19db1ded53e8000);
00104 # endif
00105 
00106 //  Initializes the ACE_Time_Value object from a Win32 FILETIME
00107 
00108 ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time)
00109 {
00110   // // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
00111   this->set (file_time);
00112 }
00113 
00114 void ACE_Time_Value::set (const FILETIME &file_time)
00115 {
00116   //  Initializes the ACE_Time_Value object from a Win32 FILETIME
00117 #if defined (ACE_LACKS_LONGLONG_T)
00118   ACE_U_LongLong LL_100ns(file_time.dwLowDateTime, file_time.dwHighDateTime);
00119   LL_100ns -= ACE_Time_Value::FILETIME_to_timval_skew;
00120   // Convert 100ns units to seconds;
00121   this->tv_.tv_sec = (long) (LL_100ns / ((double) (10000 * 1000)));
00122   // Convert remainder to microseconds;
00123   this->tv_.tv_usec = (suseconds_t)((LL_100ns % ((ACE_UINT32)(10000 * 1000))) / 10);
00124 #else
00125   // Don't use a struct initializer, gcc don't like it.
00126   ULARGE_INTEGER _100ns;
00127   _100ns.LowPart = file_time.dwLowDateTime;
00128   _100ns.HighPart = file_time.dwHighDateTime;
00129 
00130   _100ns.QuadPart -= ACE_Time_Value::FILETIME_to_timval_skew;
00131 
00132   // Convert 100ns units to seconds;
00133   this->tv_.tv_sec = (long) (_100ns.QuadPart / (10000 * 1000));
00134   // Convert remainder to microseconds;
00135   this->tv_.tv_usec = (suseconds_t) ((_100ns.QuadPart % (10000 * 1000)) / 10);
00136 #endif // ACE_LACKS_LONGLONG_T
00137   this->normalize ();
00138 }
00139 
00140 // Returns the value of the object as a Win32 FILETIME.
00141 
00142 ACE_Time_Value::operator FILETIME () const
00143 {
00144   FILETIME file_time;
00145   // ACE_OS_TRACE ("ACE_Time_Value::operator FILETIME");
00146 
00147 #if defined (ACE_LACKS_LONGLONG_T)
00148   ACE_U_LongLong LL_sec(this->tv_.tv_sec);
00149   ACE_U_LongLong LL_usec(this->tv_.tv_usec);
00150   ACE_U_LongLong LL_100ns = LL_sec * (ACE_UINT32)(10000 * 1000) +
00151                             LL_usec * (ACE_UINT32)10 +
00152                             ACE_Time_Value::FILETIME_to_timval_skew;
00153   file_time.dwLowDateTime = LL_100ns.lo();
00154   file_time.dwHighDateTime = LL_100ns.hi();
00155 #else
00156   ULARGE_INTEGER _100ns;
00157   _100ns.QuadPart = (((DWORDLONG) this->tv_.tv_sec * (10000 * 1000) +
00158                      this->tv_.tv_usec * 10) +
00159                      ACE_Time_Value::FILETIME_to_timval_skew);
00160 
00161   file_time.dwLowDateTime = _100ns.LowPart;
00162   file_time.dwHighDateTime = _100ns.HighPart;
00163 #endif //ACE_LACKS_LONGLONG_T
00164 
00165   return file_time;
00166 }
00167 
00168 #endif /* ACE_WIN32 */
00169 
00170 void
00171 ACE_Time_Value::dump (void) const
00172 {
00173 #if defined (ACE_HAS_DUMP)
00174   // ACE_OS_TRACE ("ACE_Time_Value::dump");
00175 #if 0
00176   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00177   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntv_sec_ = %d"), this->tv_.tv_sec));
00178   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntv_usec_ = %d\n"), this->tv_.tv_usec));
00179   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00180 #endif /* 0 */
00181 #endif /* ACE_HAS_DUMP */
00182 }
00183 
00184 void
00185 ACE_Time_Value::normalize (void)
00186 {
00187   // // ACE_OS_TRACE ("ACE_Time_Value::normalize");
00188   // From Hans Rohnert...
00189 
00190   if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS)
00191     {
00192       /*! \todo This loop needs some optimization.
00193        */
00194       do
00195         {
00196           ++this->tv_.tv_sec;
00197           this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00198         }
00199       while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS);
00200     }
00201   else if (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS)
00202     {
00203       /*! \todo This loop needs some optimization.
00204        */
00205       do
00206         {
00207           --this->tv_.tv_sec;
00208           this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00209         }
00210       while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS);
00211     }
00212 
00213   if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0)
00214     {
00215       --this->tv_.tv_sec;
00216       this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
00217     }
00218 // tv_sec in qnxnto is unsigned
00219 #if !defined ( __QNXNTO__)
00220   else if (this->tv_.tv_sec < 0 && this->tv_.tv_usec > 0)
00221     {
00222       ++this->tv_.tv_sec;
00223       this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
00224     }
00225 #endif /* __QNXNTO__  */
00226 }
00227 
00228 
00229 ACE_Time_Value &
00230 ACE_Time_Value::operator *= (double d)
00231 {
00232   // double is long enough (16 digits) to not lose the accuracy.
00233   double time_total =
00234     (this->sec ()
00235      + static_cast<double> (this->usec ()) / ACE_ONE_SECOND_IN_USECS) * d;
00236 
00237   // shall we saturate the result?
00238 #if !defined(ACE_LACKS_NUMERIC_LIMITS) && !defined (ACE_WIN64)
00239   static const double max_int = std::numeric_limits<time_t>::max () + 0.999999;
00240   static const double min_int = std::numeric_limits<time_t>::min () - 0.999999;
00241 #else
00242   static const double max_int = LONG_MAX + 0.999999;
00243   static const double min_int = LONG_MIN - 0.999999;
00244 #endif
00245 
00246   if (time_total > max_int)
00247     time_total = max_int;
00248   if (time_total < min_int)
00249     time_total = min_int;
00250 
00251   const time_t time_sec = static_cast<time_t> (time_total);
00252 
00253   time_total -= time_sec;
00254   time_total *= ACE_ONE_SECOND_IN_USECS;
00255 
00256   suseconds_t time_usec = static_cast<suseconds_t> (time_total);
00257 
00258   // round up the result to save the last usec
00259   if (time_usec > 0 && (time_total - time_usec) >= 0.5)
00260     ++time_usec;
00261   else if (time_usec < 0 && (time_total - time_usec) <= -0.5)
00262     --time_usec;
00263 
00264   this->set (time_sec, time_usec);
00265 
00266   return *this;
00267 }
00268 
00269 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:42:07 2006 for ACE by doxygen 1.3.6