blob: e17fc1d716dd85e54440f9eeced6ff7f65b3bf1b [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include <ctime>
9#include <iosfwd>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include <limits>
11
Ben Murdochc5610432016-08-08 18:44:38 +010012#include "src/base/bits.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/base/macros.h"
Ben Murdochc5610432016-08-08 18:44:38 +010014#include "src/base/safe_math.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015
16// Forward declarations.
17extern "C" {
18struct _FILETIME;
19struct mach_timespec;
20struct timespec;
21struct timeval;
22}
23
24namespace v8 {
25namespace base {
26
27class Time;
Ben Murdochc5610432016-08-08 18:44:38 +010028class TimeDelta;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029class TimeTicks;
30
Ben Murdochc5610432016-08-08 18:44:38 +010031namespace time_internal {
32template<class TimeClass>
33class TimeBase;
34}
35
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036// -----------------------------------------------------------------------------
37// TimeDelta
38//
39// This class represents a duration of time, internally represented in
40// microseonds.
41
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042class TimeDelta final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 public:
44 TimeDelta() : delta_(0) {}
45
46 // Converts units of time to TimeDeltas.
47 static TimeDelta FromDays(int days);
48 static TimeDelta FromHours(int hours);
49 static TimeDelta FromMinutes(int minutes);
50 static TimeDelta FromSeconds(int64_t seconds);
51 static TimeDelta FromMilliseconds(int64_t milliseconds);
52 static TimeDelta FromMicroseconds(int64_t microseconds) {
53 return TimeDelta(microseconds);
54 }
55 static TimeDelta FromNanoseconds(int64_t nanoseconds);
56
57 // Returns the time delta in some unit. The F versions return a floating
58 // point value, the "regular" versions return a rounded-down value.
59 //
60 // InMillisecondsRoundedUp() instead returns an integer that is rounded up
61 // to the next full millisecond.
62 int InDays() const;
63 int InHours() const;
64 int InMinutes() const;
65 double InSecondsF() const;
66 int64_t InSeconds() const;
67 double InMillisecondsF() const;
68 int64_t InMilliseconds() const;
69 int64_t InMillisecondsRoundedUp() const;
70 int64_t InMicroseconds() const { return delta_; }
71 int64_t InNanoseconds() const;
72
73 // Converts to/from Mach time specs.
74 static TimeDelta FromMachTimespec(struct mach_timespec ts);
75 struct mach_timespec ToMachTimespec() const;
76
77 // Converts to/from POSIX time specs.
78 static TimeDelta FromTimespec(struct timespec ts);
79 struct timespec ToTimespec() const;
80
81 TimeDelta& operator=(const TimeDelta& other) {
82 delta_ = other.delta_;
83 return *this;
84 }
85
86 // Computations with other deltas.
87 TimeDelta operator+(const TimeDelta& other) const {
88 return TimeDelta(delta_ + other.delta_);
89 }
90 TimeDelta operator-(const TimeDelta& other) const {
91 return TimeDelta(delta_ - other.delta_);
92 }
93
94 TimeDelta& operator+=(const TimeDelta& other) {
95 delta_ += other.delta_;
96 return *this;
97 }
98 TimeDelta& operator-=(const TimeDelta& other) {
99 delta_ -= other.delta_;
100 return *this;
101 }
102 TimeDelta operator-() const {
103 return TimeDelta(-delta_);
104 }
105
106 double TimesOf(const TimeDelta& other) const {
107 return static_cast<double>(delta_) / static_cast<double>(other.delta_);
108 }
109 double PercentOf(const TimeDelta& other) const {
110 return TimesOf(other) * 100.0;
111 }
112
113 // Computations with ints, note that we only allow multiplicative operations
114 // with ints, and additive operations with other deltas.
115 TimeDelta operator*(int64_t a) const {
116 return TimeDelta(delta_ * a);
117 }
118 TimeDelta operator/(int64_t a) const {
119 return TimeDelta(delta_ / a);
120 }
121 TimeDelta& operator*=(int64_t a) {
122 delta_ *= a;
123 return *this;
124 }
125 TimeDelta& operator/=(int64_t a) {
126 delta_ /= a;
127 return *this;
128 }
129 int64_t operator/(const TimeDelta& other) const {
130 return delta_ / other.delta_;
131 }
132
133 // Comparison operators.
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 bool operator<=(const TimeDelta& other) const {
144 return delta_ <= other.delta_;
145 }
146 bool operator>(const TimeDelta& other) const {
147 return delta_ > other.delta_;
148 }
149 bool operator>=(const TimeDelta& other) const {
150 return delta_ >= other.delta_;
151 }
152
153 private:
Ben Murdochc5610432016-08-08 18:44:38 +0100154 template<class TimeClass> friend class time_internal::TimeBase;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000155 // Constructs a delta given the duration in microseconds. This is private
156 // to avoid confusion by callers with an integer constructor. Use
157 // FromSeconds, FromMilliseconds, etc. instead.
158 explicit TimeDelta(int64_t delta) : delta_(delta) {}
159
160 // Delta in microseconds.
161 int64_t delta_;
162};
163
164
Ben Murdochc5610432016-08-08 18:44:38 +0100165namespace time_internal {
166
167// TimeBase--------------------------------------------------------------------
168
169// Provides value storage and comparison/math operations common to all time
170// classes. Each subclass provides for strong type-checking to ensure
171// semantically meaningful comparison/math of time values from the same clock
172// source or timeline.
173template<class TimeClass>
174class TimeBase {
175 public:
176 static const int64_t kHoursPerDay = 24;
177 static const int64_t kMillisecondsPerSecond = 1000;
178 static const int64_t kMillisecondsPerDay =
179 kMillisecondsPerSecond * 60 * 60 * kHoursPerDay;
180 static const int64_t kMicrosecondsPerMillisecond = 1000;
181 static const int64_t kMicrosecondsPerSecond =
182 kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
183 static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
184 static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
185 static const int64_t kMicrosecondsPerDay =
186 kMicrosecondsPerHour * kHoursPerDay;
187 static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
188 static const int64_t kNanosecondsPerMicrosecond = 1000;
189 static const int64_t kNanosecondsPerSecond =
190 kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
191
192 // Returns true if this object has not been initialized.
193 //
194 // Warning: Be careful when writing code that performs math on time values,
195 // since it's possible to produce a valid "zero" result that should not be
196 // interpreted as a "null" value.
197 bool IsNull() const {
198 return us_ == 0;
199 }
200
201 // Returns true if this object represents the maximum time.
202 bool IsMax() const { return us_ == std::numeric_limits<int64_t>::max(); }
203
204 // For serializing only. Use FromInternalValue() to reconstitute. Please don't
205 // use this and do arithmetic on it, as it is more error prone than using the
206 // provided operators.
207 int64_t ToInternalValue() const { return us_; }
208
209 TimeClass& operator=(TimeClass other) {
210 us_ = other.us_;
211 return *(static_cast<TimeClass*>(this));
212 }
213
214 // Compute the difference between two times.
215 TimeDelta operator-(TimeClass other) const {
216 return TimeDelta::FromMicroseconds(us_ - other.us_);
217 }
218
219 // Return a new time modified by some delta.
220 TimeClass operator+(TimeDelta delta) const {
221 return TimeClass(bits::SignedSaturatedAdd64(delta.delta_, us_));
222 }
223 TimeClass operator-(TimeDelta delta) const {
224 return TimeClass(-bits::SignedSaturatedSub64(delta.delta_, us_));
225 }
226
227 // Modify by some time delta.
228 TimeClass& operator+=(TimeDelta delta) {
229 return static_cast<TimeClass&>(*this = (*this + delta));
230 }
231 TimeClass& operator-=(TimeDelta delta) {
232 return static_cast<TimeClass&>(*this = (*this - delta));
233 }
234
235 // Comparison operators
236 bool operator==(TimeClass other) const {
237 return us_ == other.us_;
238 }
239 bool operator!=(TimeClass other) const {
240 return us_ != other.us_;
241 }
242 bool operator<(TimeClass other) const {
243 return us_ < other.us_;
244 }
245 bool operator<=(TimeClass other) const {
246 return us_ <= other.us_;
247 }
248 bool operator>(TimeClass other) const {
249 return us_ > other.us_;
250 }
251 bool operator>=(TimeClass other) const {
252 return us_ >= other.us_;
253 }
254
255 // Converts an integer value representing TimeClass to a class. This is used
256 // when deserializing a |TimeClass| structure, using a value known to be
257 // compatible. It is not provided as a constructor because the integer type
258 // may be unclear from the perspective of a caller.
259 static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); }
260
261 protected:
262 explicit TimeBase(int64_t us) : us_(us) {}
263
264 // Time value in a microsecond timebase.
265 int64_t us_;
266};
267
268} // namespace time_internal
269
270
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271// -----------------------------------------------------------------------------
272// Time
273//
274// This class represents an absolute point in time, internally represented as
275// microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
276
Ben Murdochc5610432016-08-08 18:44:38 +0100277class Time final : public time_internal::TimeBase<Time> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000278 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279 // Contains the NULL time. Use Time::Now() to get the current time.
Ben Murdochc5610432016-08-08 18:44:38 +0100280 Time() : TimeBase(0) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281
282 // Returns the current time. Watch out, the system might adjust its clock
283 // in which case time will actually go backwards. We don't guarantee that
284 // times are increasing, or that two calls to Now() won't be the same.
285 static Time Now();
286
287 // Returns the current time. Same as Now() except that this function always
288 // uses system time so that there are no discrepancies between the returned
289 // time and system time even on virtual environments including our test bot.
290 // For timing sensitive unittests, this function should be used.
291 static Time NowFromSystemTime();
292
293 // Returns the time for epoch in Unix-like system (Jan 1, 1970).
294 static Time UnixEpoch() { return Time(0); }
295
296 // Returns the maximum time, which should be greater than any reasonable time
297 // with which we might compare it.
298 static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
299
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300 // Converts to/from POSIX time specs.
301 static Time FromTimespec(struct timespec ts);
302 struct timespec ToTimespec() const;
303
304 // Converts to/from POSIX time values.
305 static Time FromTimeval(struct timeval tv);
306 struct timeval ToTimeval() const;
307
308 // Converts to/from Windows file times.
309 static Time FromFiletime(struct _FILETIME ft);
310 struct _FILETIME ToFiletime() const;
311
312 // Converts to/from the Javascript convention for times, a number of
313 // milliseconds since the epoch:
314 static Time FromJsTime(double ms_since_epoch);
315 double ToJsTime() const;
316
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000317 private:
Ben Murdochc5610432016-08-08 18:44:38 +0100318 friend class time_internal::TimeBase<Time>;
319 explicit Time(int64_t us) : TimeBase(us) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320};
321
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322std::ostream& operator<<(std::ostream&, const Time&);
323
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000324inline Time operator+(const TimeDelta& delta, const Time& time) {
325 return time + delta;
326}
327
328
329// -----------------------------------------------------------------------------
330// TimeTicks
331//
332// This class represents an abstract time that is most of the time incrementing
333// for use in measuring time durations. It is internally represented in
334// microseconds. It can not be converted to a human-readable time, but is
335// guaranteed not to decrease (if the user changes the computer clock,
336// Time::Now() may actually decrease or jump). But note that TimeTicks may
337// "stand still", for example if the computer suspended.
338
Ben Murdochc5610432016-08-08 18:44:38 +0100339class TimeTicks final : public time_internal::TimeBase<TimeTicks> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000340 public:
Ben Murdochc5610432016-08-08 18:44:38 +0100341 TimeTicks() : TimeBase(0) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342
343 // Platform-dependent tick count representing "right now."
344 // The resolution of this clock is ~1-15ms. Resolution varies depending
345 // on hardware/operating system configuration.
346 // This method never returns a null TimeTicks.
347 static TimeTicks Now();
348
349 // Returns a platform-dependent high-resolution tick count. Implementation
350 // is hardware dependent and may or may not return sub-millisecond
351 // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
352 // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
353 // This method never returns a null TimeTicks.
354 static TimeTicks HighResolutionNow();
355
356 // Returns true if the high-resolution clock is working on this system.
357 static bool IsHighResolutionClockWorking();
358
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 private:
Ben Murdochc5610432016-08-08 18:44:38 +0100360 friend class time_internal::TimeBase<TimeTicks>;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361
Ben Murdochc5610432016-08-08 18:44:38 +0100362 // Please use Now() to create a new object. This is for internal use
363 // and testing. Ticks are in microseconds.
364 explicit TimeTicks(int64_t ticks) : TimeBase(ticks) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000365};
366
367inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
368 return ticks + delta;
369}
370
Ben Murdochc5610432016-08-08 18:44:38 +0100371
372// ThreadTicks ----------------------------------------------------------------
373
374// Represents a clock, specific to a particular thread, than runs only while the
375// thread is running.
376class ThreadTicks final : public time_internal::TimeBase<ThreadTicks> {
377 public:
378 ThreadTicks() : TimeBase(0) {}
379
380 // Returns true if ThreadTicks::Now() is supported on this system.
381 static bool IsSupported();
382
383 // Returns thread-specific CPU-time on systems that support this feature.
384 // Needs to be guarded with a call to IsSupported(). Use this timer
385 // to (approximately) measure how much time the calling thread spent doing
386 // actual work vs. being de-scheduled. May return bogus results if the thread
387 // migrates to another CPU between two calls. Returns an empty ThreadTicks
388 // object until the initialization is completed.
389 static ThreadTicks Now();
390
391 private:
392 // This is for internal use and testing. Ticks are in microseconds.
393 explicit ThreadTicks(int64_t ticks) : TimeBase(ticks) {}
394};
395
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000396} // namespace base
397} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000398
399#endif // V8_BASE_PLATFORM_TIME_H_