1 : // Copyright 2013 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/trace/common/clock.h"
16 :
17 : #include "gtest/gtest.h"
18 :
19 : namespace trace {
20 : namespace common {
21 :
22 : namespace {
23 :
24 E : void CheckValidTickTimerInfo(const TimerInfo& ti) {
25 E : EXPECT_EQ(1000u, ti.frequency);
26 E : EXPECT_LT(0u, ti.resolution);
27 E : }
28 :
29 E : void CheckValidTscTimerInfo(const TimerInfo& ti) {
30 : // We have no precise expectations about TSC info, except that both entries
31 : // are zero or they are both non-zero.
32 E : if (ti.resolution == 0) {
33 i : EXPECT_EQ(0u, ti.frequency);
34 i : } else {
35 E : EXPECT_EQ(1u, ti.resolution);
36 E : EXPECT_LT(0u, ti.frequency);
37 : }
38 E : }
39 :
40 : } // namespace
41 :
42 E : TEST(GetTickTimerInfoTest, WorksAsExpected) {
43 E : TimerInfo ti = {};
44 E : GetTickTimerInfo(&ti);
45 E : CheckValidTickTimerInfo(ti);
46 E : }
47 :
48 E : TEST(GetTscTimerInfoTest, WorksAsExpected) {
49 E : TimerInfo ti = {};
50 E : GetTscTimerInfo(&ti);
51 E : CheckValidTscTimerInfo(ti);
52 E : }
53 :
54 E : TEST(GetTicksTest, WorksAsExpected) {
55 : // This will busy loop until the counter advances, or until we perform
56 : // 2^32 iterations. The counter should definitely have advanced by then.
57 E : uint64 t1 = GetTicks();
58 E : uint64 t2 = t1;
59 E : uint32 count = 0;
60 E : while (t2 == t1 && ++count != 0)
61 E : t2 = GetTicks();
62 E : }
63 :
64 E : TEST(GetTscTest, WorksAsExpected) {
65 : // This will busy loop until the counter advances, or until we perform
66 : // 2^32 iterations. The counter should definitely have advanced by then.
67 E : uint64 t1 = GetTsc();
68 E : uint64 t2 = t1;
69 E : uint32 count = 0;
70 E : while (t2 == t1 && ++count != 0)
71 E : t2 = GetTsc();
72 E : }
73 :
74 E : TEST(TimerToFileTimeTest, FailsForInvalidTimerInfo) {
75 E : FILETIME ft1 = {};
76 E : TimerInfo ti = {};
77 E : FILETIME ft2 = {};
78 E : EXPECT_FALSE(TimerToFileTime(ft1, ti, 0, 0, &ft2));
79 E : }
80 :
81 E : TEST(TimerToFileTimeTest, FailsForLargeNegativeInterval) {
82 E : FILETIME ft1 = {};
83 E : TimerInfo ti = {};
84 E : FILETIME ft2 = {};
85 :
86 : // This should fail as -100 s is not representable starting at a filetime of
87 : // 0.
88 E : ti.frequency = 1;
89 E : ti.resolution = 1;
90 E : EXPECT_FALSE(TimerToFileTime(ft1, ti, 100, 0, &ft2));
91 E : }
92 :
93 E : TEST(TimerToFileTimeTest, Identity) {
94 E : FILETIME ft1 = { 0xBAAD, 0xCAFE };
95 E : TimerInfo ti = {};
96 E : FILETIME ft2 = {};
97 :
98 E : ti.frequency = 1;
99 E : ti.resolution = 1;
100 E : EXPECT_TRUE(TimerToFileTime(ft1, ti, 0, 0, &ft2));
101 E : EXPECT_EQ(ft1.dwLowDateTime, ft2.dwLowDateTime);
102 E : EXPECT_EQ(ft1.dwHighDateTime, ft2.dwHighDateTime);
103 E : }
104 :
105 E : TEST(TimerToFileTimeTest, PositiveInterval) {
106 E : FILETIME ft1 = {};
107 E : TimerInfo ti = {};
108 E : FILETIME ft2 = {};
109 :
110 E : ft1.dwLowDateTime = 0x10000;
111 :
112 : // This corresponds to 100ns ticks, which is the same precision as the
113 : // underlying filetime.
114 E : ti.frequency = 10000000;
115 E : ti.resolution = 1;
116 :
117 : // We expect the filetime to have increased by 100 intervals.
118 E : EXPECT_TRUE(TimerToFileTime(ft1, ti, 200, 300, &ft2));
119 E : EXPECT_EQ(0u, ft2.dwHighDateTime);
120 E : EXPECT_EQ(ft1.dwLowDateTime + 100, ft2.dwLowDateTime);
121 E : }
122 :
123 E : TEST(TimerToFileTimeTest, NegativeInterval) {
124 E : FILETIME ft1 = {};
125 E : TimerInfo ti = {};
126 E : FILETIME ft2 = {};
127 :
128 E : ft1.dwLowDateTime = 0x10000;
129 :
130 : // This corresponds to 100ns ticks, which is the same precision as the
131 : // underlying filetime.
132 E : ti.frequency = 10000000;
133 E : ti.resolution = 1;
134 :
135 : // We expect the filetime to have decreased by 100 intervals.
136 E : EXPECT_TRUE(TimerToFileTime(ft1, ti, 300, 200, &ft2));
137 E : EXPECT_EQ(0u, ft2.dwHighDateTime);
138 E : EXPECT_EQ(ft1.dwLowDateTime - 100, ft2.dwLowDateTime);
139 E : }
140 :
141 E : TEST(ClockInfoTest, GetClockInfo) {
142 E : ClockInfo ci = {};
143 E : GetClockInfo(&ci);
144 :
145 E : CheckValidTickTimerInfo(ci.ticks_info);
146 E : CheckValidTscTimerInfo(ci.tsc_info);
147 E : }
148 :
149 E : TEST(TicksToFileTimeTest, WorksAsExpected) {
150 E : ClockInfo ci = {};
151 E : FILETIME ft = {};
152 :
153 E : EXPECT_FALSE(TicksToFileTime(ci, 100, &ft));
154 :
155 : // 100 ms is 1e6 100ns intervals.
156 E : ci.ticks_info.frequency = 1000;
157 E : ci.ticks_info.resolution = 1;
158 E : EXPECT_TRUE(TicksToFileTime(ci, 100, &ft));
159 E : EXPECT_EQ(1e6, ft.dwLowDateTime);
160 E : EXPECT_EQ(0, ft.dwHighDateTime);
161 E : }
162 :
163 E : TEST(TscToFileTimeTest, WorksAsExpected) {
164 E : ClockInfo ci = {};
165 E : FILETIME ft = {};
166 :
167 E : EXPECT_FALSE(TscToFileTime(ci, 100, &ft));
168 :
169 : // 100 ms is 1e6 100ns intervals.
170 E : ci.tsc_info.frequency = 1000;
171 E : ci.tsc_info.resolution = 1;
172 E : EXPECT_TRUE(TscToFileTime(ci, 100, &ft));
173 E : EXPECT_EQ(1e6, ft.dwLowDateTime);
174 E : EXPECT_EQ(0, ft.dwHighDateTime);
175 E : }
176 :
177 : } // namespace common
178 : } // namespace trace
|