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