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