1//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This header file declares the operating system TimeValue concept. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SUPPORT_TIMEVALUE_H 15#define LLVM_SUPPORT_TIMEVALUE_H 16 17#include "llvm/Support/DataTypes.h" 18#include <string> 19 20namespace llvm { 21namespace sys { 22 /// This class is used where a precise fixed point in time is required. The 23 /// range of TimeValue spans many hundreds of billions of years both past and 24 /// present. The precision of TimeValue is to the nanosecond. However, the 25 /// actual precision of its values will be determined by the resolution of 26 /// the system clock. The TimeValue class is used in conjunction with several 27 /// other lib/System interfaces to specify the time at which a call should 28 /// timeout, etc. 29 /// @since 1.4 30 /// @brief Provides an abstraction for a fixed point in time. 31 class TimeValue { 32 33 /// @name Constants 34 /// @{ 35 public: 36 37 /// A constant TimeValue representing the smallest time 38 /// value permissible by the class. MinTime is some point 39 /// in the distant past, about 300 billion years BCE. 40 /// @brief The smallest possible time value. 41 static const TimeValue MinTime; 42 43 /// A constant TimeValue representing the largest time 44 /// value permissible by the class. MaxTime is some point 45 /// in the distant future, about 300 billion years AD. 46 /// @brief The largest possible time value. 47 static const TimeValue MaxTime; 48 49 /// A constant TimeValue representing the base time, 50 /// or zero time of 00:00:00 (midnight) January 1st, 2000. 51 /// @brief 00:00:00 Jan 1, 2000 UTC. 52 static const TimeValue ZeroTime; 53 54 /// A constant TimeValue for the Posix base time which is 55 /// 00:00:00 (midnight) January 1st, 1970. 56 /// @brief 00:00:00 Jan 1, 1970 UTC. 57 static const TimeValue PosixZeroTime; 58 59 /// A constant TimeValue for the Win32 base time which is 60 /// 00:00:00 (midnight) January 1st, 1601. 61 /// @brief 00:00:00 Jan 1, 1601 UTC. 62 static const TimeValue Win32ZeroTime; 63 64 /// @} 65 /// @name Types 66 /// @{ 67 public: 68 typedef int64_t SecondsType; ///< Type used for representing seconds. 69 typedef int32_t NanoSecondsType;///< Type used for representing nanoseconds. 70 71 enum TimeConversions { 72 NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion 73 MICROSECONDS_PER_SECOND = 1000000, ///< One Million 74 MILLISECONDS_PER_SECOND = 1000, ///< One Thousand 75 NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand 76 NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million 77 NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 10^7 Hz (10ns) 78 }; 79 80 /// @} 81 /// @name Constructors 82 /// @{ 83 public: 84 /// \brief Default construct a time value, initializing to ZeroTime. 85 TimeValue() : seconds_(0), nanos_(0) {} 86 87 /// Caller provides the exact value in seconds and nanoseconds. The 88 /// \p nanos argument defaults to zero for convenience. 89 /// @brief Explicit constructor 90 explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0) 91 : seconds_( seconds ), nanos_( nanos ) { this->normalize(); } 92 93 /// Caller provides the exact value as a double in seconds with the 94 /// fractional part representing nanoseconds. 95 /// @brief Double Constructor. 96 explicit TimeValue( double new_time ) 97 : seconds_( 0 ) , nanos_ ( 0 ) { 98 SecondsType integer_part = static_cast<SecondsType>( new_time ); 99 seconds_ = integer_part; 100 nanos_ = static_cast<NanoSecondsType>( (new_time - 101 static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND ); 102 this->normalize(); 103 } 104 105 /// This is a static constructor that returns a TimeValue that represents 106 /// the current time. 107 /// @brief Creates a TimeValue with the current time (UTC). 108 static TimeValue now(); 109 110 /// @} 111 /// @name Operators 112 /// @{ 113 public: 114 /// Add \p that to \p this. 115 /// @returns this 116 /// @brief Incrementing assignment operator. 117 TimeValue& operator += (const TimeValue& that ) { 118 this->seconds_ += that.seconds_ ; 119 this->nanos_ += that.nanos_ ; 120 this->normalize(); 121 return *this; 122 } 123 124 /// Subtract \p that from \p this. 125 /// @returns this 126 /// @brief Decrementing assignment operator. 127 TimeValue& operator -= (const TimeValue &that ) { 128 this->seconds_ -= that.seconds_ ; 129 this->nanos_ -= that.nanos_ ; 130 this->normalize(); 131 return *this; 132 } 133 134 /// Determine if \p this is less than \p that. 135 /// @returns True iff *this < that. 136 /// @brief True if this < that. 137 int operator < (const TimeValue &that) const { return that > *this; } 138 139 /// Determine if \p this is greather than \p that. 140 /// @returns True iff *this > that. 141 /// @brief True if this > that. 142 int operator > (const TimeValue &that) const { 143 if ( this->seconds_ > that.seconds_ ) { 144 return 1; 145 } else if ( this->seconds_ == that.seconds_ ) { 146 if ( this->nanos_ > that.nanos_ ) return 1; 147 } 148 return 0; 149 } 150 151 /// Determine if \p this is less than or equal to \p that. 152 /// @returns True iff *this <= that. 153 /// @brief True if this <= that. 154 int operator <= (const TimeValue &that) const { return that >= *this; } 155 156 /// Determine if \p this is greater than or equal to \p that. 157 /// @returns True iff *this >= that. 158 int operator >= (const TimeValue &that) const { 159 if ( this->seconds_ > that.seconds_ ) { 160 return 1; 161 } else if ( this->seconds_ == that.seconds_ ) { 162 if ( this->nanos_ >= that.nanos_ ) return 1; 163 } 164 return 0; 165 } 166 167 /// Determines if two TimeValue objects represent the same moment in time. 168 /// @returns True iff *this == that. 169 int operator == (const TimeValue &that) const { 170 return (this->seconds_ == that.seconds_) && 171 (this->nanos_ == that.nanos_); 172 } 173 174 /// Determines if two TimeValue objects represent times that are not the 175 /// same. 176 /// @returns True iff *this != that. 177 int operator != (const TimeValue &that) const { return !(*this == that); } 178 179 /// Adds two TimeValue objects together. 180 /// @returns The sum of the two operands as a new TimeValue 181 /// @brief Addition operator. 182 friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2); 183 184 /// Subtracts two TimeValue objects. 185 /// @returns The difference of the two operands as a new TimeValue 186 /// @brief Subtraction operator. 187 friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2); 188 189 /// @} 190 /// @name Accessors 191 /// @{ 192 public: 193 194 /// Returns only the seconds component of the TimeValue. The nanoseconds 195 /// portion is ignored. No rounding is performed. 196 /// @brief Retrieve the seconds component 197 SecondsType seconds() const { return seconds_; } 198 199 /// Returns only the nanoseconds component of the TimeValue. The seconds 200 /// portion is ignored. 201 /// @brief Retrieve the nanoseconds component. 202 NanoSecondsType nanoseconds() const { return nanos_; } 203 204 /// Returns only the fractional portion of the TimeValue rounded down to the 205 /// nearest microsecond (divide by one thousand). 206 /// @brief Retrieve the fractional part as microseconds; 207 uint32_t microseconds() const { 208 return nanos_ / NANOSECONDS_PER_MICROSECOND; 209 } 210 211 /// Returns only the fractional portion of the TimeValue rounded down to the 212 /// nearest millisecond (divide by one million). 213 /// @brief Retrieve the fractional part as milliseconds; 214 uint32_t milliseconds() const { 215 return nanos_ / NANOSECONDS_PER_MILLISECOND; 216 } 217 218 /// Returns the TimeValue as a number of microseconds. Note that the value 219 /// returned can overflow because the range of a uint64_t is smaller than 220 /// the range of a TimeValue. Nevertheless, this is useful on some operating 221 /// systems and is therefore provided. 222 /// @brief Convert to a number of microseconds (can overflow) 223 uint64_t usec() const { 224 return seconds_ * MICROSECONDS_PER_SECOND + 225 ( nanos_ / NANOSECONDS_PER_MICROSECOND ); 226 } 227 228 /// Returns the TimeValue as a number of milliseconds. Note that the value 229 /// returned can overflow because the range of a uint64_t is smaller than 230 /// the range of a TimeValue. Nevertheless, this is useful on some operating 231 /// systems and is therefore provided. 232 /// @brief Convert to a number of milliseconds (can overflow) 233 uint64_t msec() const { 234 return seconds_ * MILLISECONDS_PER_SECOND + 235 ( nanos_ / NANOSECONDS_PER_MILLISECOND ); 236 } 237 238 /// Converts the TimeValue into the corresponding number of seconds 239 /// since the epoch (00:00:00 Jan 1,1970). 240 uint64_t toEpochTime() const { 241 return seconds_ - PosixZeroTimeSeconds; 242 } 243 244 /// Converts the TimeValue into the corresponding number of "ticks" for 245 /// Win32 platforms, correcting for the difference in Win32 zero time. 246 /// @brief Convert to Win32's FILETIME 247 /// (100ns intervals since 00:00:00 Jan 1, 1601 UTC) 248 uint64_t toWin32Time() const { 249 uint64_t result = (uint64_t)10000000 * (seconds_ - Win32ZeroTimeSeconds); 250 result += nanos_ / NANOSECONDS_PER_WIN32_TICK; 251 return result; 252 } 253 254 /// Provides the seconds and nanoseconds as results in its arguments after 255 /// correction for the Posix zero time. 256 /// @brief Convert to timespec time (ala POSIX.1b) 257 void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const { 258 seconds = seconds_ - PosixZeroTimeSeconds; 259 nanos = nanos_; 260 } 261 262 /// Provides conversion of the TimeValue into a readable time & date. 263 /// @returns std::string containing the readable time value 264 /// @brief Convert time to a string. 265 std::string str() const; 266 267 /// @} 268 /// @name Mutators 269 /// @{ 270 public: 271 /// The seconds component of the TimeValue is set to \p sec without 272 /// modifying the nanoseconds part. This is useful for whole second 273 /// arithmetic. 274 /// @brief Set the seconds component. 275 void seconds (SecondsType sec ) { 276 this->seconds_ = sec; 277 this->normalize(); 278 } 279 280 /// The nanoseconds component of the TimeValue is set to \p nanos without 281 /// modifying the seconds part. This is useful for basic computations 282 /// involving just the nanoseconds portion. Note that the TimeValue will be 283 /// normalized after this call so that the fractional (nanoseconds) portion 284 /// will have the smallest equivalent value. 285 /// @brief Set the nanoseconds component using a number of nanoseconds. 286 void nanoseconds ( NanoSecondsType nanos ) { 287 this->nanos_ = nanos; 288 this->normalize(); 289 } 290 291 /// The seconds component remains unchanged. 292 /// @brief Set the nanoseconds component using a number of microseconds. 293 void microseconds ( int32_t micros ) { 294 this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND; 295 this->normalize(); 296 } 297 298 /// The seconds component remains unchanged. 299 /// @brief Set the nanoseconds component using a number of milliseconds. 300 void milliseconds ( int32_t millis ) { 301 this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND; 302 this->normalize(); 303 } 304 305 /// @brief Converts from microsecond format to TimeValue format 306 void usec( int64_t microseconds ) { 307 this->seconds_ = microseconds / MICROSECONDS_PER_SECOND; 308 this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) * 309 NANOSECONDS_PER_MICROSECOND; 310 this->normalize(); 311 } 312 313 /// @brief Converts from millisecond format to TimeValue format 314 void msec( int64_t milliseconds ) { 315 this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND; 316 this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) * 317 NANOSECONDS_PER_MILLISECOND; 318 this->normalize(); 319 } 320 321 /// Converts the \p seconds argument from PosixTime to the corresponding 322 /// TimeValue and assigns that value to \p this. 323 /// @brief Convert seconds form PosixTime to TimeValue 324 void fromEpochTime( SecondsType seconds ) { 325 seconds_ = seconds + PosixZeroTimeSeconds; 326 nanos_ = 0; 327 this->normalize(); 328 } 329 330 /// Converts the \p win32Time argument from Windows FILETIME to the 331 /// corresponding TimeValue and assigns that value to \p this. 332 /// @brief Convert seconds form Windows FILETIME to TimeValue 333 void fromWin32Time( uint64_t win32Time ) { 334 this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds; 335 this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100; 336 } 337 338 /// @} 339 /// @name Implementation 340 /// @{ 341 private: 342 /// This causes the values to be represented so that the fractional 343 /// part is minimized, possibly incrementing the seconds part. 344 /// @brief Normalize to canonical form. 345 void normalize(); 346 347 /// @} 348 /// @name Data 349 /// @{ 350 private: 351 /// Store the values as a <timeval>. 352 SecondsType seconds_;///< Stores the seconds part of the TimeVal 353 NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal 354 355 static const SecondsType PosixZeroTimeSeconds; 356 static const SecondsType Win32ZeroTimeSeconds; 357 /// @} 358 359 }; 360 361inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) { 362 TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_); 363 sum.normalize (); 364 return sum; 365} 366 367inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) { 368 TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ ); 369 difference.normalize (); 370 return difference; 371} 372 373} 374} 375 376#endif 377