| Index: src/base/platform/time.h
|
| diff --git a/src/base/platform/time.h b/src/base/platform/time.h
|
| index c8140efe4a50ba9a23802267adeba271400f20b0..834f74a9d9501f5431435312e36dd75bd786d3d7 100644
|
| --- a/src/base/platform/time.h
|
| +++ b/src/base/platform/time.h
|
| @@ -9,7 +9,9 @@
|
| #include <iosfwd>
|
| #include <limits>
|
|
|
| +#include "src/base/bits.h"
|
| #include "src/base/macros.h"
|
| +#include "src/base/safe_math.h"
|
|
|
| // Forward declarations.
|
| extern "C" {
|
| @@ -23,8 +25,14 @@ namespace v8 {
|
| namespace base {
|
|
|
| class Time;
|
| +class TimeDelta;
|
| class TimeTicks;
|
|
|
| +namespace time_internal {
|
| +template<class TimeClass>
|
| +class TimeBase;
|
| +}
|
| +
|
| // -----------------------------------------------------------------------------
|
| // TimeDelta
|
| //
|
| @@ -143,6 +151,7 @@ class TimeDelta final {
|
| }
|
|
|
| private:
|
| + template<class TimeClass> friend class time_internal::TimeBase;
|
| // Constructs a delta given the duration in microseconds. This is private
|
| // to avoid confusion by callers with an integer constructor. Use
|
| // FromSeconds, FromMilliseconds, etc. instead.
|
| @@ -153,35 +162,123 @@ class TimeDelta final {
|
| };
|
|
|
|
|
| -// -----------------------------------------------------------------------------
|
| -// Time
|
| -//
|
| -// This class represents an absolute point in time, internally represented as
|
| -// microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
|
| +namespace time_internal {
|
| +
|
| +// TimeBase--------------------------------------------------------------------
|
|
|
| -class Time final {
|
| +// Provides value storage and comparison/math operations common to all time
|
| +// classes. Each subclass provides for strong type-checking to ensure
|
| +// semantically meaningful comparison/math of time values from the same clock
|
| +// source or timeline.
|
| +template<class TimeClass>
|
| +class TimeBase {
|
| public:
|
| + static const int64_t kHoursPerDay = 24;
|
| static const int64_t kMillisecondsPerSecond = 1000;
|
| + static const int64_t kMillisecondsPerDay =
|
| + kMillisecondsPerSecond * 60 * 60 * kHoursPerDay;
|
| static const int64_t kMicrosecondsPerMillisecond = 1000;
|
| - static const int64_t kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
|
| - kMillisecondsPerSecond;
|
| + static const int64_t kMicrosecondsPerSecond =
|
| + kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
|
| static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
|
| static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
|
| - static const int64_t kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
|
| + static const int64_t kMicrosecondsPerDay =
|
| + kMicrosecondsPerHour * kHoursPerDay;
|
| static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
|
| static const int64_t kNanosecondsPerMicrosecond = 1000;
|
| - static const int64_t kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
|
| - kMicrosecondsPerSecond;
|
| + static const int64_t kNanosecondsPerSecond =
|
| + kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
|
|
|
| - // Contains the NULL time. Use Time::Now() to get the current time.
|
| - Time() : us_(0) {}
|
| -
|
| - // Returns true if the time object has not been initialized.
|
| - bool IsNull() const { return us_ == 0; }
|
| + // Returns true if this object has not been initialized.
|
| + //
|
| + // Warning: Be careful when writing code that performs math on time values,
|
| + // since it's possible to produce a valid "zero" result that should not be
|
| + // interpreted as a "null" value.
|
| + bool IsNull() const {
|
| + return us_ == 0;
|
| + }
|
|
|
| - // Returns true if the time object is the maximum time.
|
| + // Returns true if this object represents the maximum time.
|
| bool IsMax() const { return us_ == std::numeric_limits<int64_t>::max(); }
|
|
|
| + // For serializing only. Use FromInternalValue() to reconstitute. Please don't
|
| + // use this and do arithmetic on it, as it is more error prone than using the
|
| + // provided operators.
|
| + int64_t ToInternalValue() const { return us_; }
|
| +
|
| + TimeClass& operator=(TimeClass other) {
|
| + us_ = other.us_;
|
| + return *(static_cast<TimeClass*>(this));
|
| + }
|
| +
|
| + // Compute the difference between two times.
|
| + TimeDelta operator-(TimeClass other) const {
|
| + return TimeDelta::FromMicroseconds(us_ - other.us_);
|
| + }
|
| +
|
| + // Return a new time modified by some delta.
|
| + TimeClass operator+(TimeDelta delta) const {
|
| + return TimeClass(bits::SignedSaturatedAdd64(delta.delta_, us_));
|
| + }
|
| + TimeClass operator-(TimeDelta delta) const {
|
| + return TimeClass(-bits::SignedSaturatedSub64(delta.delta_, us_));
|
| + }
|
| +
|
| + // Modify by some time delta.
|
| + TimeClass& operator+=(TimeDelta delta) {
|
| + return static_cast<TimeClass&>(*this = (*this + delta));
|
| + }
|
| + TimeClass& operator-=(TimeDelta delta) {
|
| + return static_cast<TimeClass&>(*this = (*this - delta));
|
| + }
|
| +
|
| + // Comparison operators
|
| + bool operator==(TimeClass other) const {
|
| + return us_ == other.us_;
|
| + }
|
| + bool operator!=(TimeClass other) const {
|
| + return us_ != other.us_;
|
| + }
|
| + bool operator<(TimeClass other) const {
|
| + return us_ < other.us_;
|
| + }
|
| + bool operator<=(TimeClass other) const {
|
| + return us_ <= other.us_;
|
| + }
|
| + bool operator>(TimeClass other) const {
|
| + return us_ > other.us_;
|
| + }
|
| + bool operator>=(TimeClass other) const {
|
| + return us_ >= other.us_;
|
| + }
|
| +
|
| + // Converts an integer value representing TimeClass to a class. This is used
|
| + // when deserializing a |TimeClass| structure, using a value known to be
|
| + // compatible. It is not provided as a constructor because the integer type
|
| + // may be unclear from the perspective of a caller.
|
| + static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); }
|
| +
|
| + protected:
|
| + explicit TimeBase(int64_t us) : us_(us) {}
|
| +
|
| + // Time value in a microsecond timebase.
|
| + int64_t us_;
|
| +};
|
| +
|
| +} // namespace time_internal
|
| +
|
| +
|
| +// -----------------------------------------------------------------------------
|
| +// Time
|
| +//
|
| +// This class represents an absolute point in time, internally represented as
|
| +// microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
|
| +
|
| +class Time final : public time_internal::TimeBase<Time> {
|
| + public:
|
| + // Contains the NULL time. Use Time::Now() to get the current time.
|
| + Time() : TimeBase(0) {}
|
| +
|
| // Returns the current time. Watch out, the system might adjust its clock
|
| // in which case time will actually go backwards. We don't guarantee that
|
| // times are increasing, or that two calls to Now() won't be the same.
|
| @@ -200,15 +297,6 @@ class Time final {
|
| // with which we might compare it.
|
| static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
|
|
|
| - // Converts to/from internal values. The meaning of the "internal value" is
|
| - // completely up to the implementation, so it should be treated as opaque.
|
| - static Time FromInternalValue(int64_t value) {
|
| - return Time(value);
|
| - }
|
| - int64_t ToInternalValue() const {
|
| - return us_;
|
| - }
|
| -
|
| // Converts to/from POSIX time specs.
|
| static Time FromTimespec(struct timespec ts);
|
| struct timespec ToTimespec() const;
|
| @@ -226,59 +314,9 @@ class Time final {
|
| static Time FromJsTime(double ms_since_epoch);
|
| double ToJsTime() const;
|
|
|
| - Time& operator=(const Time& other) {
|
| - us_ = other.us_;
|
| - return *this;
|
| - }
|
| -
|
| - // Compute the difference between two times.
|
| - TimeDelta operator-(const Time& other) const {
|
| - return TimeDelta::FromMicroseconds(us_ - other.us_);
|
| - }
|
| -
|
| - // Modify by some time delta.
|
| - Time& operator+=(const TimeDelta& delta) {
|
| - us_ += delta.InMicroseconds();
|
| - return *this;
|
| - }
|
| - Time& operator-=(const TimeDelta& delta) {
|
| - us_ -= delta.InMicroseconds();
|
| - return *this;
|
| - }
|
| -
|
| - // Return a new time modified by some delta.
|
| - Time operator+(const TimeDelta& delta) const {
|
| - return Time(us_ + delta.InMicroseconds());
|
| - }
|
| - Time operator-(const TimeDelta& delta) const {
|
| - return Time(us_ - delta.InMicroseconds());
|
| - }
|
| -
|
| - // Comparison operators
|
| - bool operator==(const Time& other) const {
|
| - return us_ == other.us_;
|
| - }
|
| - bool operator!=(const Time& other) const {
|
| - return us_ != other.us_;
|
| - }
|
| - bool operator<(const Time& other) const {
|
| - return us_ < other.us_;
|
| - }
|
| - bool operator<=(const Time& other) const {
|
| - return us_ <= other.us_;
|
| - }
|
| - bool operator>(const Time& other) const {
|
| - return us_ > other.us_;
|
| - }
|
| - bool operator>=(const Time& other) const {
|
| - return us_ >= other.us_;
|
| - }
|
| -
|
| private:
|
| - explicit Time(int64_t us) : us_(us) {}
|
| -
|
| - // Time in microseconds in UTC.
|
| - int64_t us_;
|
| + friend class time_internal::TimeBase<Time>;
|
| + explicit Time(int64_t us) : TimeBase(us) {}
|
| };
|
|
|
| std::ostream& operator<<(std::ostream&, const Time&);
|
| @@ -298,9 +336,9 @@ inline Time operator+(const TimeDelta& delta, const Time& time) {
|
| // Time::Now() may actually decrease or jump). But note that TimeTicks may
|
| // "stand still", for example if the computer suspended.
|
|
|
| -class TimeTicks final {
|
| +class TimeTicks final : public time_internal::TimeBase<TimeTicks> {
|
| public:
|
| - TimeTicks() : ticks_(0) {}
|
| + TimeTicks() : TimeBase(0) {}
|
|
|
| // Platform-dependent tick count representing "right now."
|
| // The resolution of this clock is ~1-15ms. Resolution varies depending
|
| @@ -318,73 +356,12 @@ class TimeTicks final {
|
| // Returns true if the high-resolution clock is working on this system.
|
| static bool IsHighResolutionClockWorking();
|
|
|
| - // Returns true if this object has not been initialized.
|
| - bool IsNull() const { return ticks_ == 0; }
|
| -
|
| - // Converts to/from internal values. The meaning of the "internal value" is
|
| - // completely up to the implementation, so it should be treated as opaque.
|
| - static TimeTicks FromInternalValue(int64_t value) {
|
| - return TimeTicks(value);
|
| - }
|
| - int64_t ToInternalValue() const {
|
| - return ticks_;
|
| - }
|
| -
|
| - TimeTicks& operator=(const TimeTicks other) {
|
| - ticks_ = other.ticks_;
|
| - return *this;
|
| - }
|
| -
|
| - // Compute the difference between two times.
|
| - TimeDelta operator-(const TimeTicks other) const {
|
| - return TimeDelta::FromMicroseconds(ticks_ - other.ticks_);
|
| - }
|
| -
|
| - // Modify by some time delta.
|
| - TimeTicks& operator+=(const TimeDelta& delta) {
|
| - ticks_ += delta.InMicroseconds();
|
| - return *this;
|
| - }
|
| - TimeTicks& operator-=(const TimeDelta& delta) {
|
| - ticks_ -= delta.InMicroseconds();
|
| - return *this;
|
| - }
|
| -
|
| - // Return a new TimeTicks modified by some delta.
|
| - TimeTicks operator+(const TimeDelta& delta) const {
|
| - return TimeTicks(ticks_ + delta.InMicroseconds());
|
| - }
|
| - TimeTicks operator-(const TimeDelta& delta) const {
|
| - return TimeTicks(ticks_ - delta.InMicroseconds());
|
| - }
|
| -
|
| - // Comparison operators
|
| - bool operator==(const TimeTicks& other) const {
|
| - return ticks_ == other.ticks_;
|
| - }
|
| - bool operator!=(const TimeTicks& other) const {
|
| - return ticks_ != other.ticks_;
|
| - }
|
| - bool operator<(const TimeTicks& other) const {
|
| - return ticks_ < other.ticks_;
|
| - }
|
| - bool operator<=(const TimeTicks& other) const {
|
| - return ticks_ <= other.ticks_;
|
| - }
|
| - bool operator>(const TimeTicks& other) const {
|
| - return ticks_ > other.ticks_;
|
| - }
|
| - bool operator>=(const TimeTicks& other) const {
|
| - return ticks_ >= other.ticks_;
|
| - }
|
| -
|
| private:
|
| + friend class time_internal::TimeBase<TimeTicks>;
|
| +
|
| // Please use Now() to create a new object. This is for internal use
|
| // and testing. Ticks is in microseconds.
|
| - explicit TimeTicks(int64_t ticks) : ticks_(ticks) {}
|
| -
|
| - // Tick count in microseconds.
|
| - int64_t ticks_;
|
| + explicit TimeTicks(int64_t ticks) : TimeBase(ticks) {}
|
| };
|
|
|
| inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
|
|
|