LLVM API Documentation

TimeValue.h

Go to the documentation of this file.
00001 //===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Reid Spencer and is distributed under the
00006 // University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This header file declares the operating system TimeValue concept.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Support/DataTypes.h"
00015 #include "llvm/System/IncludeFile.h"
00016 #include <string>
00017 
00018 #ifndef LLVM_SYSTEM_TIMEVALUE_H
00019 #define LLVM_SYSTEM_TIMEVALUE_H
00020 
00021 namespace llvm {
00022 namespace sys {
00023   /// This class is used where a precise fixed point in time is required. The
00024   /// range of TimeValue spans many hundreds of billions of years both past and
00025   /// present.  The precision of TimeValue is to the nanosecond. However, the
00026   /// actual precision of its values will be determined by the resolution of
00027   /// the system clock. The TimeValue class is used in conjunction with several
00028   /// other lib/System interfaces to specify the time at which a call should
00029   /// timeout, etc.
00030   /// @since 1.4
00031   /// @brief Provides an abstraction for a fixed point in time.
00032   class TimeValue {
00033 
00034   /// @name Constants
00035   /// @{
00036   public:
00037 
00038     /// A constant TimeValue representing the smallest time
00039     /// value permissable by the class. MinTime is some point
00040     /// in the distant past, about 300 billion years BCE.
00041     /// @brief The smallest possible time value.
00042     static const TimeValue MinTime;
00043 
00044     /// A constant TimeValue representing the largest time
00045     /// value permissable by the class. MaxTime is some point
00046     /// in the distant future, about 300 billion years AD.
00047     /// @brief The largest possible time value.
00048     static const TimeValue MaxTime;
00049 
00050     /// A constant TimeValue representing the base time,
00051     /// or zero time of 00:00:00 (midnight) January 1st, 2000.
00052     /// @brief 00:00:00 Jan 1, 2000 UTC.
00053     static const TimeValue ZeroTime;
00054 
00055     /// A constant TimeValue for the Posix base time which is
00056     /// 00:00:00 (midnight) January 1st, 1970.
00057     /// @brief 00:00:00 Jan 1, 1970 UTC.
00058     static const TimeValue PosixZeroTime;
00059 
00060     /// A constant TimeValue for the Win32 base time which is
00061     /// 00:00:00 (midnight) January 1st, 1601.
00062     /// @brief 00:00:00 Jan 1, 1601 UTC.
00063     static const TimeValue Win32ZeroTime;
00064 
00065   /// @}
00066   /// @name Types
00067   /// @{
00068   public:
00069     typedef int64_t SecondsType;        ///< Type used for representing seconds.
00070     typedef int32_t NanoSecondsType;    ///< Type used for representing nanoseconds.
00071 
00072     enum TimeConversions {
00073       NANOSECONDS_PER_SECOND = 1000000000,  ///< One Billion
00074       MICROSECONDS_PER_SECOND = 1000000,    ///< One Million
00075       MILLISECONDS_PER_SECOND = 1000,       ///< One Thousand
00076       NANOSECONDS_PER_MICROSECOND = 1000,   ///< One Thousand
00077       NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
00078       NANOSECONDS_PER_POSIX_TICK = 100,     ///< Posix tick is 100 Hz (10ms)
00079       NANOSECONDS_PER_WIN32_TICK = 100      ///< Win32 tick is 100 Hz (10ms)
00080     };
00081 
00082   /// @}
00083   /// @name Constructors
00084   /// @{
00085   public:
00086     /// Caller provides the exact value in seconds and nanoseconds. The
00087     /// \p nanos argument defaults to zero for convenience.
00088     /// @brief Explicit constructor
00089     explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
00090       : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
00091 
00092     /// Caller provides the exact value as a double in seconds with the
00093     /// fractional part representing nanoseconds.
00094     /// @brief Double Constructor.
00095     explicit TimeValue( double new_time )
00096       : seconds_( 0 ) , nanos_ ( 0 ) {
00097       SecondsType integer_part = static_cast<SecondsType>( new_time );
00098       seconds_ = integer_part;
00099       nanos_ = static_cast<NanoSecondsType>( (new_time -
00100                static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
00101       this->normalize();
00102     }
00103 
00104     /// This is a static constructor that returns a TimeValue that represents
00105     /// the current time.
00106     /// @brief Creates a TimeValue with the current time (UTC).
00107     static TimeValue now();
00108 
00109   /// @}
00110   /// @name Operators
00111   /// @{
00112   public:
00113     /// Add \p that to \p this.
00114     /// @returns this
00115     /// @brief Incrementing assignment operator.
00116     TimeValue& operator += (const TimeValue& that ) {
00117       this->seconds_ += that.seconds_  ;
00118       this->nanos_ += that.nanos_ ;
00119       this->normalize();
00120       return *this;
00121     }
00122 
00123     /// Subtract \p that from \p this.
00124     /// @returns this
00125     /// @brief Decrementing assignment operator.
00126     TimeValue& operator -= (const TimeValue &that ) {
00127       this->seconds_ -= that.seconds_ ;
00128       this->nanos_ -= that.nanos_ ;
00129       this->normalize();
00130       return *this;
00131     }
00132 
00133     /// Determine if \p this is less than \p that.
00134     /// @returns True iff *this < that.
00135     /// @brief True if this < that.
00136     int operator < (const TimeValue &that) const { return that > *this; }
00137 
00138     /// Determine if \p this is greather than \p that.
00139     /// @returns True iff *this > that.
00140     /// @brief True if this > that.
00141     int operator > (const TimeValue &that) const {
00142       if ( this->seconds_ > that.seconds_ ) {
00143           return 1;
00144       } else if ( this->seconds_ == that.seconds_ ) {
00145           if ( this->nanos_ > that.nanos_ ) return 1;
00146       }
00147       return 0;
00148     }
00149 
00150     /// Determine if \p this is less than or equal to \p that.
00151     /// @returns True iff *this <= that.
00152     /// @brief True if this <= that.
00153     int operator <= (const TimeValue &that) const { return that >= *this; }
00154 
00155     /// Determine if \p this is greater than or equal to \p that.
00156     /// @returns True iff *this >= that.
00157     /// @brief True if this >= that.
00158     int operator >= (const TimeValue &that) const {
00159       if ( this->seconds_ > that.seconds_ ) {
00160           return 1;
00161       } else if ( this->seconds_ == that.seconds_ ) {
00162           if ( this->nanos_ >= that.nanos_ ) return 1;
00163       }
00164       return 0;
00165     }
00166 
00167     /// Determines if two TimeValue objects represent the same moment in time.
00168     /// @brief True iff *this == that.
00169     /// @brief True if this == that.
00170     int operator == (const TimeValue &that) const {
00171       return (this->seconds_ == that.seconds_) &&
00172              (this->nanos_ == that.nanos_);
00173     }
00174 
00175     /// Determines if two TimeValue objects represent times that are not the
00176     /// same.
00177     /// @return True iff *this != that.
00178     /// @brief True if this != that.
00179     int operator != (const TimeValue &that) const { return !(*this == that); }
00180 
00181     /// Adds two TimeValue objects together.
00182     /// @returns The sum of the two operands as a new TimeValue
00183     /// @brief Addition operator.
00184     friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
00185 
00186     /// Subtracts two TimeValue objects.
00187     /// @returns The difference of the two operands as a new TimeValue
00188     /// @brief Subtraction operator.
00189     friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
00190 
00191   /// @}
00192   /// @name Accessors
00193   /// @{
00194   public:
00195 
00196     /// Returns only the seconds component of the TimeValue. The nanoseconds
00197     /// portion is ignored. No rounding is performed.
00198     /// @brief Retrieve the seconds component
00199     SecondsType seconds() const { return seconds_; }
00200 
00201     /// Returns only the nanoseconds component of the TimeValue. The seconds
00202     /// portion is ignored.
00203     /// @brief Retrieve the nanoseconds component.
00204     NanoSecondsType nanoseconds() const { return nanos_; }
00205 
00206     /// Returns only the fractional portion of the TimeValue rounded down to the
00207     /// nearest microsecond (divide by one thousand).
00208     /// @brief Retrieve the fractional part as microseconds;
00209     uint32_t microseconds() const {
00210       return nanos_ / NANOSECONDS_PER_MICROSECOND;
00211     }
00212 
00213     /// Returns only the fractional portion of the TimeValue rounded down to the
00214     /// nearest millisecond (divide by one million).
00215     /// @brief Retrieve the fractional part as milliseconds;
00216     uint32_t milliseconds() const {
00217       return nanos_ / NANOSECONDS_PER_MILLISECOND;
00218     }
00219 
00220     /// Returns the TimeValue as a number of microseconds. Note that the value
00221     /// returned can overflow because the range of a uint64_t is smaller than
00222     /// the range of a TimeValue. Nevertheless, this is useful on some operating
00223     /// systems and is therefore provided.
00224     /// @brief Convert to a number of microseconds (can overflow)
00225     uint64_t usec() const {
00226       return seconds_ * MICROSECONDS_PER_SECOND +
00227              ( nanos_ / NANOSECONDS_PER_MICROSECOND );
00228     }
00229 
00230     /// Returns the TimeValue as a number of milliseconds. Note that the value
00231     /// returned can overflow because the range of a uint64_t is smaller than
00232     /// the range of a TimeValue. Nevertheless, this is useful on some operating
00233     /// systems and is therefore provided.
00234     /// @brief Convert to a number of milliseconds (can overflow)
00235     uint64_t msec() const {
00236       return seconds_ * MILLISECONDS_PER_SECOND +
00237              ( nanos_ / NANOSECONDS_PER_MILLISECOND );
00238     }
00239 
00240     /// Converts the TimeValue into the corresponding number of "ticks" for
00241     /// Posix, correcting for the difference in Posix zero time.
00242     /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
00243     uint64_t toPosixTime() const {
00244       uint64_t result = seconds_ - PosixZeroTime.seconds_;
00245       result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
00246       return result;
00247     }
00248 
00249     /// Converts the TimeValue into the corresponding number of seconds
00250     /// since the epoch (00:00:00 Jan 1,1970).
00251     uint64_t toEpochTime() const {
00252       return seconds_ - PosixZeroTime.seconds_;
00253     }
00254 
00255     /// Converts the TiemValue into the correspodning number of "ticks" for
00256     /// Win32 platforms, correcting for the difference in Win32 zero time.
00257     /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
00258     uint64_t toWin32Time() const {
00259       uint64_t result = seconds_ - Win32ZeroTime.seconds_;
00260       result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
00261       return result;
00262     }
00263 
00264     /// Provides the seconds and nanoseconds as results in its arguments after
00265     /// correction for the Posix zero time.
00266     /// @brief Convert to timespec time (ala POSIX.1b)
00267     void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
00268       seconds = seconds_ - PosixZeroTime.seconds_;
00269       nanos = nanos_;
00270     }
00271 
00272     /// Provides conversion of the TimeValue into a readable time & date.
00273     /// @returns std::string containing the readable time value
00274     /// @brief Convert time to a string.
00275     std::string toString() const;
00276 
00277   /// @}
00278   /// @name Mutators
00279   /// @{
00280   public:
00281     /// The seconds component of the TimeValue is set to \p sec without
00282     /// modifying the nanoseconds part.  This is useful for whole second
00283     /// arithmetic.
00284     /// @brief Set the seconds component.
00285     void seconds (SecondsType sec ) {
00286       this->seconds_ = sec;
00287       this->normalize();
00288     }
00289 
00290     /// The nanoseconds component of the TimeValue is set to \p nanos without
00291     /// modifying the seconds part. This is useful for basic computations
00292     /// involving just the nanoseconds portion. Note that the TimeValue will be
00293     /// normalized after this call so that the fractional (nanoseconds) portion
00294     /// will have the smallest equivalent value.
00295     /// @brief Set the nanoseconds component using a number of nanoseconds.
00296     void nanoseconds ( NanoSecondsType nanos ) {
00297       this->nanos_ = nanos;
00298       this->normalize();
00299     }
00300 
00301     /// The seconds component remains unchanged.
00302     /// @brief Set the nanoseconds component using a number of microseconds.
00303     void microseconds ( int32_t micros ) {
00304       this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
00305       this->normalize();
00306     };
00307 
00308     /// The seconds component remains unchanged.
00309     /// @brief Set the nanoseconds component using a number of milliseconds.
00310     void milliseconds ( int32_t millis ) {
00311       this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
00312       this->normalize();
00313     };
00314 
00315     /// @brief Converts from microsecond format to TimeValue format
00316     void usec( int64_t microseconds ) {
00317       this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
00318       this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
00319         NANOSECONDS_PER_MICROSECOND;
00320       this->normalize();
00321     }
00322 
00323     /// @brief Converts from millisecond format to TimeValue format
00324     void msec( int64_t milliseconds ) {
00325       this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
00326       this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
00327         NANOSECONDS_PER_MILLISECOND;
00328       this->normalize();
00329     }
00330 
00331     /// Converts the \p seconds argument from PosixTime to the corresponding
00332     /// TimeValue and assigns that value to \p this.
00333     /// @brief Convert seconds form PosixTime to TimeValue
00334     void fromEpochTime( SecondsType seconds ) {
00335       seconds_ = seconds + PosixZeroTime.seconds_;
00336       nanos_ = 0;
00337       this->normalize();
00338     }
00339 
00340     /// Converts the \p win32Time argument from Windows FILETIME to the
00341     /// corresponding TimeValue and assigns that value to \p this.
00342     /// @brief Convert seconds form Windows FILETIME to TimeValue
00343     void fromWin32Time( uint64_t win32Time ) {
00344       this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
00345       this->nanos_ = NanoSecondsType(win32Time  % 10000000) * 100;
00346     }
00347 
00348   /// @}
00349   /// @name Implementation
00350   /// @{
00351   private:
00352     /// This causes the values to be represented so that the fractional
00353     /// part is minimized, possibly incrementing the seconds part.
00354     /// @brief Normalize to canonical form.
00355     void normalize();
00356 
00357 /// @}
00358   /// @name Data
00359   /// @{
00360   private:
00361       /// Store the values as a <timeval>.
00362       SecondsType      seconds_;///< Stores the seconds part of the TimeVal
00363       NanoSecondsType  nanos_;  ///< Stores the nanoseconds part of the TimeVal
00364 
00365   /// @}
00366 
00367   };
00368 
00369 inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
00370   TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
00371   sum.normalize ();
00372   return sum;
00373 }
00374 
00375 inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
00376   TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
00377   difference.normalize ();
00378   return difference;
00379 }
00380 
00381 }
00382 }
00383 
00384 FORCE_DEFINING_FILE_TO_BE_LINKED(SystemTimeValue)
00385 
00386 #endif