OLD | NEW |
| (Empty) |
1 // Copyright 2006-2009 Google Inc. | |
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 "base/basictypes.h" | |
16 #include "omaha/base/highres_timer-win32.h" | |
17 #include "omaha/testing/unit_test.h" | |
18 | |
19 namespace omaha { | |
20 | |
21 // Timing tests are extremely sensitive to external interference from other | |
22 // work currently being done on the machine. scoped_priority_boost temporarily | |
23 // raises the priority of the caller's thread to reduce the chance of an | |
24 // intervening context switch. | |
25 | |
26 class scoped_priority_boost { | |
27 public: | |
28 scoped_priority_boost() { | |
29 orig_process_priority_ = ::GetPriorityClass(::GetCurrentProcess()); | |
30 if (0 != orig_process_priority_) { | |
31 if (0 == ::SetPriorityClass(::GetCurrentProcess(), | |
32 HIGH_PRIORITY_CLASS)) { | |
33 orig_process_priority_ = 0; | |
34 } | |
35 } | |
36 | |
37 orig_thread_priority_ = ::GetThreadPriority(::GetCurrentThread()); | |
38 if (THREAD_PRIORITY_ERROR_RETURN != orig_thread_priority_) { | |
39 if (0 == ::SetThreadPriority(::GetCurrentThread(), | |
40 THREAD_PRIORITY_HIGHEST)) { | |
41 orig_thread_priority_ = THREAD_PRIORITY_ERROR_RETURN; | |
42 } | |
43 } | |
44 } | |
45 | |
46 ~scoped_priority_boost() { | |
47 if (0 != orig_process_priority_) { | |
48 ::SetPriorityClass(::GetCurrentProcess(), orig_process_priority_); | |
49 } | |
50 if (THREAD_PRIORITY_ERROR_RETURN != orig_thread_priority_) { | |
51 ::SetPriorityClass(::GetCurrentProcess(), orig_process_priority_); | |
52 } | |
53 } | |
54 | |
55 bool succeeded() const { | |
56 return (0 != orig_process_priority_) && | |
57 (THREAD_PRIORITY_ERROR_RETURN != orig_thread_priority_); | |
58 } | |
59 | |
60 private: | |
61 DWORD orig_process_priority_; | |
62 int orig_thread_priority_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(scoped_priority_boost); | |
65 }; | |
66 | |
67 TEST(HighresTimer, MillisecondClock) { | |
68 scoped_priority_boost spb; | |
69 EXPECT_TRUE(spb.succeeded()); | |
70 | |
71 HighresTimer timer; | |
72 | |
73 // note: this could fail if we context switch between initializing the timer | |
74 // and here. Very unlikely however. | |
75 EXPECT_EQ(0, timer.GetElapsedMs()); | |
76 timer.Start(); | |
77 uint64 half_ms = (HighresTimer::GetTimerFrequency() / 2000) + 1; | |
78 // busy wait for a fraction more than half a millisecond. | |
79 while (timer.start_ticks() + half_ms > HighresTimer::GetCurrentTicks()) { | |
80 // Nothing | |
81 } | |
82 EXPECT_EQ(1, timer.GetElapsedMs()); | |
83 } | |
84 | |
85 TEST(HighresTimer, SecondClock) { | |
86 scoped_priority_boost spb; | |
87 EXPECT_TRUE(spb.succeeded()); | |
88 | |
89 HighresTimer timer; | |
90 | |
91 EXPECT_EQ(0, timer.GetElapsedSec()); | |
92 #ifdef OS_WINDOWS | |
93 ::Sleep(250); | |
94 #else | |
95 struct timespec ts1 = {0, 250000000}; | |
96 nanosleep(&ts1, 0); | |
97 #endif | |
98 EXPECT_EQ(0, timer.GetElapsedSec()); | |
99 EXPECT_LE(230, timer.GetElapsedMs()); | |
100 EXPECT_GE(270, timer.GetElapsedMs()); | |
101 #ifdef OS_WINDOWS | |
102 ::Sleep(251); | |
103 #else | |
104 struct timespec ts2 = {0, 251000000}; | |
105 nanosleep(&ts2, 0); | |
106 #endif | |
107 EXPECT_EQ(1, timer.GetElapsedSec()); | |
108 } | |
109 | |
110 } // namespace omaha | |
111 | |
OLD | NEW |