OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium 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 // Time represents an absolute point in coordinated universal time (UTC), | 5 // Time represents an absolute point in coordinated universal time (UTC), |
6 // internally represented as microseconds (s/1,000,000) since the Windows epoch | 6 // internally represented as microseconds (s/1,000,000) since the Windows epoch |
7 // (1601-01-01 00:00:00 UTC) (See http://crbug.com/14734). System-dependent | 7 // (1601-01-01 00:00:00 UTC) (See http://crbug.com/14734). System-dependent |
8 // clock interface routines are defined in time_PLATFORM.cc. | 8 // clock interface routines are defined in time_PLATFORM.cc. |
9 // | 9 // |
10 // TimeDelta represents a duration of time, internally represented in | 10 // TimeDelta represents a duration of time, internally represented in |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 #ifndef BASE_TIME_TIME_H_ | 27 #ifndef BASE_TIME_TIME_H_ |
28 #define BASE_TIME_TIME_H_ | 28 #define BASE_TIME_TIME_H_ |
29 | 29 |
30 #include <time.h> | 30 #include <time.h> |
31 | 31 |
32 #include <iosfwd> | 32 #include <iosfwd> |
33 | 33 |
34 #include "base/base_export.h" | 34 #include "base/base_export.h" |
35 #include "base/basictypes.h" | 35 #include "base/basictypes.h" |
| 36 #include "base/numerics/safe_math.h" |
36 #include "build/build_config.h" | 37 #include "build/build_config.h" |
37 | 38 |
38 #if defined(OS_MACOSX) | 39 #if defined(OS_MACOSX) |
39 #include <CoreFoundation/CoreFoundation.h> | 40 #include <CoreFoundation/CoreFoundation.h> |
40 // Avoid Mac system header macro leak. | 41 // Avoid Mac system header macro leak. |
41 #undef TYPE_BOOL | 42 #undef TYPE_BOOL |
42 #endif | 43 #endif |
43 | 44 |
44 #if defined(OS_POSIX) | 45 #if defined(OS_POSIX) |
45 #include <unistd.h> | 46 #include <unistd.h> |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 int64 InMillisecondsRoundedUp() const; | 134 int64 InMillisecondsRoundedUp() const; |
134 int64 InMicroseconds() const; | 135 int64 InMicroseconds() const; |
135 | 136 |
136 TimeDelta& operator=(TimeDelta other) { | 137 TimeDelta& operator=(TimeDelta other) { |
137 delta_ = other.delta_; | 138 delta_ = other.delta_; |
138 return *this; | 139 return *this; |
139 } | 140 } |
140 | 141 |
141 // Computations with other deltas. | 142 // Computations with other deltas. |
142 TimeDelta operator+(TimeDelta other) const { | 143 TimeDelta operator+(TimeDelta other) const { |
143 return TimeDelta(delta_ + other.delta_); | 144 return TimeDelta(SaturatedAdd(other.delta_)); |
144 } | 145 } |
145 TimeDelta operator-(TimeDelta other) const { | 146 TimeDelta operator-(TimeDelta other) const { |
146 return TimeDelta(delta_ - other.delta_); | 147 return TimeDelta(SaturatedSub(other.delta_)); |
147 } | 148 } |
148 | 149 |
149 TimeDelta& operator+=(TimeDelta other) { | 150 TimeDelta& operator+=(TimeDelta other) { |
150 delta_ += other.delta_; | 151 delta_ = SaturatedAdd(other.delta_); |
151 return *this; | 152 return *this; |
152 } | 153 } |
153 TimeDelta& operator-=(TimeDelta other) { | 154 TimeDelta& operator-=(TimeDelta other) { |
154 delta_ -= other.delta_; | 155 delta_ = SaturatedSub(other.delta_); |
155 return *this; | 156 return *this; |
156 } | 157 } |
157 TimeDelta operator-() const { | 158 TimeDelta operator-() const { |
158 return TimeDelta(-delta_); | 159 return TimeDelta(-delta_); |
159 } | 160 } |
160 | 161 |
161 // Computations with numeric types. | 162 // Computations with numeric types. |
162 template<typename T> | 163 template<typename T> |
163 TimeDelta operator*(T a) const { | 164 TimeDelta operator*(T a) const { |
164 return TimeDelta(delta_ * a); | 165 CheckedNumeric<int64> rv(delta_); |
| 166 rv *= a; |
| 167 return TimeDelta(FromCheckedNumeric(rv)); |
165 } | 168 } |
166 template<typename T> | 169 template<typename T> |
167 TimeDelta operator/(T a) const { | 170 TimeDelta operator/(T a) const { |
168 return TimeDelta(delta_ / a); | 171 CheckedNumeric<int64> rv(delta_); |
| 172 rv /= a; |
| 173 return TimeDelta(FromCheckedNumeric(rv)); |
169 } | 174 } |
170 template<typename T> | 175 template<typename T> |
171 TimeDelta& operator*=(T a) { | 176 TimeDelta& operator*=(T a) { |
172 delta_ *= a; | 177 CheckedNumeric<int64> rv(delta_); |
| 178 rv *= a; |
| 179 delta_ = FromCheckedNumeric(rv); |
173 return *this; | 180 return *this; |
174 } | 181 } |
175 template<typename T> | 182 template<typename T> |
176 TimeDelta& operator/=(T a) { | 183 TimeDelta& operator/=(T a) { |
177 delta_ /= a; | 184 CheckedNumeric<int64> rv(delta_); |
| 185 rv /= a; |
| 186 delta_ = FromCheckedNumeric(rv); |
178 return *this; | 187 return *this; |
179 } | 188 } |
180 | 189 |
181 int64 operator/(TimeDelta a) const { | 190 int64 operator/(TimeDelta a) const { |
182 return delta_ / a.delta_; | 191 return delta_ / a.delta_; |
183 } | 192 } |
184 | 193 |
185 // Defined below because it depends on the definition of the other classes. | 194 // Defined below because it depends on the definition of the other classes. |
186 Time operator+(Time t) const; | 195 Time operator+(Time t) const; |
187 TimeTicks operator+(TimeTicks t) const; | 196 TimeTicks operator+(TimeTicks t) const; |
(...skipping 21 matching lines...) Expand all Loading... |
209 private: | 218 private: |
210 friend class Time; | 219 friend class Time; |
211 friend class TimeTicks; | 220 friend class TimeTicks; |
212 | 221 |
213 // Constructs a delta given the duration in microseconds. This is private | 222 // Constructs a delta given the duration in microseconds. This is private |
214 // to avoid confusion by callers with an integer constructor. Use | 223 // to avoid confusion by callers with an integer constructor. Use |
215 // FromSeconds, FromMilliseconds, etc. instead. | 224 // FromSeconds, FromMilliseconds, etc. instead. |
216 explicit TimeDelta(int64 delta_us) : delta_(delta_us) { | 225 explicit TimeDelta(int64 delta_us) : delta_(delta_us) { |
217 } | 226 } |
218 | 227 |
| 228 // Add or subtract |value| from this delta. |
| 229 int64 SaturatedAdd(int64 value) const; |
| 230 int64 SaturatedSub(int64 value) const; |
| 231 |
| 232 // Clamp |value| on overflow and underflow conditions. |
| 233 static int64 FromCheckedNumeric(const CheckedNumeric<int64> value); |
| 234 |
219 // Delta in microseconds. | 235 // Delta in microseconds. |
220 int64 delta_; | 236 int64 delta_; |
221 }; | 237 }; |
222 | 238 |
223 template<typename T> | 239 template<typename T> |
224 inline TimeDelta operator*(T a, TimeDelta td) { | 240 inline TimeDelta operator*(T a, TimeDelta td) { |
225 return td * a; | 241 return td * a; |
226 } | 242 } |
227 | 243 |
228 // For logging use only. | 244 // For logging use only. |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 return *this; | 460 return *this; |
445 } | 461 } |
446 | 462 |
447 // Compute the difference between two times. | 463 // Compute the difference between two times. |
448 TimeDelta operator-(Time other) const { | 464 TimeDelta operator-(Time other) const { |
449 return TimeDelta(us_ - other.us_); | 465 return TimeDelta(us_ - other.us_); |
450 } | 466 } |
451 | 467 |
452 // Modify by some time delta. | 468 // Modify by some time delta. |
453 Time& operator+=(TimeDelta delta) { | 469 Time& operator+=(TimeDelta delta) { |
454 us_ += delta.delta_; | 470 us_ = delta.SaturatedAdd(us_); |
455 return *this; | 471 return *this; |
456 } | 472 } |
457 Time& operator-=(TimeDelta delta) { | 473 Time& operator-=(TimeDelta delta) { |
458 us_ -= delta.delta_; | 474 us_ = -delta.SaturatedSub(us_); |
459 return *this; | 475 return *this; |
460 } | 476 } |
461 | 477 |
462 // Return a new time modified by some delta. | 478 // Return a new time modified by some delta. |
463 Time operator+(TimeDelta delta) const { | 479 Time operator+(TimeDelta delta) const { |
464 return Time(us_ + delta.delta_); | 480 return Time(delta.SaturatedAdd(us_)); |
465 } | 481 } |
466 Time operator-(TimeDelta delta) const { | 482 Time operator-(TimeDelta delta) const { |
467 return Time(us_ - delta.delta_); | 483 return Time(-delta.SaturatedSub(us_)); |
468 } | 484 } |
469 | 485 |
470 // Comparison operators | 486 // Comparison operators |
471 bool operator==(Time other) const { | 487 bool operator==(Time other) const { |
472 return us_ == other.us_; | 488 return us_ == other.us_; |
473 } | 489 } |
474 bool operator!=(Time other) const { | 490 bool operator!=(Time other) const { |
475 return us_ != other.us_; | 491 return us_ != other.us_; |
476 } | 492 } |
477 bool operator<(Time other) const { | 493 bool operator<(Time other) const { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 | 592 |
577 // static | 593 // static |
578 inline TimeDelta TimeDelta::FromMicroseconds(int64 us) { | 594 inline TimeDelta TimeDelta::FromMicroseconds(int64 us) { |
579 // Preserve max to prevent overflow. | 595 // Preserve max to prevent overflow. |
580 if (us == std::numeric_limits<int64>::max()) | 596 if (us == std::numeric_limits<int64>::max()) |
581 return Max(); | 597 return Max(); |
582 return TimeDelta(us); | 598 return TimeDelta(us); |
583 } | 599 } |
584 | 600 |
585 inline Time TimeDelta::operator+(Time t) const { | 601 inline Time TimeDelta::operator+(Time t) const { |
586 return Time(t.us_ + delta_); | 602 return Time(SaturatedAdd(t.us_)); |
587 } | 603 } |
588 | 604 |
589 // For logging use only. | 605 // For logging use only. |
590 BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time); | 606 BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time); |
591 | 607 |
592 // TimeTicks ------------------------------------------------------------------ | 608 // TimeTicks ------------------------------------------------------------------ |
593 | 609 |
594 class BASE_EXPORT TimeTicks { | 610 class BASE_EXPORT TimeTicks { |
595 public: | 611 public: |
596 // We define this even without OS_CHROMEOS for seccomp sandbox testing. | 612 // We define this even without OS_CHROMEOS for seccomp sandbox testing. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 // value has the same origin as Now(). Do NOT attempt to use this if | 674 // value has the same origin as Now(). Do NOT attempt to use this if |
659 // IsHighResolution() returns false. | 675 // IsHighResolution() returns false. |
660 static TimeTicks FromQPCValue(LONGLONG qpc_value); | 676 static TimeTicks FromQPCValue(LONGLONG qpc_value); |
661 #endif | 677 #endif |
662 | 678 |
663 // Returns true if this object has not been initialized. | 679 // Returns true if this object has not been initialized. |
664 bool is_null() const { | 680 bool is_null() const { |
665 return ticks_ == 0; | 681 return ticks_ == 0; |
666 } | 682 } |
667 | 683 |
| 684 // Returns true if the time delta is the maximum delta. |
| 685 bool is_max() const { |
| 686 return ticks_ == std::numeric_limits<int64>::max(); |
| 687 } |
| 688 |
668 // Converts an integer value representing TimeTicks to a class. This is used | 689 // Converts an integer value representing TimeTicks to a class. This is used |
669 // when deserializing a |TimeTicks| structure, using a value known to be | 690 // when deserializing a |TimeTicks| structure, using a value known to be |
670 // compatible. It is not provided as a constructor because the integer type | 691 // compatible. It is not provided as a constructor because the integer type |
671 // may be unclear from the perspective of a caller. | 692 // may be unclear from the perspective of a caller. |
672 static TimeTicks FromInternalValue(int64 ticks) { | 693 static TimeTicks FromInternalValue(int64 ticks) { |
673 return TimeTicks(ticks); | 694 return TimeTicks(ticks); |
674 } | 695 } |
675 | 696 |
676 // Get the TimeTick value at the time of the UnixEpoch. This is useful when | 697 // Get the TimeTick value at the time of the UnixEpoch. This is useful when |
677 // you need to relate the value of TimeTicks to a real time and date. | 698 // you need to relate the value of TimeTicks to a real time and date. |
(...skipping 20 matching lines...) Expand all Loading... |
698 return *this; | 719 return *this; |
699 } | 720 } |
700 | 721 |
701 // Compute the difference between two times. | 722 // Compute the difference between two times. |
702 TimeDelta operator-(TimeTicks other) const { | 723 TimeDelta operator-(TimeTicks other) const { |
703 return TimeDelta(ticks_ - other.ticks_); | 724 return TimeDelta(ticks_ - other.ticks_); |
704 } | 725 } |
705 | 726 |
706 // Modify by some time delta. | 727 // Modify by some time delta. |
707 TimeTicks& operator+=(TimeDelta delta) { | 728 TimeTicks& operator+=(TimeDelta delta) { |
708 ticks_ += delta.delta_; | 729 ticks_ = delta.SaturatedAdd(ticks_); |
709 return *this; | 730 return *this; |
710 } | 731 } |
711 TimeTicks& operator-=(TimeDelta delta) { | 732 TimeTicks& operator-=(TimeDelta delta) { |
712 ticks_ -= delta.delta_; | 733 ticks_ = -delta.SaturatedSub(ticks_); |
713 return *this; | 734 return *this; |
714 } | 735 } |
715 | 736 |
716 // Return a new TimeTicks modified by some delta. | 737 // Return a new TimeTicks modified by some delta. |
717 TimeTicks operator+(TimeDelta delta) const { | 738 TimeTicks operator+(TimeDelta delta) const { |
718 return TimeTicks(ticks_ + delta.delta_); | 739 return TimeTicks(delta.SaturatedAdd(ticks_)); |
719 } | 740 } |
720 TimeTicks operator-(TimeDelta delta) const { | 741 TimeTicks operator-(TimeDelta delta) const { |
721 return TimeTicks(ticks_ - delta.delta_); | 742 return TimeTicks(-delta.SaturatedSub(ticks_)); |
722 } | 743 } |
723 | 744 |
724 // Comparison operators | 745 // Comparison operators |
725 bool operator==(TimeTicks other) const { | 746 bool operator==(TimeTicks other) const { |
726 return ticks_ == other.ticks_; | 747 return ticks_ == other.ticks_; |
727 } | 748 } |
728 bool operator!=(TimeTicks other) const { | 749 bool operator!=(TimeTicks other) const { |
729 return ticks_ != other.ticks_; | 750 return ticks_ != other.ticks_; |
730 } | 751 } |
731 bool operator<(TimeTicks other) const { | 752 bool operator<(TimeTicks other) const { |
(...skipping 20 matching lines...) Expand all Loading... |
752 // Tick count in microseconds. | 773 // Tick count in microseconds. |
753 int64 ticks_; | 774 int64 ticks_; |
754 | 775 |
755 #if defined(OS_WIN) | 776 #if defined(OS_WIN) |
756 typedef DWORD (*TickFunctionType)(void); | 777 typedef DWORD (*TickFunctionType)(void); |
757 static TickFunctionType SetMockTickFunction(TickFunctionType ticker); | 778 static TickFunctionType SetMockTickFunction(TickFunctionType ticker); |
758 #endif | 779 #endif |
759 }; | 780 }; |
760 | 781 |
761 inline TimeTicks TimeDelta::operator+(TimeTicks t) const { | 782 inline TimeTicks TimeDelta::operator+(TimeTicks t) const { |
762 return TimeTicks(t.ticks_ + delta_); | 783 return TimeTicks(SaturatedAdd(t.ticks_)); |
763 } | 784 } |
764 | 785 |
765 // For logging use only. | 786 // For logging use only. |
766 BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks); | 787 BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks); |
767 | 788 |
768 } // namespace base | 789 } // namespace base |
769 | 790 |
770 #endif // BASE_TIME_TIME_H_ | 791 #endif // BASE_TIME_TIME_H_ |
OLD | NEW |