V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
time.h
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 <stdint.h>
9 
10 #include <ctime>
11 #include <iosfwd>
12 #include <limits>
13 
14 #include "src/base/base-export.h"
15 #include "src/base/bits.h"
16 #include "src/base/macros.h"
17 #include "src/base/safe_math.h"
18 #if V8_OS_WIN
19 #include "src/base/win32-headers.h"
20 #endif
21 
22 // Forward declarations.
23 extern "C" {
24 struct _FILETIME;
25 struct mach_timespec;
26 struct timespec;
27 struct timeval;
28 }
29 
30 namespace v8 {
31 namespace base {
32 
33 class Time;
34 class TimeDelta;
35 class TimeTicks;
36 
37 namespace time_internal {
38 template<class TimeClass>
39 class TimeBase;
40 }
41 
43  public:
44  static constexpr int64_t kHoursPerDay = 24;
45  static constexpr int64_t kMillisecondsPerSecond = 1000;
46  static constexpr int64_t kMillisecondsPerDay =
47  kMillisecondsPerSecond * 60 * 60 * kHoursPerDay;
48  static constexpr int64_t kMicrosecondsPerMillisecond = 1000;
49  static constexpr int64_t kMicrosecondsPerSecond =
50  kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
51  static constexpr int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
52  static constexpr int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
53  static constexpr int64_t kMicrosecondsPerDay =
54  kMicrosecondsPerHour * kHoursPerDay;
55  static constexpr int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
56  static constexpr int64_t kNanosecondsPerMicrosecond = 1000;
57  static constexpr int64_t kNanosecondsPerSecond =
58  kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
59 };
60 
61 // -----------------------------------------------------------------------------
62 // TimeDelta
63 //
64 // This class represents a duration of time, internally represented in
65 // microseonds.
66 
67 class V8_BASE_EXPORT TimeDelta final {
68  public:
69  constexpr TimeDelta() : delta_(0) {}
70 
71  // Converts units of time to TimeDeltas.
72  static constexpr TimeDelta FromDays(int days) {
73  return TimeDelta(days * TimeConstants::kMicrosecondsPerDay);
74  }
75  static constexpr TimeDelta FromHours(int hours) {
76  return TimeDelta(hours * TimeConstants::kMicrosecondsPerHour);
77  }
78  static constexpr TimeDelta FromMinutes(int minutes) {
79  return TimeDelta(minutes * TimeConstants::kMicrosecondsPerMinute);
80  }
81  static constexpr TimeDelta FromSeconds(int64_t seconds) {
82  return TimeDelta(seconds * TimeConstants::kMicrosecondsPerSecond);
83  }
84  static constexpr TimeDelta FromMilliseconds(int64_t milliseconds) {
85  return TimeDelta(milliseconds * TimeConstants::kMicrosecondsPerMillisecond);
86  }
87  static constexpr TimeDelta FromMicroseconds(int64_t microseconds) {
88  return TimeDelta(microseconds);
89  }
90  static constexpr TimeDelta FromNanoseconds(int64_t nanoseconds) {
91  return TimeDelta(nanoseconds / TimeConstants::kNanosecondsPerMicrosecond);
92  }
93 
94  // Returns the maximum time delta, which should be greater than any reasonable
95  // time delta we might compare it to. Adding or subtracting the maximum time
96  // delta to a time or another time delta has an undefined result.
97  static constexpr TimeDelta Max();
98 
99  // Returns the minimum time delta, which should be less than than any
100  // reasonable time delta we might compare it to. Adding or subtracting the
101  // minimum time delta to a time or another time delta has an undefined result.
102  static constexpr TimeDelta Min();
103 
104  // Returns true if the time delta is zero.
105  constexpr bool IsZero() const { return delta_ == 0; }
106 
107  // Returns true if the time delta is the maximum/minimum time delta.
108  constexpr bool IsMax() const {
109  return delta_ == std::numeric_limits<int64_t>::max();
110  }
111  constexpr bool IsMin() const {
112  return delta_ == std::numeric_limits<int64_t>::min();
113  }
114 
115  // Returns the time delta in some unit. The F versions return a floating
116  // point value, the "regular" versions return a rounded-down value.
117  //
118  // InMillisecondsRoundedUp() instead returns an integer that is rounded up
119  // to the next full millisecond.
120  int InDays() const;
121  int InHours() const;
122  int InMinutes() const;
123  double InSecondsF() const;
124  int64_t InSeconds() const;
125  double InMillisecondsF() const;
126  int64_t InMilliseconds() const;
127  int64_t InMillisecondsRoundedUp() const;
128  int64_t InMicroseconds() const;
129  int64_t InNanoseconds() const;
130 
131  // Converts to/from Mach time specs.
132  static TimeDelta FromMachTimespec(struct mach_timespec ts);
133  struct mach_timespec ToMachTimespec() const;
134 
135  // Converts to/from POSIX time specs.
136  static TimeDelta FromTimespec(struct timespec ts);
137  struct timespec ToTimespec() const;
138 
139  TimeDelta& operator=(const TimeDelta& other) = default;
140 
141  // Computations with other deltas.
142  TimeDelta operator+(const TimeDelta& other) const {
143  return TimeDelta(delta_ + other.delta_);
144  }
145  TimeDelta operator-(const TimeDelta& other) const {
146  return TimeDelta(delta_ - other.delta_);
147  }
148 
149  TimeDelta& operator+=(const TimeDelta& other) {
150  delta_ += other.delta_;
151  return *this;
152  }
153  TimeDelta& operator-=(const TimeDelta& other) {
154  delta_ -= other.delta_;
155  return *this;
156  }
157  constexpr TimeDelta operator-() const { return TimeDelta(-delta_); }
158 
159  double TimesOf(const TimeDelta& other) const {
160  return static_cast<double>(delta_) / static_cast<double>(other.delta_);
161  }
162  double PercentOf(const TimeDelta& other) const {
163  return TimesOf(other) * 100.0;
164  }
165 
166  // Computations with ints, note that we only allow multiplicative operations
167  // with ints, and additive operations with other deltas.
168  TimeDelta operator*(int64_t a) const {
169  return TimeDelta(delta_ * a);
170  }
171  TimeDelta operator/(int64_t a) const {
172  return TimeDelta(delta_ / a);
173  }
174  TimeDelta& operator*=(int64_t a) {
175  delta_ *= a;
176  return *this;
177  }
178  TimeDelta& operator/=(int64_t a) {
179  delta_ /= a;
180  return *this;
181  }
182  int64_t operator/(const TimeDelta& other) const {
183  return delta_ / other.delta_;
184  }
185 
186  // Comparison operators.
187  constexpr bool operator==(const TimeDelta& other) const {
188  return delta_ == other.delta_;
189  }
190  constexpr bool operator!=(const TimeDelta& other) const {
191  return delta_ != other.delta_;
192  }
193  constexpr bool operator<(const TimeDelta& other) const {
194  return delta_ < other.delta_;
195  }
196  constexpr bool operator<=(const TimeDelta& other) const {
197  return delta_ <= other.delta_;
198  }
199  constexpr bool operator>(const TimeDelta& other) const {
200  return delta_ > other.delta_;
201  }
202  constexpr bool operator>=(const TimeDelta& other) const {
203  return delta_ >= other.delta_;
204  }
205 
206  private:
207  template<class TimeClass> friend class time_internal::TimeBase;
208  // Constructs a delta given the duration in microseconds. This is private
209  // to avoid confusion by callers with an integer constructor. Use
210  // FromSeconds, FromMilliseconds, etc. instead.
211  explicit constexpr TimeDelta(int64_t delta) : delta_(delta) {}
212 
213  // Delta in microseconds.
214  int64_t delta_;
215 };
216 
217 // static
218 constexpr TimeDelta TimeDelta::Max() {
219  return TimeDelta(std::numeric_limits<int64_t>::max());
220 }
221 
222 // static
223 constexpr TimeDelta TimeDelta::Min() {
224  return TimeDelta(std::numeric_limits<int64_t>::min());
225 }
226 
227 namespace time_internal {
228 
229 // TimeBase--------------------------------------------------------------------
230 
231 // Provides value storage and comparison/math operations common to all time
232 // classes. Each subclass provides for strong type-checking to ensure
233 // semantically meaningful comparison/math of time values from the same clock
234 // source or timeline.
235 template <class TimeClass>
236 class TimeBase : public TimeConstants {
237  public:
238 #if V8_OS_WIN
239  // To avoid overflow in QPC to Microseconds calculations, since we multiply
240  // by kMicrosecondsPerSecond, then the QPC value should not exceed
241  // (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply.
242  static constexpr int64_t kQPCOverflowThreshold = INT64_C(0x8637BD05AF7);
243 #endif
244 
245  // Returns true if this object has not been initialized.
246  //
247  // Warning: Be careful when writing code that performs math on time values,
248  // since it's possible to produce a valid "zero" result that should not be
249  // interpreted as a "null" value.
250  constexpr bool IsNull() const { return us_ == 0; }
251 
252  // Returns the maximum/minimum times, which should be greater/less than any
253  // reasonable time with which we might compare it.
254  static TimeClass Max() {
255  return TimeClass(std::numeric_limits<int64_t>::max());
256  }
257  static TimeClass Min() {
258  return TimeClass(std::numeric_limits<int64_t>::min());
259  }
260 
261  // Returns true if this object represents the maximum/minimum time.
262  constexpr bool IsMax() const {
263  return us_ == std::numeric_limits<int64_t>::max();
264  }
265  constexpr bool IsMin() const {
266  return us_ == std::numeric_limits<int64_t>::min();
267  }
268 
269  // For serializing only. Use FromInternalValue() to reconstitute. Please don't
270  // use this and do arithmetic on it, as it is more error prone than using the
271  // provided operators.
272  int64_t ToInternalValue() const { return us_; }
273 
274  TimeClass& operator=(TimeClass other) {
275  us_ = other.us_;
276  return *(static_cast<TimeClass*>(this));
277  }
278 
279  // Compute the difference between two times.
280  TimeDelta operator-(TimeClass other) const {
281  return TimeDelta::FromMicroseconds(us_ - other.us_);
282  }
283 
284  // Return a new time modified by some delta.
285  TimeClass operator+(TimeDelta delta) const {
286  return TimeClass(bits::SignedSaturatedAdd64(delta.delta_, us_));
287  }
288  TimeClass operator-(TimeDelta delta) const {
289  return TimeClass(-bits::SignedSaturatedSub64(delta.delta_, us_));
290  }
291 
292  // Modify by some time delta.
293  TimeClass& operator+=(TimeDelta delta) {
294  return static_cast<TimeClass&>(*this = (*this + delta));
295  }
296  TimeClass& operator-=(TimeDelta delta) {
297  return static_cast<TimeClass&>(*this = (*this - delta));
298  }
299 
300  // Comparison operators
301  bool operator==(TimeClass other) const {
302  return us_ == other.us_;
303  }
304  bool operator!=(TimeClass other) const {
305  return us_ != other.us_;
306  }
307  bool operator<(TimeClass other) const {
308  return us_ < other.us_;
309  }
310  bool operator<=(TimeClass other) const {
311  return us_ <= other.us_;
312  }
313  bool operator>(TimeClass other) const {
314  return us_ > other.us_;
315  }
316  bool operator>=(TimeClass other) const {
317  return us_ >= other.us_;
318  }
319 
320  // Converts an integer value representing TimeClass to a class. This is used
321  // when deserializing a |TimeClass| structure, using a value known to be
322  // compatible. It is not provided as a constructor because the integer type
323  // may be unclear from the perspective of a caller.
324  static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); }
325 
326  protected:
327  explicit constexpr TimeBase(int64_t us) : us_(us) {}
328 
329  // Time value in a microsecond timebase.
330  int64_t us_;
331 };
332 
333 } // namespace time_internal
334 
335 
336 // -----------------------------------------------------------------------------
337 // Time
338 //
339 // This class represents an absolute point in time, internally represented as
340 // microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
341 
342 class V8_BASE_EXPORT Time final : public time_internal::TimeBase<Time> {
343  public:
344  // Contains the nullptr time. Use Time::Now() to get the current time.
345  constexpr Time() : TimeBase(0) {}
346 
347  // Returns the current time. Watch out, the system might adjust its clock
348  // in which case time will actually go backwards. We don't guarantee that
349  // times are increasing, or that two calls to Now() won't be the same.
350  static Time Now();
351 
352  // Returns the current time. Same as Now() except that this function always
353  // uses system time so that there are no discrepancies between the returned
354  // time and system time even on virtual environments including our test bot.
355  // For timing sensitive unittests, this function should be used.
356  static Time NowFromSystemTime();
357 
358  // Returns the time for epoch in Unix-like system (Jan 1, 1970).
359  static Time UnixEpoch() { return Time(0); }
360 
361  // Converts to/from POSIX time specs.
362  static Time FromTimespec(struct timespec ts);
363  struct timespec ToTimespec() const;
364 
365  // Converts to/from POSIX time values.
366  static Time FromTimeval(struct timeval tv);
367  struct timeval ToTimeval() const;
368 
369  // Converts to/from Windows file times.
370  static Time FromFiletime(struct _FILETIME ft);
371  struct _FILETIME ToFiletime() const;
372 
373  // Converts to/from the Javascript convention for times, a number of
374  // milliseconds since the epoch:
375  static Time FromJsTime(double ms_since_epoch);
376  double ToJsTime() const;
377 
378  private:
379  friend class time_internal::TimeBase<Time>;
380  explicit constexpr Time(int64_t us) : TimeBase(us) {}
381 };
382 
383 V8_BASE_EXPORT std::ostream& operator<<(std::ostream&, const Time&);
384 
385 inline Time operator+(const TimeDelta& delta, const Time& time) {
386  return time + delta;
387 }
388 
389 
390 // -----------------------------------------------------------------------------
391 // TimeTicks
392 //
393 // This class represents an abstract time that is most of the time incrementing
394 // for use in measuring time durations. It is internally represented in
395 // microseconds. It can not be converted to a human-readable time, but is
396 // guaranteed not to decrease (if the user changes the computer clock,
397 // Time::Now() may actually decrease or jump). But note that TimeTicks may
398 // "stand still", for example if the computer suspended.
399 
400 class V8_BASE_EXPORT TimeTicks final
401  : public time_internal::TimeBase<TimeTicks> {
402  public:
403  constexpr TimeTicks() : TimeBase(0) {}
404 
405  // Platform-dependent tick count representing "right now." When
406  // IsHighResolution() returns false, the resolution of the clock could be as
407  // coarse as ~15.6ms. Otherwise, the resolution should be no worse than one
408  // microsecond.
409  // This method never returns a null TimeTicks.
410  static TimeTicks Now();
411 
412  // This is equivalent to Now() but DCHECKs that IsHighResolution(). Useful for
413  // test frameworks that rely on high resolution clocks (in practice all
414  // platforms but low-end Windows devices have high resolution clocks).
415  static TimeTicks HighResolutionNow();
416 
417  // Returns true if the high-resolution clock is working on this system.
418  static bool IsHighResolution();
419 
420  private:
421  friend class time_internal::TimeBase<TimeTicks>;
422 
423  // Please use Now() to create a new object. This is for internal use
424  // and testing. Ticks are in microseconds.
425  explicit constexpr TimeTicks(int64_t ticks) : TimeBase(ticks) {}
426 };
427 
428 inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
429  return ticks + delta;
430 }
431 
432 
433 // ThreadTicks ----------------------------------------------------------------
434 
435 // Represents a clock, specific to a particular thread, than runs only while the
436 // thread is running.
437 class V8_BASE_EXPORT ThreadTicks final
438  : public time_internal::TimeBase<ThreadTicks> {
439  public:
440  constexpr ThreadTicks() : TimeBase(0) {}
441 
442  // Returns true if ThreadTicks::Now() is supported on this system.
443  static bool IsSupported();
444 
445  // Waits until the initialization is completed. Needs to be guarded with a
446  // call to IsSupported().
447  static void WaitUntilInitialized() {
448 #if V8_OS_WIN
449  WaitUntilInitializedWin();
450 #endif
451  }
452 
453  // Returns thread-specific CPU-time on systems that support this feature.
454  // Needs to be guarded with a call to IsSupported(). Use this timer
455  // to (approximately) measure how much time the calling thread spent doing
456  // actual work vs. being de-scheduled. May return bogus results if the thread
457  // migrates to another CPU between two calls. Returns an empty ThreadTicks
458  // object until the initialization is completed. If a clock reading is
459  // absolutely needed, call WaitUntilInitialized() before this method.
460  static ThreadTicks Now();
461 
462 #if V8_OS_WIN
463  // Similar to Now() above except this returns thread-specific CPU time for an
464  // arbitrary thread. All comments for Now() method above apply apply to this
465  // method as well.
466  static ThreadTicks GetForThread(const HANDLE& thread_handle);
467 #endif
468 
469  private:
470  template <class TimeClass>
471  friend class time_internal::TimeBase;
472 
473  // Please use Now() or GetForThread() to create a new object. This is for
474  // internal use and testing. Ticks are in microseconds.
475  explicit constexpr ThreadTicks(int64_t ticks) : TimeBase(ticks) {}
476 
477 #if V8_OS_WIN
478  // Returns the frequency of the TSC in ticks per second, or 0 if it hasn't
479  // been measured yet. Needs to be guarded with a call to IsSupported().
480  static double TSCTicksPerSecond();
481  static bool IsSupportedWin();
482  static void WaitUntilInitializedWin();
483 #endif
484 };
485 
486 } // namespace base
487 } // namespace v8
488 
489 #endif // V8_BASE_PLATFORM_TIME_H_
Definition: libplatform.h:13