LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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