Home | History | Annotate | Download | only in platform
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_BASE_PLATFORM_TIME_H_
      6 #define V8_BASE_PLATFORM_TIME_H_
      7 
      8 #include <time.h>
      9 #include <limits>
     10 
     11 #include "src/base/macros.h"
     12 
     13 // Forward declarations.
     14 extern "C" {
     15 struct _FILETIME;
     16 struct mach_timespec;
     17 struct timespec;
     18 struct timeval;
     19 }
     20 
     21 namespace v8 {
     22 namespace base {
     23 
     24 class Time;
     25 class TimeTicks;
     26 
     27 // -----------------------------------------------------------------------------
     28 // TimeDelta
     29 //
     30 // This class represents a duration of time, internally represented in
     31 // microseonds.
     32 
     33 class TimeDelta FINAL {
     34  public:
     35   TimeDelta() : delta_(0) {}
     36 
     37   // Converts units of time to TimeDeltas.
     38   static TimeDelta FromDays(int days);
     39   static TimeDelta FromHours(int hours);
     40   static TimeDelta FromMinutes(int minutes);
     41   static TimeDelta FromSeconds(int64_t seconds);
     42   static TimeDelta FromMilliseconds(int64_t milliseconds);
     43   static TimeDelta FromMicroseconds(int64_t microseconds) {
     44     return TimeDelta(microseconds);
     45   }
     46   static TimeDelta FromNanoseconds(int64_t nanoseconds);
     47 
     48   // Returns the time delta in some unit. The F versions return a floating
     49   // point value, the "regular" versions return a rounded-down value.
     50   //
     51   // InMillisecondsRoundedUp() instead returns an integer that is rounded up
     52   // to the next full millisecond.
     53   int InDays() const;
     54   int InHours() const;
     55   int InMinutes() const;
     56   double InSecondsF() const;
     57   int64_t InSeconds() const;
     58   double InMillisecondsF() const;
     59   int64_t InMilliseconds() const;
     60   int64_t InMillisecondsRoundedUp() const;
     61   int64_t InMicroseconds() const { return delta_; }
     62   int64_t InNanoseconds() const;
     63 
     64   // Converts to/from Mach time specs.
     65   static TimeDelta FromMachTimespec(struct mach_timespec ts);
     66   struct mach_timespec ToMachTimespec() const;
     67 
     68   // Converts to/from POSIX time specs.
     69   static TimeDelta FromTimespec(struct timespec ts);
     70   struct timespec ToTimespec() const;
     71 
     72   TimeDelta& operator=(const TimeDelta& other) {
     73     delta_ = other.delta_;
     74     return *this;
     75   }
     76 
     77   // Computations with other deltas.
     78   TimeDelta operator+(const TimeDelta& other) const {
     79     return TimeDelta(delta_ + other.delta_);
     80   }
     81   TimeDelta operator-(const TimeDelta& other) const {
     82     return TimeDelta(delta_ - other.delta_);
     83   }
     84 
     85   TimeDelta& operator+=(const TimeDelta& other) {
     86     delta_ += other.delta_;
     87     return *this;
     88   }
     89   TimeDelta& operator-=(const TimeDelta& other) {
     90     delta_ -= other.delta_;
     91     return *this;
     92   }
     93   TimeDelta operator-() const {
     94     return TimeDelta(-delta_);
     95   }
     96 
     97   double TimesOf(const TimeDelta& other) const {
     98     return static_cast<double>(delta_) / static_cast<double>(other.delta_);
     99   }
    100   double PercentOf(const TimeDelta& other) const {
    101     return TimesOf(other) * 100.0;
    102   }
    103 
    104   // Computations with ints, note that we only allow multiplicative operations
    105   // with ints, and additive operations with other deltas.
    106   TimeDelta operator*(int64_t a) const {
    107     return TimeDelta(delta_ * a);
    108   }
    109   TimeDelta operator/(int64_t a) const {
    110     return TimeDelta(delta_ / a);
    111   }
    112   TimeDelta& operator*=(int64_t a) {
    113     delta_ *= a;
    114     return *this;
    115   }
    116   TimeDelta& operator/=(int64_t a) {
    117     delta_ /= a;
    118     return *this;
    119   }
    120   int64_t operator/(const TimeDelta& other) const {
    121     return delta_ / other.delta_;
    122   }
    123 
    124   // Comparison operators.
    125   bool operator==(const TimeDelta& other) const {
    126     return delta_ == other.delta_;
    127   }
    128   bool operator!=(const TimeDelta& other) const {
    129     return delta_ != other.delta_;
    130   }
    131   bool operator<(const TimeDelta& other) const {
    132     return delta_ < other.delta_;
    133   }
    134   bool operator<=(const TimeDelta& other) const {
    135     return delta_ <= other.delta_;
    136   }
    137   bool operator>(const TimeDelta& other) const {
    138     return delta_ > other.delta_;
    139   }
    140   bool operator>=(const TimeDelta& other) const {
    141     return delta_ >= other.delta_;
    142   }
    143 
    144  private:
    145   // Constructs a delta given the duration in microseconds. This is private
    146   // to avoid confusion by callers with an integer constructor. Use
    147   // FromSeconds, FromMilliseconds, etc. instead.
    148   explicit TimeDelta(int64_t delta) : delta_(delta) {}
    149 
    150   // Delta in microseconds.
    151   int64_t delta_;
    152 };
    153 
    154 
    155 // -----------------------------------------------------------------------------
    156 // Time
    157 //
    158 // This class represents an absolute point in time, internally represented as
    159 // microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
    160 
    161 class Time FINAL {
    162  public:
    163   static const int64_t kMillisecondsPerSecond = 1000;
    164   static const int64_t kMicrosecondsPerMillisecond = 1000;
    165   static const int64_t kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
    166                                                 kMillisecondsPerSecond;
    167   static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
    168   static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
    169   static const int64_t kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
    170   static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
    171   static const int64_t kNanosecondsPerMicrosecond = 1000;
    172   static const int64_t kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
    173                                                kMicrosecondsPerSecond;
    174 
    175   // Contains the NULL time. Use Time::Now() to get the current time.
    176   Time() : us_(0) {}
    177 
    178   // Returns true if the time object has not been initialized.
    179   bool IsNull() const { return us_ == 0; }
    180 
    181   // Returns true if the time object is the maximum time.
    182   bool IsMax() const { return us_ == std::numeric_limits<int64_t>::max(); }
    183 
    184   // Returns the current time. Watch out, the system might adjust its clock
    185   // in which case time will actually go backwards. We don't guarantee that
    186   // times are increasing, or that two calls to Now() won't be the same.
    187   static Time Now();
    188 
    189   // Returns the current time. Same as Now() except that this function always
    190   // uses system time so that there are no discrepancies between the returned
    191   // time and system time even on virtual environments including our test bot.
    192   // For timing sensitive unittests, this function should be used.
    193   static Time NowFromSystemTime();
    194 
    195   // Returns the time for epoch in Unix-like system (Jan 1, 1970).
    196   static Time UnixEpoch() { return Time(0); }
    197 
    198   // Returns the maximum time, which should be greater than any reasonable time
    199   // with which we might compare it.
    200   static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
    201 
    202   // Converts to/from internal values. The meaning of the "internal value" is
    203   // completely up to the implementation, so it should be treated as opaque.
    204   static Time FromInternalValue(int64_t value) {
    205     return Time(value);
    206   }
    207   int64_t ToInternalValue() const {
    208     return us_;
    209   }
    210 
    211   // Converts to/from POSIX time specs.
    212   static Time FromTimespec(struct timespec ts);
    213   struct timespec ToTimespec() const;
    214 
    215   // Converts to/from POSIX time values.
    216   static Time FromTimeval(struct timeval tv);
    217   struct timeval ToTimeval() const;
    218 
    219   // Converts to/from Windows file times.
    220   static Time FromFiletime(struct _FILETIME ft);
    221   struct _FILETIME ToFiletime() const;
    222 
    223   // Converts to/from the Javascript convention for times, a number of
    224   // milliseconds since the epoch:
    225   static Time FromJsTime(double ms_since_epoch);
    226   double ToJsTime() const;
    227 
    228   Time& operator=(const Time& other) {
    229     us_ = other.us_;
    230     return *this;
    231   }
    232 
    233   // Compute the difference between two times.
    234   TimeDelta operator-(const Time& other) const {
    235     return TimeDelta::FromMicroseconds(us_ - other.us_);
    236   }
    237 
    238   // Modify by some time delta.
    239   Time& operator+=(const TimeDelta& delta) {
    240     us_ += delta.InMicroseconds();
    241     return *this;
    242   }
    243   Time& operator-=(const TimeDelta& delta) {
    244     us_ -= delta.InMicroseconds();
    245     return *this;
    246   }
    247 
    248   // Return a new time modified by some delta.
    249   Time operator+(const TimeDelta& delta) const {
    250     return Time(us_ + delta.InMicroseconds());
    251   }
    252   Time operator-(const TimeDelta& delta) const {
    253     return Time(us_ - delta.InMicroseconds());
    254   }
    255 
    256   // Comparison operators
    257   bool operator==(const Time& other) const {
    258     return us_ == other.us_;
    259   }
    260   bool operator!=(const Time& other) const {
    261     return us_ != other.us_;
    262   }
    263   bool operator<(const Time& other) const {
    264     return us_ < other.us_;
    265   }
    266   bool operator<=(const Time& other) const {
    267     return us_ <= other.us_;
    268   }
    269   bool operator>(const Time& other) const {
    270     return us_ > other.us_;
    271   }
    272   bool operator>=(const Time& other) const {
    273     return us_ >= other.us_;
    274   }
    275 
    276  private:
    277   explicit Time(int64_t us) : us_(us) {}
    278 
    279   // Time in microseconds in UTC.
    280   int64_t us_;
    281 };
    282 
    283 inline Time operator+(const TimeDelta& delta, const Time& time) {
    284   return time + delta;
    285 }
    286 
    287 
    288 // -----------------------------------------------------------------------------
    289 // TimeTicks
    290 //
    291 // This class represents an abstract time that is most of the time incrementing
    292 // for use in measuring time durations. It is internally represented in
    293 // microseconds.  It can not be converted to a human-readable time, but is
    294 // guaranteed not to decrease (if the user changes the computer clock,
    295 // Time::Now() may actually decrease or jump).  But note that TimeTicks may
    296 // "stand still", for example if the computer suspended.
    297 
    298 class TimeTicks FINAL {
    299  public:
    300   TimeTicks() : ticks_(0) {}
    301 
    302   // Platform-dependent tick count representing "right now."
    303   // The resolution of this clock is ~1-15ms.  Resolution varies depending
    304   // on hardware/operating system configuration.
    305   // This method never returns a null TimeTicks.
    306   static TimeTicks Now();
    307 
    308   // Returns a platform-dependent high-resolution tick count. Implementation
    309   // is hardware dependent and may or may not return sub-millisecond
    310   // resolution.  THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
    311   // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
    312   // This method never returns a null TimeTicks.
    313   static TimeTicks HighResolutionNow();
    314 
    315   // Returns true if the high-resolution clock is working on this system.
    316   static bool IsHighResolutionClockWorking();
    317 
    318   // Returns Linux kernel timestamp for generating profiler events. This method
    319   // returns null TimeTicks if the kernel cannot provide the timestamps (e.g.,
    320   // on non-Linux OS or if the kernel module for timestamps is not loaded).
    321 
    322   static TimeTicks KernelTimestampNow();
    323   static bool KernelTimestampAvailable();
    324 
    325   // Returns true if this object has not been initialized.
    326   bool IsNull() const { return ticks_ == 0; }
    327 
    328   // Converts to/from internal values. The meaning of the "internal value" is
    329   // completely up to the implementation, so it should be treated as opaque.
    330   static TimeTicks FromInternalValue(int64_t value) {
    331     return TimeTicks(value);
    332   }
    333   int64_t ToInternalValue() const {
    334     return ticks_;
    335   }
    336 
    337   TimeTicks& operator=(const TimeTicks other) {
    338     ticks_ = other.ticks_;
    339     return *this;
    340   }
    341 
    342   // Compute the difference between two times.
    343   TimeDelta operator-(const TimeTicks other) const {
    344     return TimeDelta::FromMicroseconds(ticks_ - other.ticks_);
    345   }
    346 
    347   // Modify by some time delta.
    348   TimeTicks& operator+=(const TimeDelta& delta) {
    349     ticks_ += delta.InMicroseconds();
    350     return *this;
    351   }
    352   TimeTicks& operator-=(const TimeDelta& delta) {
    353     ticks_ -= delta.InMicroseconds();
    354     return *this;
    355   }
    356 
    357   // Return a new TimeTicks modified by some delta.
    358   TimeTicks operator+(const TimeDelta& delta) const {
    359     return TimeTicks(ticks_ + delta.InMicroseconds());
    360   }
    361   TimeTicks operator-(const TimeDelta& delta) const {
    362     return TimeTicks(ticks_ - delta.InMicroseconds());
    363   }
    364 
    365   // Comparison operators
    366   bool operator==(const TimeTicks& other) const {
    367     return ticks_ == other.ticks_;
    368   }
    369   bool operator!=(const TimeTicks& other) const {
    370     return ticks_ != other.ticks_;
    371   }
    372   bool operator<(const TimeTicks& other) const {
    373     return ticks_ < other.ticks_;
    374   }
    375   bool operator<=(const TimeTicks& other) const {
    376     return ticks_ <= other.ticks_;
    377   }
    378   bool operator>(const TimeTicks& other) const {
    379     return ticks_ > other.ticks_;
    380   }
    381   bool operator>=(const TimeTicks& other) const {
    382     return ticks_ >= other.ticks_;
    383   }
    384 
    385  private:
    386   // Please use Now() to create a new object. This is for internal use
    387   // and testing. Ticks is in microseconds.
    388   explicit TimeTicks(int64_t ticks) : ticks_(ticks) {}
    389 
    390   // Tick count in microseconds.
    391   int64_t ticks_;
    392 };
    393 
    394 inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
    395   return ticks + delta;
    396 }
    397 
    398 } }  // namespace v8::base
    399 
    400 #endif  // V8_BASE_PLATFORM_TIME_H_
    401