Bug 564076: Small parser cleanup changes. (r=mrbkap)
[mozilla-central.git] / xpcom / ds / TimeStamp.h
blob7e90263dcd2184383f78e81a7965c26f969f6148
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is Mozilla code.
18 * The Initial Developer of the Original Code is the Mozilla Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2009
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Robert O'Callahan <robert@ocallahan.org>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef mozilla_TimeStamp_h
40 #define mozilla_TimeStamp_h
42 #include "prinrval.h"
43 #include "nsDebug.h"
45 namespace mozilla {
47 class TimeStamp;
49 /**
50 * Instances of this class represent the length of an interval of time.
51 * Negative durations are allowed, meaning the end is before the start.
53 * Internally the duration is stored as a PRInt64 in units of
54 * PR_TicksPerSecond() when building with NSPR interval timers, or a
55 * system-dependent unit when building with system clocks. The
56 * system-dependent unit must be constant, otherwise the semantics of
57 * this class would be broken.
59 class NS_COM TimeDuration
61 public:
62 // The default duration is 0.
63 TimeDuration() : mValue(0) {}
64 // Allow construction using '0' as the initial value, for readability,
65 // but no other numbers (so we don't have any implicit unit conversions).
66 struct _SomethingVeryRandomHere;
67 TimeDuration(_SomethingVeryRandomHere* aZero) : mValue(0) {
68 NS_ASSERTION(!aZero, "Who's playing funny games here?");
70 // Default copy-constructor and assignment are OK
72 double ToSeconds() const;
73 // Return a duration value that includes digits of time we think to
74 // be significant. This method should be used when displaying a
75 // time to humans.
76 double ToSecondsSigDigits() const;
78 static TimeDuration FromSeconds(PRInt32 aSeconds);
79 static TimeDuration FromMilliseconds(PRInt32 aMilliseconds);
81 TimeDuration operator+(const TimeDuration& aOther) const {
82 return TimeDuration::FromTicks(mValue + aOther.mValue);
84 TimeDuration operator-(const TimeDuration& aOther) const {
85 return TimeDuration::FromTicks(mValue - aOther.mValue);
87 TimeDuration& operator+=(const TimeDuration& aOther) {
88 mValue += aOther.mValue;
89 return *this;
91 TimeDuration& operator-=(const TimeDuration& aOther) {
92 mValue -= aOther.mValue;
93 return *this;
96 PRBool operator<(const TimeDuration& aOther) const {
97 return mValue < aOther.mValue;
99 PRBool operator<=(const TimeDuration& aOther) const {
100 return mValue <= aOther.mValue;
102 PRBool operator>=(const TimeDuration& aOther) const {
103 return mValue >= aOther.mValue;
105 PRBool operator>(const TimeDuration& aOther) const {
106 return mValue > aOther.mValue;
109 // Return a best guess at the system's current timing resolution,
110 // which might be variable. TimeDurations below this order of
111 // magnitude are meaningless, and those at the same order of
112 // magnitude or just above are suspect.
113 static TimeDuration Resolution();
115 // We could define additional operators here:
116 // -- convert to/from other time units
117 // -- scale duration by a float
118 // but let's do that on demand.
119 // Comparing durations for equality will only lead to bugs on
120 // platforms with high-resolution timers.
122 private:
123 friend class TimeStamp;
125 static TimeDuration FromTicks(PRInt64 aTicks) {
126 TimeDuration t;
127 t.mValue = aTicks;
128 return t;
131 // Duration in PRIntervalTime units
132 PRInt64 mValue;
136 * Instances of this class represent moments in time, or a special
137 * "null" moment. We do not use the non-monotonic system clock or
138 * local time, since they can be reset, causing apparent backward
139 * travel in time, which can confuse algorithms. Instead we measure
140 * elapsed time according to the system. This time can never go
141 * backwards (i.e. it never wraps around, at least not in less than
142 * five million years of system elapsed time). It might not advance
143 * while the system is sleeping. If TimeStamp::SetNow() is not called
144 * at all for hours or days, we might not notice the passage of some
145 * of that time.
147 * We deliberately do not expose a way to convert TimeStamps to some
148 * particular unit. All you can do is compute a difference between two
149 * TimeStamps to get a TimeDuration. You can also add a TimeDuration
150 * to a TimeStamp to get a new TimeStamp. You can't do something
151 * meaningless like add two TimeStamps.
153 * Internally this is implemented as either a wrapper around
154 * - high-resolution, monotonic, system clocks if they exist on this
155 * platform
156 * - PRIntervalTime otherwise. We detect wraparounds of
157 * PRIntervalTime and work around them.
159 class NS_COM TimeStamp
161 public:
163 * Initialize to the "null" moment
165 TimeStamp() : mValue(0) {}
166 // Default copy-constructor and assignment are OK
169 * Return true if this is the "null" moment
171 PRBool IsNull() const { return mValue == 0; }
173 * Return a timestamp reflecting the current elapsed system time. This
174 * is monotonically increasing (i.e., does not decrease) over the
175 * lifetime of this process' XPCOM session.
177 static TimeStamp Now();
179 * Compute the difference between two timestamps. Both must be non-null.
181 TimeDuration operator-(const TimeStamp& aOther) const {
182 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
183 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
184 return TimeDuration::FromTicks(mValue - aOther.mValue);
187 TimeStamp operator+(const TimeDuration& aOther) const {
188 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
189 return TimeStamp(mValue + aOther.mValue);
191 TimeStamp operator-(const TimeDuration& aOther) const {
192 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
193 return TimeStamp(mValue - aOther.mValue);
195 TimeStamp& operator+=(const TimeDuration& aOther) {
196 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
197 mValue += aOther.mValue;
198 return *this;
200 TimeStamp& operator-=(const TimeDuration& aOther) {
201 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
202 mValue -= aOther.mValue;
203 return *this;
206 PRBool operator<(const TimeStamp& aOther) const {
207 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
208 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
209 return mValue < aOther.mValue;
211 PRBool operator<=(const TimeStamp& aOther) const {
212 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
213 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
214 return mValue <= aOther.mValue;
216 PRBool operator>=(const TimeStamp& aOther) const {
217 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
218 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
219 return mValue >= aOther.mValue;
221 PRBool operator>(const TimeStamp& aOther) const {
222 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
223 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
224 return mValue > aOther.mValue;
226 PRBool operator==(const TimeStamp& aOther) const {
227 // Maybe it's ok to check == with null timestamps?
228 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
229 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
230 return mValue == aOther.mValue;
232 PRBool operator!=(const TimeStamp& aOther) const {
233 // Maybe it's ok to check != with null timestamps?
234 NS_ASSERTION(!IsNull(), "Cannot compute with a null value");
235 NS_ASSERTION(!aOther.IsNull(), "Cannot compute with aOther null value");
236 return mValue != aOther.mValue;
239 // Comparing TimeStamps for equality should be discouraged. Adding
240 // two TimeStamps, or scaling TimeStamps, is nonsense and must never
241 // be allowed.
243 static NS_HIDDEN_(nsresult) Startup();
244 static NS_HIDDEN_(void) Shutdown();
246 private:
247 TimeStamp(PRUint64 aValue) : mValue(aValue) {}
250 * When built with PRIntervalTime, a value of 0 means this instance
251 * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
252 * and the high 32 bits represent a counter of the number of
253 * rollovers of PRIntervalTime that we've seen. This counter starts
254 * at 1 to avoid a real time colliding with the "null" value.
256 * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
257 * time to wrap around is about 2^64/100000 seconds, i.e. about
258 * 5,849,424 years.
260 * When using a system clock, a value is system dependent.
262 PRUint64 mValue;
267 #endif /* mozilla_TimeStamp_h */