2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
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
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.
36 #include "native_client/include/portability.h"
37 #include "native_client/include/base/basictypes.h"
39 #include "native_client/service_runtime/time.h"
41 // The Time routines in this file use standard POSIX routines, or almost-
42 // standard routines in the case of timegm.
43 // The TimeTicks routines are Mach-specific.
45 // Time -----------------------------------------------------------------------
47 // The internal representation of Time uses time_t directly, so there is no
48 // offset. The epoch is 1970-01-01 00:00:00 UTC.
50 const int64
NaCl::Time::kTimeTToMicrosecondsOffset
= GG_INT64_C(0);
53 int64
NaCl::Time::CurrentWallclockMicroseconds() {
55 struct timezone tz
= { 0, 0 }; // UTC
56 if (gettimeofday(&tv
, &tz
) != 0) {
57 // DCHECK(0) << "Could not determine time of day";
59 // Combine seconds and microseconds in a 64-bit field containing microseconds
60 // since the epoch. That's enough for nearly 600 centuries.
61 return tv
.tv_sec
* GG_UINT64_C(1000000) + tv
.tv_usec
;
65 NaCl::Time
NaCl::Time::FromExploded(bool is_local
, const Exploded
& exploded
) {
67 timestruct
.tm_sec
= exploded
.second
;
68 timestruct
.tm_min
= exploded
.minute
;
69 timestruct
.tm_hour
= exploded
.hour
;
70 timestruct
.tm_mday
= exploded
.day_of_month
;
71 timestruct
.tm_mon
= exploded
.month
- 1;
72 timestruct
.tm_year
= exploded
.year
- 1900;
73 timestruct
.tm_wday
= exploded
.day_of_week
; // mktime/timegm ignore this
74 timestruct
.tm_yday
= 0; // mktime/timegm ignore this
75 timestruct
.tm_isdst
= -1; // attempt to figure it out
76 timestruct
.tm_gmtoff
= 0; // not a POSIX field, so mktime/timegm ignore
77 timestruct
.tm_zone
= NULL
; // not a POSIX field, so mktime/timegm ignore
81 seconds
= mktime(×truct
);
83 seconds
= timegm(×truct
);
84 // DCHECK(seconds >= 0) << "mktime/timegm could not convert from exploded";
86 uint64 milliseconds
= seconds
* kMillisecondsPerSecond
+ exploded
.millisecond
;
87 return Time(milliseconds
* kMicrosecondsPerMillisecond
);
90 void NaCl::Time::Explode(bool is_local
, Exploded
* exploded
) const {
91 // Time stores times with microsecond resolution, but Exploded only carries
92 // millisecond resolution, so begin by being lossy.
93 uint64 milliseconds
= us_
/ kMicrosecondsPerMillisecond
;
94 time_t seconds
= milliseconds
/ kMillisecondsPerSecond
;
98 localtime_r(&seconds
, ×truct
);
100 gmtime_r(&seconds
, ×truct
);
102 exploded
->year
= timestruct
.tm_year
+ 1900;
103 exploded
->month
= timestruct
.tm_mon
+ 1;
104 exploded
->day_of_week
= timestruct
.tm_wday
;
105 exploded
->day_of_month
= timestruct
.tm_mday
;
106 exploded
->hour
= timestruct
.tm_hour
;
107 exploded
->minute
= timestruct
.tm_min
;
108 exploded
->second
= timestruct
.tm_sec
;
109 exploded
->millisecond
= milliseconds
% kMillisecondsPerSecond
;
112 // TimeTicks ------------------------------------------------------------------
115 NaCl::TimeTicks
NaCl::TimeTicks::Now() {
117 struct timezone tz
= { 0, 0 }; // UTC
118 if (gettimeofday(&tv
, &tz
) != 0) {
119 // DCHECK(0) << "Could not determine time of day";
122 // Combine seconds and microseconds in a 64-bit field containing microseconds
123 // since the epoch. That's enough for nearly 600 centuries.
124 return TimeTicks(tv
.tv_sec
* GG_UINT64_C(1000000) + tv
.tv_usec
);
128 NaCl::TimeTicks
NaCl::TimeTicks::UnreliableHighResNow() {
132 void NaCl::TimeTicks::InitTimespec(struct timespec
*ts
) const {
133 // from microseconds into seconds
134 ts
->tv_sec
= ticks_
/ GG_UINT64_C(1000000);
135 // microseconds into nano
136 ts
->tv_nsec
= (ticks_
- ts
->tv_sec
* GG_UINT64_C(1000000)) * 1000;