Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
14 KiB

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