OLD | NEW |
| (Empty) |
1 // Copyright 2014 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/base/platform/time.h" | |
6 | |
7 #if V8_OS_MACOSX | |
8 #include <mach/mach_time.h> | |
9 #endif | |
10 #if V8_OS_POSIX | |
11 #include <sys/time.h> | |
12 #endif | |
13 | |
14 #if V8_OS_WIN | |
15 #include "src/base/win32-headers.h" | |
16 #endif | |
17 | |
18 #include "src/base/platform/elapsed-timer.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace v8 { | |
22 namespace base { | |
23 | |
24 TEST(TimeDelta, FromAndIn) { | |
25 EXPECT_EQ(TimeDelta::FromDays(2), TimeDelta::FromHours(48)); | |
26 EXPECT_EQ(TimeDelta::FromHours(3), TimeDelta::FromMinutes(180)); | |
27 EXPECT_EQ(TimeDelta::FromMinutes(2), TimeDelta::FromSeconds(120)); | |
28 EXPECT_EQ(TimeDelta::FromSeconds(2), TimeDelta::FromMilliseconds(2000)); | |
29 EXPECT_EQ(TimeDelta::FromMilliseconds(2), TimeDelta::FromMicroseconds(2000)); | |
30 EXPECT_EQ(static_cast<int>(13), TimeDelta::FromDays(13).InDays()); | |
31 EXPECT_EQ(static_cast<int>(13), TimeDelta::FromHours(13).InHours()); | |
32 EXPECT_EQ(static_cast<int>(13), TimeDelta::FromMinutes(13).InMinutes()); | |
33 EXPECT_EQ(static_cast<int64_t>(13), TimeDelta::FromSeconds(13).InSeconds()); | |
34 EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF()); | |
35 EXPECT_EQ(static_cast<int64_t>(13), | |
36 TimeDelta::FromMilliseconds(13).InMilliseconds()); | |
37 EXPECT_DOUBLE_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF()); | |
38 EXPECT_EQ(static_cast<int64_t>(13), | |
39 TimeDelta::FromMicroseconds(13).InMicroseconds()); | |
40 } | |
41 | |
42 | |
43 #if V8_OS_MACOSX | |
44 TEST(TimeDelta, MachTimespec) { | |
45 TimeDelta null = TimeDelta(); | |
46 EXPECT_EQ(null, TimeDelta::FromMachTimespec(null.ToMachTimespec())); | |
47 TimeDelta delta1 = TimeDelta::FromMilliseconds(42); | |
48 EXPECT_EQ(delta1, TimeDelta::FromMachTimespec(delta1.ToMachTimespec())); | |
49 TimeDelta delta2 = TimeDelta::FromDays(42); | |
50 EXPECT_EQ(delta2, TimeDelta::FromMachTimespec(delta2.ToMachTimespec())); | |
51 } | |
52 #endif | |
53 | |
54 | |
55 TEST(Time, JsTime) { | |
56 Time t = Time::FromJsTime(700000.3); | |
57 EXPECT_DOUBLE_EQ(700000.3, t.ToJsTime()); | |
58 } | |
59 | |
60 | |
61 #if V8_OS_POSIX | |
62 TEST(Time, Timespec) { | |
63 Time null; | |
64 EXPECT_TRUE(null.IsNull()); | |
65 EXPECT_EQ(null, Time::FromTimespec(null.ToTimespec())); | |
66 Time now = Time::Now(); | |
67 EXPECT_EQ(now, Time::FromTimespec(now.ToTimespec())); | |
68 Time now_sys = Time::NowFromSystemTime(); | |
69 EXPECT_EQ(now_sys, Time::FromTimespec(now_sys.ToTimespec())); | |
70 Time unix_epoch = Time::UnixEpoch(); | |
71 EXPECT_EQ(unix_epoch, Time::FromTimespec(unix_epoch.ToTimespec())); | |
72 Time max = Time::Max(); | |
73 EXPECT_TRUE(max.IsMax()); | |
74 EXPECT_EQ(max, Time::FromTimespec(max.ToTimespec())); | |
75 } | |
76 | |
77 | |
78 TEST(Time, Timeval) { | |
79 Time null; | |
80 EXPECT_TRUE(null.IsNull()); | |
81 EXPECT_EQ(null, Time::FromTimeval(null.ToTimeval())); | |
82 Time now = Time::Now(); | |
83 EXPECT_EQ(now, Time::FromTimeval(now.ToTimeval())); | |
84 Time now_sys = Time::NowFromSystemTime(); | |
85 EXPECT_EQ(now_sys, Time::FromTimeval(now_sys.ToTimeval())); | |
86 Time unix_epoch = Time::UnixEpoch(); | |
87 EXPECT_EQ(unix_epoch, Time::FromTimeval(unix_epoch.ToTimeval())); | |
88 Time max = Time::Max(); | |
89 EXPECT_TRUE(max.IsMax()); | |
90 EXPECT_EQ(max, Time::FromTimeval(max.ToTimeval())); | |
91 } | |
92 #endif | |
93 | |
94 | |
95 #if V8_OS_WIN | |
96 TEST(Time, Filetime) { | |
97 Time null; | |
98 EXPECT_TRUE(null.IsNull()); | |
99 EXPECT_EQ(null, Time::FromFiletime(null.ToFiletime())); | |
100 Time now = Time::Now(); | |
101 EXPECT_EQ(now, Time::FromFiletime(now.ToFiletime())); | |
102 Time now_sys = Time::NowFromSystemTime(); | |
103 EXPECT_EQ(now_sys, Time::FromFiletime(now_sys.ToFiletime())); | |
104 Time unix_epoch = Time::UnixEpoch(); | |
105 EXPECT_EQ(unix_epoch, Time::FromFiletime(unix_epoch.ToFiletime())); | |
106 Time max = Time::Max(); | |
107 EXPECT_TRUE(max.IsMax()); | |
108 EXPECT_EQ(max, Time::FromFiletime(max.ToFiletime())); | |
109 } | |
110 #endif | |
111 | |
112 | |
113 namespace { | |
114 | |
115 template <typename T> | |
116 static void ResolutionTest(T (*Now)(), TimeDelta target_granularity) { | |
117 // We're trying to measure that intervals increment in a VERY small amount | |
118 // of time -- according to the specified target granularity. Unfortunately, | |
119 // if we happen to have a context switch in the middle of our test, the | |
120 // context switch could easily exceed our limit. So, we iterate on this | |
121 // several times. As long as we're able to detect the fine-granularity | |
122 // timers at least once, then the test has succeeded. | |
123 static const TimeDelta kExpirationTimeout = TimeDelta::FromSeconds(1); | |
124 ElapsedTimer timer; | |
125 timer.Start(); | |
126 TimeDelta delta; | |
127 do { | |
128 T start = Now(); | |
129 T now = start; | |
130 // Loop until we can detect that the clock has changed. Non-HighRes timers | |
131 // will increment in chunks, i.e. 15ms. By spinning until we see a clock | |
132 // change, we detect the minimum time between measurements. | |
133 do { | |
134 now = Now(); | |
135 delta = now - start; | |
136 } while (now <= start); | |
137 EXPECT_NE(static_cast<int64_t>(0), delta.InMicroseconds()); | |
138 } while (delta > target_granularity && !timer.HasExpired(kExpirationTimeout)); | |
139 EXPECT_LE(delta, target_granularity); | |
140 } | |
141 | |
142 } // namespace | |
143 | |
144 | |
145 TEST(Time, NowResolution) { | |
146 // We assume that Time::Now() has at least 16ms resolution. | |
147 static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16); | |
148 ResolutionTest<Time>(&Time::Now, kTargetGranularity); | |
149 } | |
150 | |
151 | |
152 TEST(TimeTicks, NowResolution) { | |
153 // We assume that TimeTicks::Now() has at least 16ms resolution. | |
154 static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(16); | |
155 ResolutionTest<TimeTicks>(&TimeTicks::Now, kTargetGranularity); | |
156 } | |
157 | |
158 | |
159 TEST(TimeTicks, HighResolutionNowResolution) { | |
160 if (!TimeTicks::IsHighResolutionClockWorking()) return; | |
161 | |
162 // We assume that TimeTicks::HighResolutionNow() has sub-ms resolution. | |
163 static const TimeDelta kTargetGranularity = TimeDelta::FromMilliseconds(1); | |
164 ResolutionTest<TimeTicks>(&TimeTicks::HighResolutionNow, kTargetGranularity); | |
165 } | |
166 | |
167 | |
168 TEST(TimeTicks, IsMonotonic) { | |
169 TimeTicks previous_normal_ticks; | |
170 TimeTicks previous_highres_ticks; | |
171 ElapsedTimer timer; | |
172 timer.Start(); | |
173 while (!timer.HasExpired(TimeDelta::FromMilliseconds(100))) { | |
174 TimeTicks normal_ticks = TimeTicks::Now(); | |
175 TimeTicks highres_ticks = TimeTicks::HighResolutionNow(); | |
176 EXPECT_GE(normal_ticks, previous_normal_ticks); | |
177 EXPECT_GE((normal_ticks - previous_normal_ticks).InMicroseconds(), 0); | |
178 EXPECT_GE(highres_ticks, previous_highres_ticks); | |
179 EXPECT_GE((highres_ticks - previous_highres_ticks).InMicroseconds(), 0); | |
180 previous_normal_ticks = normal_ticks; | |
181 previous_highres_ticks = highres_ticks; | |
182 } | |
183 } | |
184 | |
185 } // namespace base | |
186 } // namespace v8 | |
OLD | NEW |