sel_ldr: Remove support for rodata segment at start of executable
[nativeclient.git] / service_runtime / time.h
blobb4944d665f5306fcd7c4308d5f8787919a67f83d
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Time represents an absolute point in time, internally represented as
34 // microseconds (s/1,000,000) since a platform-dependent epoch. Each
35 // platform's epoch, along with other system-dependent clock interface
36 // routines, is defined in time_PLATFORM.cc.
38 // TimeDelta represents a duration of time, internally represented in
39 // microseconds.
41 // TimeTicks represents an abstract time that is always incrementing for use
42 // in measuring time durations. It is internally represented in microseconds.
43 // It can not be converted to a human-readable time, but is guaranteed not to
44 // decrease (if the user changes the computer clock, Time::Now() may actually
45 // decrease or jump).
47 // These classes are represented as only a 64-bit value, so they can be
48 // efficiently passed by value.
50 #ifndef NATIVE_CLIENT_SERVICE_RUNTIME_TIME_H__
51 #define NATIVE_CLIENT_SERVICE_RUNTIME_TIME_H__
53 namespace NaCl {
55 class Time;
56 class TimeTicks;
58 // This unit test does a lot of manual time manipulation.
59 class PageLoadTrackerUnitTest;
61 // TimeDelta ------------------------------------------------------------------
63 class TimeDelta {
64 public:
65 TimeDelta() : delta_(0) {
68 // Converts units of time to TimeDeltas.
69 static TimeDelta FromDays(int64 days);
70 static TimeDelta FromHours(int64 hours);
71 static TimeDelta FromMinutes(int64 minutes);
72 static TimeDelta FromSeconds(int64 secs);
73 static TimeDelta FromMilliseconds(int64 ms);
74 static TimeDelta FromMicroseconds(int64 us);
76 // Returns the internal numeric value of the TimeDelta object. Please don't
77 // use this and do arithmetic on it, as it is more error prone than using the
78 // provided operators.
79 int64 ToInternalValue() const {
80 return delta_;
83 // Returns the time delta in some unit. The F versions return a floating
84 // point value, the "regular" versions return a rounded-down value.
85 int InDays() const;
86 double InSecondsF() const;
87 int64 InSeconds() const;
88 double InMillisecondsF() const;
89 int64 InMilliseconds() const;
90 int64 InMicroseconds() const;
92 TimeDelta& operator=(TimeDelta other) {
93 delta_ = other.delta_;
94 return *this;
97 // Computations with other deltas.
98 TimeDelta operator+(TimeDelta other) const {
99 return TimeDelta(delta_ + other.delta_);
101 TimeDelta operator-(TimeDelta other) const {
102 return TimeDelta(delta_ - other.delta_);
105 TimeDelta& operator+=(TimeDelta other) {
106 delta_ += other.delta_;
107 return *this;
109 TimeDelta& operator-=(TimeDelta other) {
110 delta_ -= other.delta_;
111 return *this;
113 TimeDelta operator-() const {
114 return TimeDelta(-delta_);
117 // Computations with ints, note that we only allow multiplicative operations
118 // with ints, and additive operations with other deltas.
119 TimeDelta operator*(int64 a) const {
120 return TimeDelta(delta_ * a);
122 TimeDelta operator/(int64 a) const {
123 return TimeDelta(delta_ / a);
125 TimeDelta& operator*=(int64 a) {
126 delta_ *= a;
127 return *this;
129 TimeDelta& operator/=(int64 a) {
130 delta_ /= a;
131 return *this;
133 int64 operator/(TimeDelta a) const {
134 return delta_ / a.delta_;
137 // Defined below because it depends on the definition of the other classes.
138 Time operator+(Time t) const;
139 TimeTicks operator+(TimeTicks t) const;
141 // Comparison operators.
142 bool operator==(TimeDelta other) const {
143 return delta_ == other.delta_;
145 bool operator!=(TimeDelta other) const {
146 return delta_ != other.delta_;
148 bool operator<(TimeDelta other) const {
149 return delta_ < other.delta_;
151 bool operator<=(TimeDelta other) const {
152 return delta_ <= other.delta_;
154 bool operator>(TimeDelta other) const {
155 return delta_ > other.delta_;
157 bool operator>=(TimeDelta other) const {
158 return delta_ >= other.delta_;
161 private:
162 friend class Time;
163 friend class TimeTicks;
164 friend TimeDelta operator*(int64 a, TimeDelta td);
166 // Constructs a delta given the duration in microseconds. This is private
167 // to avoid confusion by callers with an integer constructor. Use
168 // FromSeconds, FromMilliseconds, etc. instead.
169 explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
172 // Delta in microseconds.
173 int64 delta_;
176 inline TimeDelta operator*(int64 a, TimeDelta td) {
177 return TimeDelta(a * td.delta_);
180 // Time -----------------------------------------------------------------------
182 // Represents a wall clock time.
183 class Time {
184 public:
185 static const int64 kMillisecondsPerSecond = 1000;
186 static const int64 kMicrosecondsPerMillisecond = 1000;
187 static const int64 kNanosecondsPerMicrosecond = 1000;
188 static const int64 kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
189 kMillisecondsPerSecond;
190 static const int64 kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
191 static const int64 kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
192 static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * 24;
193 static const int64 kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
195 // Represents an exploded time that can be formatted nicely. This is kind of
196 // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
197 // additions and changes to prevent errors.
198 struct Exploded {
199 int year; // Four digit year "2007"
200 int month; // 1-based month (values 1 = January, etc.)
201 int day_of_week; // 0-based day of week (0 = Sunday, etc.)
202 int day_of_month; // 1-based day of month (1-31)
203 int hour; // Hour within the current day (0-23)
204 int minute; // Minute within the current hour (0-59)
205 int second; // Second within the current minute (0-59 plus leap
206 // seconds which may take it up to 60).
207 int millisecond; // Milliseconds within the current second (0-999)
210 // Contains the NULL time. Use Time::Now() to get the current time.
211 explicit Time() : us_(0) {
214 // Returns true if the time object has not been initialized.
215 bool is_null() const {
216 return us_ == 0;
219 // Returns the current time. Watch out, the system might adjust its clock
220 // in which case time will actually go backwards. We don't guarantee that
221 // times are increasing, or that two calls to Now() won't be the same.
222 static Time Now();
224 // Converts to/from time_t in UTC and a Time class.
225 // TODO this should be removed once everybody starts using the |Time|
226 // class.
227 static Time FromTimeT(time_t tt);
228 time_t ToTimeT() const;
230 // Converts time to a double which is the number of seconds since epoch
231 // (Jan 1, 1970). Webkit uses this format to represent time.
232 double ToDoubleT() const;
234 #ifdef WIN32
235 static Time FromFileTime(FILETIME ft);
236 FILETIME ToFileTime() const;
237 #endif
239 // Converts an exploded structure representing either the local time or UTC
240 // into a Time class.
241 static Time FromUTCExploded(const Exploded& exploded) {
242 return FromExploded(false, exploded);
244 static Time FromLocalExploded(const Exploded& exploded) {
245 return FromExploded(true, exploded);
248 // Converts an integer value representing Time to a class. This is used
249 // when deserializing a |Time| structure, using a value known to be
250 // compatible. It is not provided as a constructor because the integer type
251 // may be unclear from the perspective of a caller.
252 static Time FromInternalValue(int64 us) {
253 return Time(us);
256 // Converts a string representation of time to a Time object.
257 // An example of a time string which is converted is as below:-
258 // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified
259 // in the input string, we assume local time.
260 // TODO Move the FromString/FromTimeT/ToTimeT/FromFileTime to
261 // a new time converter class.
262 // NOTE - removed to avoid the need in string suppport
263 // static bool FromString(const wchar_t* time_string, Time* parsed_time);
265 // For serializing, use FromInternalValue to reconstitute. Please don't use
266 // this and do arithmetic on it, as it is more error prone than using the
267 // provided operators.
268 int64 ToInternalValue() const {
269 return us_;
272 // Fills the given exploded structure with either the local time or UTC from
273 // this time structure (containing UTC).
274 void UTCExplode(Exploded* exploded) const {
275 return Explode(false, exploded);
277 void LocalExplode(Exploded* exploded) const {
278 return Explode(true, exploded);
281 // Rounds this time down to the nearest day in local time. It will represent
282 // midnight on that day.
283 Time LocalMidnight() const;
285 Time& operator=(Time other) {
286 us_ = other.us_;
287 return *this;
290 // Compute the difference between two times.
291 TimeDelta operator-(Time other) const {
292 return TimeDelta(us_ - other.us_);
295 // Modify by some time delta.
296 Time& operator+=(TimeDelta delta) {
297 us_ += delta.delta_;
298 return *this;
300 Time& operator-=(TimeDelta delta) {
301 us_ -= delta.delta_;
302 return *this;
305 // Return a new time modified by some delta.
306 Time operator+(TimeDelta delta) const {
307 return us_ + delta.delta_;
309 Time operator-(TimeDelta delta) const {
310 return us_ - delta.delta_;
313 // Comparison operators
314 bool operator==(Time other) const {
315 return us_ == other.us_;
317 bool operator!=(Time other) const {
318 return us_ != other.us_;
320 bool operator<(Time other) const {
321 return us_ < other.us_;
323 bool operator<=(Time other) const {
324 return us_ <= other.us_;
326 bool operator>(Time other) const {
327 return us_ > other.us_;
329 bool operator>=(Time other) const {
330 return us_ >= other.us_;
333 private:
334 friend class TimeDelta;
336 // Platform-dependent wall clock interface
337 static int64 CurrentWallclockMicroseconds();
339 // Initialize or resynchronize the clock.
340 static void InitializeClock();
342 // Explodes the given time to either local time |is_local = true| or UTC
343 // |is_local = false|.
344 void Explode(bool is_local, Exploded* exploded) const;
346 // Unexplodes a given time assuming the source is either local time
347 // |is_local = true| or UTC |is_local = false|.
348 static Time FromExploded(bool is_local, const Exploded& exploded);
350 Time(int64 us) : us_(us) {
353 // The representation of Jan 1, 1970 UTC in microseconds since the
354 // platform-dependent epoch.
355 static const int64 kTimeTToMicrosecondsOffset;
357 // Time in microseconds in UTC.
358 int64 us_;
360 // The initial time sampled via this API.
361 static int64 initial_time_;
363 // The initial clock counter sampled via this API.
364 static TimeTicks initial_ticks_;
367 inline Time TimeDelta::operator+(Time t) const {
368 return Time(t.us_ + delta_);
371 // TimeTicks ------------------------------------------------------------------
373 class TimeTicks {
374 public:
375 TimeTicks() : ticks_(0) {
378 // TODO: made this constructor public, but might undo this change
379 // when we cleanup the time-handling code.
380 explicit TimeTicks(int64 ticks) : ticks_(ticks) {
383 // Platform-dependent tick count representing "right now."
384 // The resolution of this clock is ~1-5ms. Resolution varies depending
385 // on hardware/operating system configuration.
386 static TimeTicks Now();
388 // Returns a platform-dependent high-resolution tick count. IT IS BROKEN ON
389 // SOME HARDWARE and is designed to be used for profiling and perf testing
390 // only (see the impl for more information).
391 static TimeTicks UnreliableHighResNow();
394 // Returns true if this object has not been initialized.
395 bool is_null() const {
396 return ticks_ == 0;
399 TimeTicks& operator=(TimeTicks other) {
400 ticks_ = other.ticks_;
401 return *this;
404 // Compute the difference between two times.
405 TimeDelta operator-(TimeTicks other) const {
406 return TimeDelta(ticks_ - other.ticks_);
409 // Modify by some time delta.
410 TimeTicks& operator+=(TimeDelta delta) {
411 ticks_ += delta.delta_;
412 return *this;
414 TimeTicks& operator-=(TimeDelta delta) {
415 ticks_ -= delta.delta_;
416 return *this;
419 // Return a new TimeTicks modified by some delta.
420 TimeTicks operator+(TimeDelta delta) const {
421 return TimeTicks(ticks_ + delta.delta_);
423 TimeTicks operator-(TimeDelta delta) const {
424 return TimeTicks(ticks_ - delta.delta_);
427 // Comparison operators
428 bool operator==(TimeTicks other) const {
429 return ticks_ == other.ticks_;
431 bool operator!=(TimeTicks other) const {
432 return ticks_ != other.ticks_;
434 bool operator<(TimeTicks other) const {
435 return ticks_ < other.ticks_;
437 bool operator<=(TimeTicks other) const {
438 return ticks_ <= other.ticks_;
440 bool operator>(TimeTicks other) const {
441 return ticks_ > other.ticks_;
443 bool operator>=(TimeTicks other) const {
444 return ticks_ >= other.ticks_;
446 #if NACL_LINUX || NACL_OSX
447 void InitTimespec(struct timespec *ts) const;
448 #endif
449 protected:
450 friend class TimeDelta;
451 friend class PageLoadTrackerUnitTest;
454 // Tick count in microseconds.
455 int64 ticks_;
457 #ifdef WIN32
458 // The function to use for counting ticks.
459 typedef int (__stdcall *TickFunction)(void);
460 static TickFunction tick_function_;
461 #endif
464 inline TimeTicks TimeDelta::operator+(TimeTicks t) const {
465 return TimeTicks(t.ticks_ + delta_);
468 } // namespace NaCl
470 #endif // NATIVE_CLIENT_SERVICE_RUNTIME_TIME_H__