OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/scheduler/Scheduler.h" | 6 #include "platform/scheduler/Scheduler.h" |
7 | 7 |
8 #include "platform/TestingPlatformSupport.h" | 8 #include "platform/TestingPlatformSupport.h" |
9 #include "platform/TraceLocation.h" | 9 #include "platform/TraceLocation.h" |
10 #include "public/platform/Platform.h" | 10 #include "public/platform/Platform.h" |
11 #include "public/platform/WebThread.h" | 11 #include "public/platform/WebThread.h" |
12 | 12 |
13 #include <gmock/gmock.h> | 13 #include <gmock/gmock.h> |
14 #include <gtest/gtest.h> | 14 #include <gtest/gtest.h> |
15 #include <string> | 15 #include <string> |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 using blink::Scheduler; | 18 using blink::Scheduler; |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 class SchedulerForTest : public blink::Scheduler { | |
23 public: | |
24 static void initializeOnMainThread() | |
25 { | |
26 s_sharedScheduler = new SchedulerForTest(); | |
27 } | |
28 | |
29 using Scheduler::Normal; | |
Sami
2014/09/11 11:32:18
Neat!
alexclarke
2014/09/11 11:52:05
Acknowledged.
| |
30 using Scheduler::CompositorPriority; | |
31 using Scheduler::enterSchedulerPolicy; | |
32 }; | |
33 | |
22 class TestMainThread : public blink::WebThread { | 34 class TestMainThread : public blink::WebThread { |
23 public: | 35 public: |
24 // blink::WebThread implementation. | 36 // blink::WebThread implementation. |
25 virtual void postTask(Task* task) OVERRIDE | 37 virtual void postTask(Task* task) OVERRIDE |
26 { | 38 { |
27 m_pendingTasks.append(adoptPtr(task)); | 39 m_pendingTasks.append(adoptPtr(task)); |
28 } | 40 } |
29 | 41 |
30 virtual void postDelayedTask(Task* task, long long delayMs) OVERRIDE | 42 virtual void postDelayedTask(Task* task, long long delayMs) OVERRIDE |
31 { | 43 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 }; | 81 }; |
70 | 82 |
71 class SchedulerTestingPlatformSupport : blink::TestingPlatformSupport { | 83 class SchedulerTestingPlatformSupport : blink::TestingPlatformSupport { |
72 public: | 84 public: |
73 SchedulerTestingPlatformSupport() | 85 SchedulerTestingPlatformSupport() |
74 : TestingPlatformSupport(TestingPlatformSupport::Config()) | 86 : TestingPlatformSupport(TestingPlatformSupport::Config()) |
75 , m_sharedTimerFunction(nullptr) | 87 , m_sharedTimerFunction(nullptr) |
76 , m_sharedTimerRunning(false) | 88 , m_sharedTimerRunning(false) |
77 , m_sharedTimerFireInterval(0) | 89 , m_sharedTimerFireInterval(0) |
78 { | 90 { |
91 WTF::setMonotonicallyIncreasingTimeFunction(getMonotonicTimeForTest); | |
Sami
2014/09/11 11:32:19
Drop the "get", it's cleaner :)
Do we actually ne
alexclarke
2014/09/11 11:52:05
Turns out we don't. Nice.
| |
92 } | |
93 | |
94 virtual ~SchedulerTestingPlatformSupport() | |
95 { | |
96 WTF::setMonotonicallyIncreasingTimeFunction(0); | |
79 } | 97 } |
80 | 98 |
81 // blink::Platform implementation. | 99 // blink::Platform implementation. |
82 virtual blink::WebThread* currentThread() OVERRIDE | 100 virtual blink::WebThread* currentThread() OVERRIDE |
83 { | 101 { |
84 return &m_mainThread; | 102 return &m_mainThread; |
85 } | 103 } |
86 | 104 |
87 virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) OVERRIDE | 105 virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) OVERRIDE |
88 { | 106 { |
89 m_sharedTimerFunction = timerFunction; | 107 m_sharedTimerFunction = timerFunction; |
90 } | 108 } |
91 | 109 |
110 virtual double monotonicallyIncreasingTime() OVERRIDE | |
111 { | |
112 return s_debugTime; | |
Sami
2014/09/11 11:32:18
nit: also call this s_monotonicallyIncreasingTime.
alexclarke
2014/09/11 11:52:05
Done.
| |
113 } | |
114 | |
92 virtual void setSharedTimerFireInterval(double) | 115 virtual void setSharedTimerFireInterval(double) |
93 { | 116 { |
94 m_sharedTimerFireInterval = 0; | 117 m_sharedTimerFireInterval = 0; |
95 m_sharedTimerRunning = true; | 118 m_sharedTimerRunning = true; |
96 } | 119 } |
97 | 120 |
98 virtual void stopSharedTimer() | 121 virtual void stopSharedTimer() |
99 { | 122 { |
100 m_sharedTimerRunning = false; | 123 m_sharedTimerRunning = false; |
101 } | 124 } |
(...skipping 16 matching lines...) Expand all Loading... | |
118 void triggerSharedTimer() | 141 void triggerSharedTimer() |
119 { | 142 { |
120 m_sharedTimerFunction(); | 143 m_sharedTimerFunction(); |
121 } | 144 } |
122 | 145 |
123 size_t numPendingMainThreadTasks() const | 146 size_t numPendingMainThreadTasks() const |
124 { | 147 { |
125 return m_mainThread.numPendingMainThreadTasks(); | 148 return m_mainThread.numPendingMainThreadTasks(); |
126 } | 149 } |
127 | 150 |
151 static void setDebugTime(double time) | |
Sami
2014/09/11 11:32:18
setMonotonicTimeForTest?
alexclarke
2014/09/11 11:52:05
Done.
| |
152 { | |
153 s_debugTime = time; | |
154 } | |
155 | |
128 private: | 156 private: |
157 static double getMonotonicTimeForTest(void) | |
158 { | |
159 return s_debugTime; | |
160 } | |
161 | |
129 TestMainThread m_mainThread; | 162 TestMainThread m_mainThread; |
130 SharedTimerFunction m_sharedTimerFunction; | 163 SharedTimerFunction m_sharedTimerFunction; |
131 bool m_sharedTimerRunning; | 164 bool m_sharedTimerRunning; |
132 double m_sharedTimerFireInterval; | 165 double m_sharedTimerFireInterval; |
166 | |
167 static double s_debugTime; | |
133 }; | 168 }; |
134 | 169 |
170 double SchedulerTestingPlatformSupport::s_debugTime = 0; | |
171 | |
135 class SchedulerTest : public testing::Test { | 172 class SchedulerTest : public testing::Test { |
136 public: | 173 public: |
137 SchedulerTest() | 174 SchedulerTest() |
138 : m_reentrantCount(0) | 175 : m_reentrantCount(0) |
139 , m_maxRecursion(4) | 176 , m_maxRecursion(4) |
140 { | 177 { |
141 Scheduler::initializeOnMainThread(); | 178 SchedulerForTest::initializeOnMainThread(); |
142 m_scheduler = Scheduler::shared(); | 179 m_scheduler = static_cast<SchedulerForTest*>(Scheduler::shared()); |
143 } | 180 } |
144 | 181 |
145 ~SchedulerTest() | 182 ~SchedulerTest() |
146 { | 183 { |
147 Scheduler::shutdown(); | 184 Scheduler::shutdown(); |
148 } | 185 } |
149 | 186 |
150 void runPendingTasks() | 187 void runPendingTasks() |
151 { | 188 { |
152 m_platformSupport.runPendingTasks(); | 189 m_platformSupport.runPendingTasks(); |
(...skipping 26 matching lines...) Expand all Loading... | |
179 { | 216 { |
180 m_reentrantOrder.push_back(m_reentrantCount++); | 217 m_reentrantOrder.push_back(m_reentrantCount++); |
181 | 218 |
182 if (m_reentrantCount > m_maxRecursion) | 219 if (m_reentrantCount > m_maxRecursion) |
183 return; | 220 return; |
184 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::app endToVectorReentrantCompositorTask, this)); | 221 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::app endToVectorReentrantCompositorTask, this)); |
185 } | 222 } |
186 | 223 |
187 protected: | 224 protected: |
188 SchedulerTestingPlatformSupport m_platformSupport; | 225 SchedulerTestingPlatformSupport m_platformSupport; |
189 Scheduler* m_scheduler; | 226 SchedulerForTest* m_scheduler; |
190 std::vector<std::string> m_order; | 227 std::vector<std::string> m_order; |
191 std::vector<int> m_reentrantOrder; | 228 std::vector<int> m_reentrantOrder; |
192 int m_reentrantCount; | 229 int m_reentrantCount; |
193 int m_maxRecursion; | 230 int m_maxRecursion; |
194 }; | 231 }; |
195 | 232 |
196 void orderedTestTask(int value, int* result) | 233 void orderedTestTask(int value, int* result) |
197 { | 234 { |
198 *result = (*result << 4) | value; | 235 *result = (*result << 4) | value; |
199 } | 236 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 // TODO: Check task allottedTime when implemented in the scheduler. | 296 // TODO: Check task allottedTime when implemented in the scheduler. |
260 int result = 0; | 297 int result = 0; |
261 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); | 298 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); |
262 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); | 299 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); |
263 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); | 300 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); |
264 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); | 301 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); |
265 runPendingTasks(); | 302 runPendingTasks(); |
266 EXPECT_EQ(4, result); | 303 EXPECT_EQ(4, result); |
267 } | 304 } |
268 | 305 |
269 TEST_F(SchedulerTest, TestTaskPrioritization) | 306 TEST_F(SchedulerTest, TestTaskPrioritization_normalPolicy) |
270 { | 307 { |
308 m_scheduler->enterSchedulerPolicy(SchedulerForTest::Normal); | |
Sami
2014/09/11 11:32:18
Instead of doing this in every test, let's add a s
alexclarke
2014/09/11 11:52:05
Done.
| |
271 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L1"))); | 309 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L1"))); |
272 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L2"))); | 310 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L2"))); |
273 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I1"))); | 311 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I1"))); |
312 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C1"))); | |
313 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I2"))); | |
314 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C2"))); | |
315 | |
316 runPendingTasks(); | |
317 EXPECT_THAT(m_order, testing::ElementsAre( | |
318 std::string("L1"), std::string("L2"), std::string("I1"), std::string("C1 "), std::string("I2"), std::string("C2"))); | |
319 } | |
320 | |
321 TEST_F(SchedulerTest, TestTaskPrioritization_compositorPriorityPolicy) | |
322 { | |
323 m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); | |
324 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L1"))); | |
325 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L2"))); | |
326 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I1"))); | |
274 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C1"))); | 327 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C1"))); |
275 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I2"))); | 328 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I2"))); |
276 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C2"))); | 329 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C2"))); |
277 | 330 |
278 runPendingTasks(); | 331 runPendingTasks(); |
279 EXPECT_THAT(m_order, testing::ElementsAre( | 332 EXPECT_THAT(m_order, testing::ElementsAre( |
280 std::string("I1"), std::string("C1"), std::string("I2"), std::string("C2 "), std::string("L1"), std::string("L2"))); | 333 std::string("I1"), std::string("C1"), std::string("I2"), std::string("C2 "), std::string("L1"), std::string("L2"))); |
281 } | 334 } |
282 | 335 |
283 TEST_F(SchedulerTest, TestRentrantTask) | 336 TEST_F(SchedulerTest, TestRentrantTask) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 | 429 |
377 runPendingTasks(); | 430 runPendingTasks(); |
378 EXPECT_EQ(0U, m_platformSupport.numPendingMainThreadTasks()); | 431 EXPECT_EQ(0U, m_platformSupport.numPendingMainThreadTasks()); |
379 } | 432 } |
380 | 433 |
381 void postDummyInputTask() | 434 void postDummyInputTask() |
382 { | 435 { |
383 Scheduler::shared()->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); | 436 Scheduler::shared()->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); |
384 } | 437 } |
385 | 438 |
386 TEST_F(SchedulerTest, HighPriorityTasksOnlyRunOncePerSharedTimerFiring) | 439 TEST_F(SchedulerTest, HighPriorityTasksOnlyDontRunBecasueOfSharedTimerFiring_InN ormalMode) |
Sami
2014/09/11 11:32:18
s/Becasue/Because/
alexclarke
2014/09/11 11:52:05
Done.
| |
387 { | 440 { |
388 s_dummyTaskCount = 0; | 441 s_dummyTaskCount = 0; |
442 m_scheduler->enterSchedulerPolicy(SchedulerForTest::Normal); | |
389 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); | 443 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); |
390 // Trigger the posting of an input task during execution of the shared timer function. | 444 // Trigger the posting of an input task during execution of the shared timer function. |
391 m_scheduler->setSharedTimerFiredFunction(&postDummyInputTask); | 445 m_scheduler->setSharedTimerFiredFunction(&postDummyInputTask); |
446 m_scheduler->setSharedTimerFireInterval(0); | |
447 m_platformSupport.triggerSharedTimer(); | |
448 | |
449 EXPECT_EQ(0, s_dummyTaskCount); | |
450 | |
451 // Clean up. | |
452 m_scheduler->stopSharedTimer(); | |
453 m_scheduler->setSharedTimerFiredFunction(nullptr); | |
454 } | |
455 | |
456 TEST_F(SchedulerTest, HighPriorityTasksOnlyRunOncePerSharedTimerFiring_InLowSche dulerPolicy) | |
457 { | |
458 s_dummyTaskCount = 0; | |
459 m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); | |
460 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); | |
461 // Trigger the posting of an input task during execution of the shared timer function. | |
462 m_scheduler->setSharedTimerFiredFunction(&postDummyInputTask); | |
392 m_scheduler->setSharedTimerFireInterval(0); | 463 m_scheduler->setSharedTimerFireInterval(0); |
393 m_platformSupport.triggerSharedTimer(); | 464 m_platformSupport.triggerSharedTimer(); |
394 | 465 |
395 EXPECT_EQ(1, s_dummyTaskCount); | 466 EXPECT_EQ(1, s_dummyTaskCount); |
396 | 467 |
397 // Clean up. | 468 // Clean up. |
398 m_scheduler->stopSharedTimer(); | 469 m_scheduler->stopSharedTimer(); |
399 m_scheduler->setSharedTimerFiredFunction(nullptr); | 470 m_scheduler->setSharedTimerFiredFunction(nullptr); |
400 } | 471 } |
401 | 472 |
473 TEST_F(SchedulerTest, TestInputEventDoesNotTriggerShouldYield_InNormalMode) | |
474 { | |
475 m_scheduler->enterSchedulerPolicy(SchedulerForTest::Normal); | |
476 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); | |
477 | |
478 EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); | |
479 } | |
480 | |
481 TEST_F(SchedulerTest, TestCompositorEventDoesNotTriggerShouldYield_InNormalMode) | |
482 { | |
483 m_scheduler->enterSchedulerPolicy(SchedulerForTest::Normal); | |
484 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask)); | |
485 | |
486 EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); | |
487 } | |
488 | |
489 TEST_F(SchedulerTest, TestInputEventDoesTriggerShouldYield_InLowSchedulerPolicy) | |
490 { | |
491 m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); | |
492 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); | |
493 | |
494 EXPECT_TRUE(m_scheduler->shouldYieldForHighPriorityWork()); | |
495 } | |
496 | |
497 TEST_F(SchedulerTest, TestCompositorEventDoesTriggerShouldYield_InLowSchedulerPo licy) | |
498 { | |
499 m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); | |
500 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask)); | |
501 | |
502 EXPECT_TRUE(m_scheduler->shouldYieldForHighPriorityWork()); | |
503 } | |
504 | |
505 TEST_F(SchedulerTest, TestCompositorEvent_LowSchedulerPolicyDoesntLastLong) | |
506 { | |
507 SchedulerTestingPlatformSupport::setDebugTime(1000.0); | |
508 | |
509 m_scheduler->enterSchedulerPolicy(SchedulerForTest::CompositorPriority); | |
510 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&dummyTask)); | |
511 SchedulerTestingPlatformSupport::setDebugTime(1000.5); | |
512 runPendingTasks(); | |
513 | |
514 ASSERT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); | |
515 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&dummyTask)); | |
516 | |
517 EXPECT_FALSE(m_scheduler->shouldYieldForHighPriorityWork()); | |
518 } | |
519 | |
402 } // namespace | 520 } // namespace |
OLD | NEW |