Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: src/base/platform/time.h

Issue 1952843002: Create TimeBase for time related classes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/base/platform/time.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_BASE_PLATFORM_TIME_H_ 5 #ifndef V8_BASE_PLATFORM_TIME_H_
6 #define V8_BASE_PLATFORM_TIME_H_ 6 #define V8_BASE_PLATFORM_TIME_H_
7 7
8 #include <ctime> 8 #include <ctime>
9 #include <iosfwd> 9 #include <iosfwd>
10 #include <limits> 10 #include <limits>
11 11
12 #include "src/base/macros.h" 12 #include "src/base/macros.h"
13 #include "src/base/safe_math.h"
13 14
14 // Forward declarations. 15 // Forward declarations.
15 extern "C" { 16 extern "C" {
16 struct _FILETIME; 17 struct _FILETIME;
17 struct mach_timespec; 18 struct mach_timespec;
18 struct timespec; 19 struct timespec;
19 struct timeval; 20 struct timeval;
20 } 21 }
21 22
22 namespace v8 { 23 namespace v8 {
23 namespace base { 24 namespace base {
24 25
25 class Time; 26 class Time;
27 class TimeDelta;
26 class TimeTicks; 28 class TimeTicks;
27 29
30 namespace time_internal {
31
32 // Add or subtract |value| from a TimeDelta. The int64_t argument and return
33 // value are in terms of a microsecond timebase.
34 int64_t SaturatedAdd(TimeDelta delta, int64_t value);
Benedikt Meurer 2016/05/06 04:15:06 Can you move these to base/bits.{h,cc} instead as
lpy 2016/05/06 05:09:08 Done.
35 int64_t SaturatedSub(TimeDelta delta, int64_t value);
36
37 // Clamp |value| on overflow and underflow conditions. The int64_t argument and
38 // return value are in terms of a microsecond timebase.
39 int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value);
40
41 } // namespace time_internal
42
28 // ----------------------------------------------------------------------------- 43 // -----------------------------------------------------------------------------
29 // TimeDelta 44 // TimeDelta
30 // 45 //
31 // This class represents a duration of time, internally represented in 46 // This class represents a duration of time, internally represented in
32 // microseonds. 47 // microseonds.
33 48
34 class TimeDelta final { 49 class TimeDelta final {
35 public: 50 public:
36 TimeDelta() : delta_(0) {} 51 TimeDelta() : delta_(0) {}
37 52
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 return delta_ <= other.delta_; 151 return delta_ <= other.delta_;
137 } 152 }
138 bool operator>(const TimeDelta& other) const { 153 bool operator>(const TimeDelta& other) const {
139 return delta_ > other.delta_; 154 return delta_ > other.delta_;
140 } 155 }
141 bool operator>=(const TimeDelta& other) const { 156 bool operator>=(const TimeDelta& other) const {
142 return delta_ >= other.delta_; 157 return delta_ >= other.delta_;
143 } 158 }
144 159
145 private: 160 private:
161 friend int64_t time_internal::SaturatedAdd(TimeDelta delta, int64_t value);
162 friend int64_t time_internal::SaturatedSub(TimeDelta delta, int64_t value);
163
146 // Constructs a delta given the duration in microseconds. This is private 164 // Constructs a delta given the duration in microseconds. This is private
147 // to avoid confusion by callers with an integer constructor. Use 165 // to avoid confusion by callers with an integer constructor. Use
148 // FromSeconds, FromMilliseconds, etc. instead. 166 // FromSeconds, FromMilliseconds, etc. instead.
149 explicit TimeDelta(int64_t delta) : delta_(delta) {} 167 explicit TimeDelta(int64_t delta) : delta_(delta) {}
150 168
151 // Delta in microseconds. 169 // Delta in microseconds.
152 int64_t delta_; 170 int64_t delta_;
153 }; 171 };
154 172
155 173
174 namespace time_internal {
175
176 // TimeBase--------------------------------------------------------------------
177
178 // Provides value storage and comparison/math operations common to all time
179 // classes. Each subclass provides for strong type-checking to ensure
180 // semantically meaningful comparison/math of time values from the same clock
181 // source or timeline.
182 template<class TimeClass>
183 class TimeBase {
184 public:
185 static const int64_t kHoursPerDay = 24;
186 static const int64_t kMillisecondsPerSecond = 1000;
187 static const int64_t kMillisecondsPerDay =
188 kMillisecondsPerSecond * 60 * 60 * kHoursPerDay;
189 static const int64_t kMicrosecondsPerMillisecond = 1000;
190 static const int64_t kMicrosecondsPerSecond =
191 kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
192 static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
193 static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
194 static const int64_t kMicrosecondsPerDay =
195 kMicrosecondsPerHour * kHoursPerDay;
196 static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
197 static const int64_t kNanosecondsPerMicrosecond = 1000;
198 static const int64_t kNanosecondsPerSecond =
199 kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
200
201 // Returns true if this object has not been initialized.
202 //
203 // Warning: Be careful when writing code that performs math on time values,
204 // since it's possible to produce a valid "zero" result that should not be
205 // interpreted as a "null" value.
206 bool IsNull() const {
207 return us_ == 0;
208 }
209
210 // Returns true if this object represents the maximum time.
211 bool IsMax() const { return us_ == std::numeric_limits<int64_t>::max(); }
212
213 // For serializing only. Use FromInternalValue() to reconstitute. Please don't
214 // use this and do arithmetic on it, as it is more error prone than using the
215 // provided operators.
216 int64_t ToInternalValue() const { return us_; }
217
218 TimeClass& operator=(TimeClass other) {
219 us_ = other.us_;
220 return *(static_cast<TimeClass*>(this));
221 }
222
223 // Compute the difference between two times.
224 TimeDelta operator-(TimeClass other) const {
225 return TimeDelta::FromMicroseconds(us_ - other.us_);
226 }
227
228 // Return a new time modified by some delta.
229 TimeClass operator+(TimeDelta delta) const {
230 return TimeClass(time_internal::SaturatedAdd(delta, us_));
231 }
232 TimeClass operator-(TimeDelta delta) const {
233 return TimeClass(-time_internal::SaturatedSub(delta, us_));
234 }
235
236 // Modify by some time delta.
237 TimeClass& operator+=(TimeDelta delta) {
238 return static_cast<TimeClass&>(*this = (*this + delta));
239 }
240 TimeClass& operator-=(TimeDelta delta) {
241 return static_cast<TimeClass&>(*this = (*this - delta));
242 }
243
244 // Comparison operators
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 bool operator<=(TimeClass other) const {
255 return us_ <= other.us_;
256 }
257 bool operator>(TimeClass other) const {
258 return us_ > other.us_;
259 }
260 bool operator>=(TimeClass other) const {
261 return us_ >= other.us_;
262 }
263
264 // Converts an integer value representing TimeClass to a class. This is used
265 // when deserializing a |TimeClass| structure, using a value known to be
266 // compatible. It is not provided as a constructor because the integer type
267 // may be unclear from the perspective of a caller.
268 static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); }
269
270 protected:
271 explicit TimeBase(int64_t us) : us_(us) {}
272
273 // Time value in a microsecond timebase.
274 int64_t us_;
275 };
276
277 } // namespace time_internal
278
279
156 // ----------------------------------------------------------------------------- 280 // -----------------------------------------------------------------------------
157 // Time 281 // Time
158 // 282 //
159 // This class represents an absolute point in time, internally represented as 283 // This class represents an absolute point in time, internally represented as
160 // microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970. 284 // microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
161 285
162 class Time final { 286 class Time final : public time_internal::TimeBase<Time> {
163 public: 287 public:
164 static const int64_t kMillisecondsPerSecond = 1000;
165 static const int64_t kMicrosecondsPerMillisecond = 1000;
166 static const int64_t kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
167 kMillisecondsPerSecond;
168 static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
169 static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
170 static const int64_t kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
171 static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
172 static const int64_t kNanosecondsPerMicrosecond = 1000;
173 static const int64_t kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
174 kMicrosecondsPerSecond;
175
176 // Contains the NULL time. Use Time::Now() to get the current time. 288 // Contains the NULL time. Use Time::Now() to get the current time.
177 Time() : us_(0) {} 289 Time() : TimeBase(0) {}
178
179 // Returns true if the time object has not been initialized.
180 bool IsNull() const { return us_ == 0; }
181
182 // Returns true if the time object is the maximum time.
183 bool IsMax() const { return us_ == std::numeric_limits<int64_t>::max(); }
184 290
185 // Returns the current time. Watch out, the system might adjust its clock 291 // Returns the current time. Watch out, the system might adjust its clock
186 // in which case time will actually go backwards. We don't guarantee that 292 // in which case time will actually go backwards. We don't guarantee that
187 // times are increasing, or that two calls to Now() won't be the same. 293 // times are increasing, or that two calls to Now() won't be the same.
188 static Time Now(); 294 static Time Now();
189 295
190 // Returns the current time. Same as Now() except that this function always 296 // Returns the current time. Same as Now() except that this function always
191 // uses system time so that there are no discrepancies between the returned 297 // uses system time so that there are no discrepancies between the returned
192 // time and system time even on virtual environments including our test bot. 298 // time and system time even on virtual environments including our test bot.
193 // For timing sensitive unittests, this function should be used. 299 // For timing sensitive unittests, this function should be used.
194 static Time NowFromSystemTime(); 300 static Time NowFromSystemTime();
195 301
196 // Returns the time for epoch in Unix-like system (Jan 1, 1970). 302 // Returns the time for epoch in Unix-like system (Jan 1, 1970).
197 static Time UnixEpoch() { return Time(0); } 303 static Time UnixEpoch() { return Time(0); }
198 304
199 // Returns the maximum time, which should be greater than any reasonable time 305 // Returns the maximum time, which should be greater than any reasonable time
200 // with which we might compare it. 306 // with which we might compare it.
201 static Time Max() { return Time(std::numeric_limits<int64_t>::max()); } 307 static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
202 308
203 // Converts to/from internal values. The meaning of the "internal value" is
204 // completely up to the implementation, so it should be treated as opaque.
205 static Time FromInternalValue(int64_t value) {
206 return Time(value);
207 }
208 int64_t ToInternalValue() const {
209 return us_;
210 }
211
212 // Converts to/from POSIX time specs. 309 // Converts to/from POSIX time specs.
213 static Time FromTimespec(struct timespec ts); 310 static Time FromTimespec(struct timespec ts);
214 struct timespec ToTimespec() const; 311 struct timespec ToTimespec() const;
215 312
216 // Converts to/from POSIX time values. 313 // Converts to/from POSIX time values.
217 static Time FromTimeval(struct timeval tv); 314 static Time FromTimeval(struct timeval tv);
218 struct timeval ToTimeval() const; 315 struct timeval ToTimeval() const;
219 316
220 // Converts to/from Windows file times. 317 // Converts to/from Windows file times.
221 static Time FromFiletime(struct _FILETIME ft); 318 static Time FromFiletime(struct _FILETIME ft);
222 struct _FILETIME ToFiletime() const; 319 struct _FILETIME ToFiletime() const;
223 320
224 // Converts to/from the Javascript convention for times, a number of 321 // Converts to/from the Javascript convention for times, a number of
225 // milliseconds since the epoch: 322 // milliseconds since the epoch:
226 static Time FromJsTime(double ms_since_epoch); 323 static Time FromJsTime(double ms_since_epoch);
227 double ToJsTime() const; 324 double ToJsTime() const;
228 325
229 Time& operator=(const Time& other) {
230 us_ = other.us_;
231 return *this;
232 }
233
234 // Compute the difference between two times.
235 TimeDelta operator-(const Time& other) const {
236 return TimeDelta::FromMicroseconds(us_ - other.us_);
237 }
238
239 // Modify by some time delta.
240 Time& operator+=(const TimeDelta& delta) {
241 us_ += delta.InMicroseconds();
242 return *this;
243 }
244 Time& operator-=(const TimeDelta& delta) {
245 us_ -= delta.InMicroseconds();
246 return *this;
247 }
248
249 // Return a new time modified by some delta.
250 Time operator+(const TimeDelta& delta) const {
251 return Time(us_ + delta.InMicroseconds());
252 }
253 Time operator-(const TimeDelta& delta) const {
254 return Time(us_ - delta.InMicroseconds());
255 }
256
257 // Comparison operators
258 bool operator==(const Time& other) const {
259 return us_ == other.us_;
260 }
261 bool operator!=(const Time& other) const {
262 return us_ != other.us_;
263 }
264 bool operator<(const Time& other) const {
265 return us_ < other.us_;
266 }
267 bool operator<=(const Time& other) const {
268 return us_ <= other.us_;
269 }
270 bool operator>(const Time& other) const {
271 return us_ > other.us_;
272 }
273 bool operator>=(const Time& other) const {
274 return us_ >= other.us_;
275 }
276
277 private: 326 private:
278 explicit Time(int64_t us) : us_(us) {} 327 friend class time_internal::TimeBase<Time>;
279 328 explicit Time(int64_t us) : TimeBase(us) {}
280 // Time in microseconds in UTC.
281 int64_t us_;
282 }; 329 };
283 330
284 std::ostream& operator<<(std::ostream&, const Time&); 331 std::ostream& operator<<(std::ostream&, const Time&);
285 332
286 inline Time operator+(const TimeDelta& delta, const Time& time) { 333 inline Time operator+(const TimeDelta& delta, const Time& time) {
287 return time + delta; 334 return time + delta;
288 } 335 }
289 336
290 337
291 // ----------------------------------------------------------------------------- 338 // -----------------------------------------------------------------------------
292 // TimeTicks 339 // TimeTicks
293 // 340 //
294 // This class represents an abstract time that is most of the time incrementing 341 // This class represents an abstract time that is most of the time incrementing
295 // for use in measuring time durations. It is internally represented in 342 // for use in measuring time durations. It is internally represented in
296 // microseconds. It can not be converted to a human-readable time, but is 343 // microseconds. It can not be converted to a human-readable time, but is
297 // guaranteed not to decrease (if the user changes the computer clock, 344 // guaranteed not to decrease (if the user changes the computer clock,
298 // Time::Now() may actually decrease or jump). But note that TimeTicks may 345 // Time::Now() may actually decrease or jump). But note that TimeTicks may
299 // "stand still", for example if the computer suspended. 346 // "stand still", for example if the computer suspended.
300 347
301 class TimeTicks final { 348 class TimeTicks final : public time_internal::TimeBase<TimeTicks> {
302 public: 349 public:
303 TimeTicks() : ticks_(0) {} 350 TimeTicks() : TimeBase(0) {}
304 351
305 // Platform-dependent tick count representing "right now." 352 // Platform-dependent tick count representing "right now."
306 // The resolution of this clock is ~1-15ms. Resolution varies depending 353 // The resolution of this clock is ~1-15ms. Resolution varies depending
307 // on hardware/operating system configuration. 354 // on hardware/operating system configuration.
308 // This method never returns a null TimeTicks. 355 // This method never returns a null TimeTicks.
309 static TimeTicks Now(); 356 static TimeTicks Now();
310 357
311 // Returns a platform-dependent high-resolution tick count. Implementation 358 // Returns a platform-dependent high-resolution tick count. Implementation
312 // is hardware dependent and may or may not return sub-millisecond 359 // is hardware dependent and may or may not return sub-millisecond
313 // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND 360 // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
314 // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED. 361 // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
315 // This method never returns a null TimeTicks. 362 // This method never returns a null TimeTicks.
316 static TimeTicks HighResolutionNow(); 363 static TimeTicks HighResolutionNow();
317 364
318 // Returns true if the high-resolution clock is working on this system. 365 // Returns true if the high-resolution clock is working on this system.
319 static bool IsHighResolutionClockWorking(); 366 static bool IsHighResolutionClockWorking();
320 367
321 // Returns true if this object has not been initialized. 368 private:
322 bool IsNull() const { return ticks_ == 0; } 369 friend class time_internal::TimeBase<TimeTicks>;
323 370
324 // Converts to/from internal values. The meaning of the "internal value" is
325 // completely up to the implementation, so it should be treated as opaque.
326 static TimeTicks FromInternalValue(int64_t value) {
327 return TimeTicks(value);
328 }
329 int64_t ToInternalValue() const {
330 return ticks_;
331 }
332
333 TimeTicks& operator=(const TimeTicks other) {
334 ticks_ = other.ticks_;
335 return *this;
336 }
337
338 // Compute the difference between two times.
339 TimeDelta operator-(const TimeTicks other) const {
340 return TimeDelta::FromMicroseconds(ticks_ - other.ticks_);
341 }
342
343 // Modify by some time delta.
344 TimeTicks& operator+=(const TimeDelta& delta) {
345 ticks_ += delta.InMicroseconds();
346 return *this;
347 }
348 TimeTicks& operator-=(const TimeDelta& delta) {
349 ticks_ -= delta.InMicroseconds();
350 return *this;
351 }
352
353 // Return a new TimeTicks modified by some delta.
354 TimeTicks operator+(const TimeDelta& delta) const {
355 return TimeTicks(ticks_ + delta.InMicroseconds());
356 }
357 TimeTicks operator-(const TimeDelta& delta) const {
358 return TimeTicks(ticks_ - delta.InMicroseconds());
359 }
360
361 // Comparison operators
362 bool operator==(const TimeTicks& other) const {
363 return ticks_ == other.ticks_;
364 }
365 bool operator!=(const TimeTicks& other) const {
366 return ticks_ != other.ticks_;
367 }
368 bool operator<(const TimeTicks& other) const {
369 return ticks_ < other.ticks_;
370 }
371 bool operator<=(const TimeTicks& other) const {
372 return ticks_ <= other.ticks_;
373 }
374 bool operator>(const TimeTicks& other) const {
375 return ticks_ > other.ticks_;
376 }
377 bool operator>=(const TimeTicks& other) const {
378 return ticks_ >= other.ticks_;
379 }
380
381 private:
382 // Please use Now() to create a new object. This is for internal use 371 // Please use Now() to create a new object. This is for internal use
383 // and testing. Ticks is in microseconds. 372 // and testing. Ticks is in microseconds.
384 explicit TimeTicks(int64_t ticks) : ticks_(ticks) {} 373 explicit TimeTicks(int64_t ticks) : TimeBase(ticks) {}
385
386 // Tick count in microseconds.
387 int64_t ticks_;
388 }; 374 };
389 375
390 inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) { 376 inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
391 return ticks + delta; 377 return ticks + delta;
392 } 378 }
393 379
394 } // namespace base 380 } // namespace base
395 } // namespace v8 381 } // namespace v8
396 382
397 #endif // V8_BASE_PLATFORM_TIME_H_ 383 #endif // V8_BASE_PLATFORM_TIME_H_
OLDNEW
« no previous file with comments | « no previous file | src/base/platform/time.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698