Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: Source/platform/TimerTest.cpp

Issue 1162903005: Revert of Implement timers by posting delayed tasks (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/Timer.cpp ('k') | Source/platform/blink_platform.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "platform/Timer.h" 6 #include "platform/Timer.h"
7 7
8 #include "public/platform/Platform.h" 8 #include "public/platform/Platform.h"
9 #include "public/platform/WebScheduler.h" 9 #include "public/platform/WebScheduler.h"
10 #include "public/platform/WebThread.h" 10 #include "public/platform/WebThread.h"
11 #include <gmock/gmock.h> 11 #include <gmock/gmock.h>
12 #include <gtest/gtest.h> 12 #include <gtest/gtest.h>
13 #include <queue> 13 #include <queue>
14 14
15 using testing::ElementsAre; 15 using testing::ElementsAre;
16 16
17 namespace blink { 17 namespace blink {
18 namespace { 18 namespace {
19 double gCurrentTimeSecs = 0.0; 19 double gCurrentTimeSecs = 0.0;
20 20
21 double currentTime() 21 double currentTime()
22 { 22 {
23 return gCurrentTimeSecs; 23 return gCurrentTimeSecs;
24 } 24 }
25 25
26 // This class exists because gcc doesn't know how to move an OwnPtr.
27 class RefCountedTaskContainer : public RefCounted<RefCountedTaskContainer> {
28 public:
29 explicit RefCountedTaskContainer(WebThread::Task* task) : m_task(adoptPtr(ta sk)) { }
30
31 ~RefCountedTaskContainer() { }
32
33 void run()
34 {
35 m_task->run();
36 }
37
38 private:
39 OwnPtr<WebThread::Task> m_task;
40 };
41
42 class DelayedTask {
43 public:
44 DelayedTask(WebThread::Task* task, long long delayMs)
45 : m_task(adoptRef(new RefCountedTaskContainer(task)))
46 , m_runTimeSecs(monotonicallyIncreasingTime() + 0.001 * static_cast<doub le>(delayMs))
47 , m_delayMs(delayMs) { }
48
49 bool operator<(const DelayedTask& other) const
50 {
51 return m_runTimeSecs > other.m_runTimeSecs;
52 }
53
54 void run() const
55 {
56 m_task->run();
57 }
58
59 double runTimeSecs() const
60 {
61 return m_runTimeSecs;
62 }
63
64 long long delayMs() const
65 {
66 return m_delayMs;
67 }
68
69 private:
70 RefPtr<RefCountedTaskContainer> m_task;
71 double m_runTimeSecs;
72 long long m_delayMs;
73 };
74
75 class MockWebScheduler : public WebScheduler { 26 class MockWebScheduler : public WebScheduler {
76 public: 27 public:
77 MockWebScheduler() { } 28 explicit MockWebScheduler() { }
78 ~MockWebScheduler() override { } 29 ~MockWebScheduler() override { }
79 30
80 bool shouldYieldForHighPriorityWork() override 31 bool shouldYieldForHighPriorityWork() override
81 { 32 {
82 return false; 33 return false;
83 } 34 }
84 35
85 bool canExceedIdleDeadlineIfRequired() override 36 bool canExceedIdleDeadlineIfRequired() override
86 { 37 {
87 return false; 38 return false;
(...skipping 10 matching lines...) Expand all
98 void postIdleTaskAfterWakeup(const WebTraceLocation&, WebThread::IdleTask*) override 49 void postIdleTaskAfterWakeup(const WebTraceLocation&, WebThread::IdleTask*) override
99 { 50 {
100 } 51 }
101 52
102 void postLoadingTask(const WebTraceLocation&, WebThread::Task*) override 53 void postLoadingTask(const WebTraceLocation&, WebThread::Task*) override
103 { 54 {
104 } 55 }
105 56
106 void postTimerTask(const WebTraceLocation&, WebThread::Task* task, long long delayMs) override 57 void postTimerTask(const WebTraceLocation&, WebThread::Task* task, long long delayMs) override
107 { 58 {
108 m_timerTasks.push(DelayedTask(task, delayMs));
109 } 59 }
110
111 void runUntilIdle()
112 {
113 while (!m_timerTasks.empty()) {
114 gCurrentTimeSecs = m_timerTasks.top().runTimeSecs();
115 m_timerTasks.top().run();
116 m_timerTasks.pop();
117 }
118 }
119
120 void runUntilIdleOrDeadlinePassed(double deadline)
121 {
122 while (!m_timerTasks.empty()) {
123 if (m_timerTasks.top().runTimeSecs() > deadline) {
124 gCurrentTimeSecs = deadline;
125 break;
126 }
127 gCurrentTimeSecs = m_timerTasks.top().runTimeSecs();
128 m_timerTasks.top().run();
129 m_timerTasks.pop();
130 }
131 }
132
133 bool hasOneTimerTask() const
134 {
135 return m_timerTasks.size() == 1;
136 }
137
138 long nextTimerTaskDelayMillis() const
139 {
140 ASSERT(hasOneTimerTask());
141 return m_timerTasks.top().delayMs();
142 }
143
144 private:
145 std::priority_queue<DelayedTask> m_timerTasks;
146 }; 60 };
147 61
148 class FakeWebThread : public WebThread { 62 class FakeWebThread : public WebThread {
149 public: 63 public:
150 FakeWebThread() : m_webScheduler(adoptPtr(new MockWebScheduler())) { } 64 explicit FakeWebThread(WebScheduler* webScheduler) : m_webScheduler(webSched uler) { }
151 ~FakeWebThread() override { } 65 ~FakeWebThread() override { }
152 66
153 // WebThread implementation: 67 // WebThread implementation:
154 void postTask(const WebTraceLocation&, Task*) 68 void postTask(const WebTraceLocation&, Task*)
155 { 69 {
156 ASSERT_NOT_REACHED(); 70 ASSERT_NOT_REACHED();
157 } 71 }
158 72
159 virtual void postDelayedTask(const WebTraceLocation&, Task*, long long) 73 virtual void postDelayedTask(const WebTraceLocation&, Task*, long long)
160 { 74 {
161 ASSERT_NOT_REACHED(); 75 ASSERT_NOT_REACHED();
162 } 76 }
163 77
164 virtual bool isCurrentThread() const 78 virtual bool isCurrentThread() const
165 { 79 {
166 ASSERT_NOT_REACHED(); 80 ASSERT_NOT_REACHED();
167 return true; 81 return true;
168 } 82 }
169 83
170 virtual PlatformThreadId threadId() const 84 virtual PlatformThreadId threadId() const
171 { 85 {
172 ASSERT_NOT_REACHED(); 86 ASSERT_NOT_REACHED();
173 return 0; 87 return 0;
174 } 88 }
175 89
176 WebScheduler* scheduler() const override 90 WebScheduler* scheduler() const override
177 { 91 {
178 return m_webScheduler.get(); 92 return m_webScheduler;
179 } 93 }
180 94
181 virtual void enterRunLoop() 95 virtual void enterRunLoop()
182 { 96 {
183 ASSERT_NOT_REACHED(); 97 ASSERT_NOT_REACHED();
184 } 98 }
185 99
186 virtual void exitRunLoop() 100 virtual void exitRunLoop()
187 { 101 {
188 ASSERT_NOT_REACHED(); 102 ASSERT_NOT_REACHED();
189 } 103 }
190 104
191 private: 105 private:
192 OwnPtr<MockWebScheduler> m_webScheduler; 106 WebScheduler* m_webScheduler;
193 }; 107 };
194 108
195 class TimerTestPlatform : public Platform { 109 class TimerTestPlatform : public Platform {
196 public: 110 public:
197 TimerTestPlatform() 111 explicit TimerTestPlatform(WebThread* webThread)
198 : m_webThread(adoptPtr(new FakeWebThread())) { } 112 : m_webThread(webThread)
113 , m_timerInterval(-1) { }
199 ~TimerTestPlatform() override { } 114 ~TimerTestPlatform() override { }
200 115
201 WebThread* currentThread() override 116 WebThread* currentThread() override
202 { 117 {
203 return m_webThread.get(); 118 return m_webThread;
204 } 119 }
205 120
206 void cryptographicallyRandomValues(unsigned char*, size_t) override 121 void cryptographicallyRandomValues(unsigned char*, size_t) override
207 { 122 {
208 ASSERT_NOT_REACHED(); 123 ASSERT_NOT_REACHED();
209 } 124 }
210 125
211 const unsigned char* getTraceCategoryEnabledFlag(const char* categoryName) o verride 126 const unsigned char* getTraceCategoryEnabledFlag(const char* categoryName) o verride
212 { 127 {
213 static const unsigned char enabled[] = {0}; 128 static const unsigned char enabled[] = {0};
214 return enabled; 129 return enabled;
215 } 130 }
216 131
132 void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) override
133 {
134 s_timerFunction = timerFunction;
135 }
136
137 void setSharedTimerFireInterval(double interval) override
138 {
139 m_timerInterval = interval;
140 }
141
142 virtual void stopSharedTimer() override
143 {
144 m_timerInterval = -1;
145 }
146
217 void runUntilIdle() 147 void runUntilIdle()
218 { 148 {
219 mockScheduler()->runUntilIdle(); 149 while (hasOneTimerTask()) {
150 gCurrentTimeSecs += m_timerInterval;
151 s_timerFunction();
152 }
220 } 153 }
221 154
222 void runUntilIdleOrDeadlinePassed(double deadline) 155 void runUntilIdleOrDeadlinePassed(double deadline)
223 { 156 {
224 mockScheduler()->runUntilIdleOrDeadlinePassed(deadline); 157 while (hasOneTimerTask()) {
158 double newTime = gCurrentTimeSecs + m_timerInterval;
159 if (newTime >= deadline) {
160 gCurrentTimeSecs = deadline;
161 break;
162 }
163 gCurrentTimeSecs = newTime;
164 s_timerFunction();
165 }
225 } 166 }
226 167
227 bool hasOneTimerTask() const 168 bool hasOneTimerTask() const
228 { 169 {
229 return mockScheduler()->hasOneTimerTask(); 170 return s_timerFunction && m_timerInterval >= 0;
230 } 171 }
231 172
232 long nextTimerTaskDelayMillis() const 173 long nextTimerTaskDelayMillis() const
233 { 174 {
234 return mockScheduler()->nextTimerTaskDelayMillis(); 175 ASSERT(hasOneTimerTask());
176 return static_cast<long>(m_timerInterval * 1000);
235 } 177 }
236 178
237 private: 179 private:
238 MockWebScheduler* mockScheduler() const 180 WebThread* m_webThread;
239 { 181 double m_timerInterval;
240 return static_cast<MockWebScheduler*>(m_webThread->scheduler());
241 }
242 182
243 OwnPtr<FakeWebThread> m_webThread; 183 // This needs to be static because the callback is registered only once by
184 // PlatformThreadData.
185 static SharedTimerFunction s_timerFunction;
244 }; 186 };
245 187
188 Platform::SharedTimerFunction TimerTestPlatform::s_timerFunction;
189
246 class TimerTest : public testing::Test { 190 class TimerTest : public testing::Test {
247 public: 191 public:
248 void SetUp() override 192 void SetUp() override
249 { 193 {
250 m_platform = adoptPtr(new TimerTestPlatform()); 194 m_mockWebScheduler = adoptPtr(new MockWebScheduler());
195 m_fakeWebThread = adoptPtr(new FakeWebThread(m_mockWebScheduler.get()));
196 m_platform = adoptPtr(new TimerTestPlatform(m_fakeWebThread.get()));
251 m_oldPlatform = Platform::current(); 197 m_oldPlatform = Platform::current();
252 Platform::initialize(m_platform.get()); 198 Platform::initialize(m_platform.get());
253 WTF::setMonotonicallyIncreasingTimeFunction(currentTime); 199 WTF::setMonotonicallyIncreasingTimeFunction(currentTime);
254 200
255 m_runTimes.clear(); 201 m_runTimes.clear();
256 gCurrentTimeSecs = 10.0; 202 gCurrentTimeSecs = 10.0;
257 m_startTime = gCurrentTimeSecs; 203 m_startTime = gCurrentTimeSecs;
258 } 204 }
259 205
260 void TearDown() override 206 void TearDown() override
(...skipping 29 matching lines...) Expand all
290 long nextTimerTaskDelayMillis() const 236 long nextTimerTaskDelayMillis() const
291 { 237 {
292 return m_platform->nextTimerTaskDelayMillis(); 238 return m_platform->nextTimerTaskDelayMillis();
293 } 239 }
294 240
295 protected: 241 protected:
296 double m_startTime; 242 double m_startTime;
297 std::vector<double> m_runTimes; 243 std::vector<double> m_runTimes;
298 244
299 private: 245 private:
246 OwnPtr<MockWebScheduler> m_mockWebScheduler;
247 OwnPtr<FakeWebThread> m_fakeWebThread;
300 OwnPtr<TimerTestPlatform> m_platform; 248 OwnPtr<TimerTestPlatform> m_platform;
301 Platform* m_oldPlatform; 249 Platform* m_oldPlatform;
302 }; 250 };
303 251
304 TEST_F(TimerTest, StartOneShot_Zero) 252 TEST_F(TimerTest, StartOneShot_Zero)
305 { 253 {
306 Timer<TimerTest> timer(this, &TimerTest::countingTask); 254 Timer<TimerTest> timer(this, &TimerTest::countingTask);
307 timer.startOneShot(0, FROM_HERE); 255 timer.startOneShot(0, FROM_HERE);
308 256
309 ASSERT(hasOneTimerTask()); 257 ASSERT(hasOneTimerTask());
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 MockTimerWithAlignment timer; 665 MockTimerWithAlignment timer;
718 timer.setAlignedFireTime(m_startTime + 1.0); 666 timer.setAlignedFireTime(m_startTime + 1.0);
719 667
720 timer.start(0.0, 0.0, FROM_HERE); 668 timer.start(0.0, 0.0, FROM_HERE);
721 669
722 EXPECT_FLOAT_EQ(1.0, timer.nextFireInterval()); 670 EXPECT_FLOAT_EQ(1.0, timer.nextFireInterval());
723 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval()); 671 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval());
724 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); 672 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime());
725 673
726 timer.setAlignedFireTime(m_startTime); 674 timer.setAlignedFireTime(m_startTime);
727 timer.didChangeAlignmentInterval(monotonicallyIncreasingTime()); 675 timer.didChangeAlignmentInterval();
728 676
729 EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval()); 677 EXPECT_FLOAT_EQ(0.0, timer.nextFireInterval());
730 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval()); 678 EXPECT_FLOAT_EQ(0.0, timer.nextUnalignedFireInterval());
731 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime()); 679 EXPECT_FLOAT_EQ(m_startTime, timer.lastFireTime());
732 } 680 }
733 681
734 682
735 } // namespace 683 } // namespace
736 } // namespace blink 684 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/Timer.cpp ('k') | Source/platform/blink_platform.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698