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

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
« src/base/bits.h ('K') | « src/base/bits.cc ('k') | no next file » | 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/bits.h"
12 #include "src/base/macros.h" 13 #include "src/base/macros.h"
14 #include "src/base/safe_math.h"
13 15
14 // Forward declarations. 16 // Forward declarations.
15 extern "C" { 17 extern "C" {
16 struct _FILETIME; 18 struct _FILETIME;
17 struct mach_timespec; 19 struct mach_timespec;
18 struct timespec; 20 struct timespec;
19 struct timeval; 21 struct timeval;
20 } 22 }
21 23
22 namespace v8 { 24 namespace v8 {
23 namespace base { 25 namespace base {
24 26
25 class Time; 27 class Time;
28 class TimeDelta;
26 class TimeTicks; 29 class TimeTicks;
27 30
31 namespace time_internal {
32 template<class TimeClass>
33 class TimeBase;
34 }
35
28 // ----------------------------------------------------------------------------- 36 // -----------------------------------------------------------------------------
29 // TimeDelta 37 // TimeDelta
30 // 38 //
31 // This class represents a duration of time, internally represented in 39 // This class represents a duration of time, internally represented in
32 // microseonds. 40 // microseonds.
33 41
34 class TimeDelta final { 42 class TimeDelta final {
35 public: 43 public:
36 TimeDelta() : delta_(0) {} 44 TimeDelta() : delta_(0) {}
37 45
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 return delta_ <= other.delta_; 144 return delta_ <= other.delta_;
137 } 145 }
138 bool operator>(const TimeDelta& other) const { 146 bool operator>(const TimeDelta& other) const {
139 return delta_ > other.delta_; 147 return delta_ > other.delta_;
140 } 148 }
141 bool operator>=(const TimeDelta& other) const { 149 bool operator>=(const TimeDelta& other) const {
142 return delta_ >= other.delta_; 150 return delta_ >= other.delta_;
143 } 151 }
144 152
145 private: 153 private:
154 template<class TimeClass> friend class time_internal::TimeBase;
146 // Constructs a delta given the duration in microseconds. This is private 155 // Constructs a delta given the duration in microseconds. This is private
147 // to avoid confusion by callers with an integer constructor. Use 156 // to avoid confusion by callers with an integer constructor. Use
148 // FromSeconds, FromMilliseconds, etc. instead. 157 // FromSeconds, FromMilliseconds, etc. instead.
149 explicit TimeDelta(int64_t delta) : delta_(delta) {} 158 explicit TimeDelta(int64_t delta) : delta_(delta) {}
150 159
151 // Delta in microseconds. 160 // Delta in microseconds.
152 int64_t delta_; 161 int64_t delta_;
153 }; 162 };
154 163
155 164
165 namespace 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.
173 template<class TimeClass>
174 class 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
156 // ----------------------------------------------------------------------------- 271 // -----------------------------------------------------------------------------
157 // Time 272 // Time
158 // 273 //
159 // This class represents an absolute point in time, internally represented as 274 // 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. 275 // microseconds (s/1,000,000) since 00:00:00 UTC, January 1, 1970.
161 276
162 class Time final { 277 class Time final : public time_internal::TimeBase<Time> {
163 public: 278 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. 279 // Contains the NULL time. Use Time::Now() to get the current time.
177 Time() : us_(0) {} 280 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 281
185 // Returns the current time. Watch out, the system might adjust its clock 282 // 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 283 // 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. 284 // times are increasing, or that two calls to Now() won't be the same.
188 static Time Now(); 285 static Time Now();
189 286
190 // Returns the current time. Same as Now() except that this function always 287 // 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 288 // 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. 289 // time and system time even on virtual environments including our test bot.
193 // For timing sensitive unittests, this function should be used. 290 // For timing sensitive unittests, this function should be used.
194 static Time NowFromSystemTime(); 291 static Time NowFromSystemTime();
195 292
196 // Returns the time for epoch in Unix-like system (Jan 1, 1970). 293 // Returns the time for epoch in Unix-like system (Jan 1, 1970).
197 static Time UnixEpoch() { return Time(0); } 294 static Time UnixEpoch() { return Time(0); }
198 295
199 // Returns the maximum time, which should be greater than any reasonable time 296 // Returns the maximum time, which should be greater than any reasonable time
200 // with which we might compare it. 297 // with which we might compare it.
201 static Time Max() { return Time(std::numeric_limits<int64_t>::max()); } 298 static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
202 299
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. 300 // Converts to/from POSIX time specs.
213 static Time FromTimespec(struct timespec ts); 301 static Time FromTimespec(struct timespec ts);
214 struct timespec ToTimespec() const; 302 struct timespec ToTimespec() const;
215 303
216 // Converts to/from POSIX time values. 304 // Converts to/from POSIX time values.
217 static Time FromTimeval(struct timeval tv); 305 static Time FromTimeval(struct timeval tv);
218 struct timeval ToTimeval() const; 306 struct timeval ToTimeval() const;
219 307
220 // Converts to/from Windows file times. 308 // Converts to/from Windows file times.
221 static Time FromFiletime(struct _FILETIME ft); 309 static Time FromFiletime(struct _FILETIME ft);
222 struct _FILETIME ToFiletime() const; 310 struct _FILETIME ToFiletime() const;
223 311
224 // Converts to/from the Javascript convention for times, a number of 312 // Converts to/from the Javascript convention for times, a number of
225 // milliseconds since the epoch: 313 // milliseconds since the epoch:
226 static Time FromJsTime(double ms_since_epoch); 314 static Time FromJsTime(double ms_since_epoch);
227 double ToJsTime() const; 315 double ToJsTime() const;
228 316
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: 317 private:
278 explicit Time(int64_t us) : us_(us) {} 318 friend class time_internal::TimeBase<Time>;
279 319 explicit Time(int64_t us) : TimeBase(us) {}
280 // Time in microseconds in UTC.
281 int64_t us_;
282 }; 320 };
283 321
284 std::ostream& operator<<(std::ostream&, const Time&); 322 std::ostream& operator<<(std::ostream&, const Time&);
285 323
286 inline Time operator+(const TimeDelta& delta, const Time& time) { 324 inline Time operator+(const TimeDelta& delta, const Time& time) {
287 return time + delta; 325 return time + delta;
288 } 326 }
289 327
290 328
291 // ----------------------------------------------------------------------------- 329 // -----------------------------------------------------------------------------
292 // TimeTicks 330 // TimeTicks
293 // 331 //
294 // This class represents an abstract time that is most of the time incrementing 332 // 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 333 // 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 334 // 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, 335 // guaranteed not to decrease (if the user changes the computer clock,
298 // Time::Now() may actually decrease or jump). But note that TimeTicks may 336 // Time::Now() may actually decrease or jump). But note that TimeTicks may
299 // "stand still", for example if the computer suspended. 337 // "stand still", for example if the computer suspended.
300 338
301 class TimeTicks final { 339 class TimeTicks final : public time_internal::TimeBase<TimeTicks> {
302 public: 340 public:
303 TimeTicks() : ticks_(0) {} 341 TimeTicks() : TimeBase(0) {}
304 342
305 // Platform-dependent tick count representing "right now." 343 // Platform-dependent tick count representing "right now."
306 // The resolution of this clock is ~1-15ms. Resolution varies depending 344 // The resolution of this clock is ~1-15ms. Resolution varies depending
307 // on hardware/operating system configuration. 345 // on hardware/operating system configuration.
308 // This method never returns a null TimeTicks. 346 // This method never returns a null TimeTicks.
309 static TimeTicks Now(); 347 static TimeTicks Now();
310 348
311 // Returns a platform-dependent high-resolution tick count. Implementation 349 // Returns a platform-dependent high-resolution tick count. Implementation
312 // is hardware dependent and may or may not return sub-millisecond 350 // is hardware dependent and may or may not return sub-millisecond
313 // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND 351 // resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
314 // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED. 352 // SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
315 // This method never returns a null TimeTicks. 353 // This method never returns a null TimeTicks.
316 static TimeTicks HighResolutionNow(); 354 static TimeTicks HighResolutionNow();
317 355
318 // Returns true if the high-resolution clock is working on this system. 356 // Returns true if the high-resolution clock is working on this system.
319 static bool IsHighResolutionClockWorking(); 357 static bool IsHighResolutionClockWorking();
320 358
321 // Returns true if this object has not been initialized. 359 private:
322 bool IsNull() const { return ticks_ == 0; } 360 friend class time_internal::TimeBase<TimeTicks>;
323 361
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 362 // Please use Now() to create a new object. This is for internal use
383 // and testing. Ticks is in microseconds. 363 // and testing. Ticks is in microseconds.
384 explicit TimeTicks(int64_t ticks) : ticks_(ticks) {} 364 explicit TimeTicks(int64_t ticks) : TimeBase(ticks) {}
385
386 // Tick count in microseconds.
387 int64_t ticks_;
388 }; 365 };
389 366
390 inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) { 367 inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
391 return ticks + delta; 368 return ticks + delta;
392 } 369 }
393 370
394 } // namespace base 371 } // namespace base
395 } // namespace v8 372 } // namespace v8
396 373
397 #endif // V8_BASE_PLATFORM_TIME_H_ 374 #endif // V8_BASE_PLATFORM_TIME_H_
OLDNEW
« src/base/bits.h ('K') | « src/base/bits.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698