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

Side by Side Diff: Source/platform/scheduler/SchedulerTest.cpp

Issue 540373002: Add support for Low Priorirty tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Maybe fix linker issue Created 6 years, 3 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
OLDNEW
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/WebBeginFrameArgs.h"
11 #include "public/platform/WebThread.h" 12 #include "public/platform/WebThread.h"
13 #include "wtf/CurrentTime.h"
12 14
13 #include <gmock/gmock.h> 15 #include <gmock/gmock.h>
14 #include <gtest/gtest.h> 16 #include <gtest/gtest.h>
17 #include <queue>
15 #include <string> 18 #include <string>
16 #include <vector> 19 #include <vector>
17 20
21 using blink::Platform;
18 using blink::Scheduler; 22 using blink::Scheduler;
19 23
20 namespace { 24 namespace {
21 25
22 class TestMainThread : public blink::WebThread { 26 class TestMainThread : public blink::WebThread {
23 public: 27 public:
24 // blink::WebThread implementation. 28 // blink::WebThread implementation.
25 virtual void postTask(Task* task) OVERRIDE 29 virtual void postTask(Task* task) OVERRIDE
26 { 30 {
27 m_pendingTasks.append(adoptPtr(task)); 31 m_pendingTasks.append(adoptPtr(task));
28 } 32 }
29 33
30 virtual void postDelayedTask(Task* task, long long delayMs) OVERRIDE 34 virtual void postDelayedTask(Task* task, long long delayMs) OVERRIDE
31 { 35 {
32 ASSERT_NOT_REACHED(); 36 long long deadline = static_cast<long long>(Platform::current()->monoton icallyIncreasingTime() * 1000.0) + delayMs;
37 m_pendingDelayedTasks.push(DelayedTask(deadline, adoptPtr(task)));
33 } 38 }
34 39
35 virtual bool isCurrentThread() const OVERRIDE 40 virtual bool isCurrentThread() const OVERRIDE
36 { 41 {
37 return true; 42 return true;
38 } 43 }
39 44
40 virtual void enterRunLoop() OVERRIDE 45 virtual void enterRunLoop() OVERRIDE
41 { 46 {
42 ASSERT_NOT_REACHED(); 47 ASSERT_NOT_REACHED();
43 } 48 }
44 49
45 virtual void exitRunLoop() OVERRIDE 50 virtual void exitRunLoop() OVERRIDE
46 { 51 {
47 ASSERT_NOT_REACHED(); 52 ASSERT_NOT_REACHED();
48 } 53 }
49 54
50 void runPendingTasks() 55 void runPendingTasks()
51 { 56 {
52 while (!m_pendingTasks.isEmpty()) 57 while (!m_pendingTasks.isEmpty())
53 m_pendingTasks.takeFirst()->run(); 58 m_pendingTasks.takeFirst()->run();
59
60 long long timeMs = static_cast<long long>(Platform::current()->monotonic allyIncreasingTime() * 1000.0);
61 while (!m_pendingDelayedTasks.empty() && m_pendingDelayedTasks.top().m_d eadline <= timeMs) {
62 m_pendingDelayedTasks.top().run();
63 m_pendingDelayedTasks.pop();
64 }
54 } 65 }
55 66
56 size_t numPendingMainThreadTasks() const 67 size_t numPendingMainThreadTasks() const
57 { 68 {
58 return m_pendingTasks.size(); 69 return m_pendingTasks.size();
59 } 70 }
60 71
72 double nextDelayedTaskDeadlineOrMinusOne() const
73 {
74 if (m_pendingDelayedTasks.empty())
75 return -1;
76
77 return static_cast<double>(m_pendingDelayedTasks.top().m_deadline) * 0.0 01;
78 }
79
61 private: 80 private:
81 class DelayedTask {
82 public:
83 DelayedTask(long long deadline, PassOwnPtr<WebThread::Task> task)
84 : m_deadline(deadline)
85 , m_task(task.leakPtr())
86 {
87 }
88
89 void run() const
90 {
91 m_task->run();
92 delete m_task;
93 }
94
95 bool operator<(const DelayedTask& other) const
96 {
97 return m_deadline > other.m_deadline;
98 }
99
100 long long m_deadline;
101
102 // NOTE we can't use OwnPtr<> here because the std::priority_queue uses the copy constructor
103 // and c++11 style move semantics are not allowed yet.
104 WebThread::Task* m_task;
105 };
106
62 WTF::Deque<OwnPtr<Task> > m_pendingTasks; 107 WTF::Deque<OwnPtr<Task> > m_pendingTasks;
108 std::priority_queue<DelayedTask> m_pendingDelayedTasks;
63 }; 109 };
64 110
65 class SchedulerTestingPlatformSupport : blink::TestingPlatformSupport { 111 class SchedulerTestingPlatformSupport : blink::TestingPlatformSupport {
66 public: 112 public:
67 SchedulerTestingPlatformSupport() 113 SchedulerTestingPlatformSupport()
68 : TestingPlatformSupport(TestingPlatformSupport::Config()) 114 : TestingPlatformSupport(TestingPlatformSupport::Config())
69 , m_sharedTimerFunction(nullptr) 115 , m_sharedTimerFunction(nullptr)
70 , m_sharedTimerRunning(false) 116 , m_sharedTimerRunning(false)
71 , m_sharedTimerFireInterval(0) 117 , m_sharedTimerFireInterval(0)
72 { 118 {
119 WTF::setMonotonicallyIncreasingTimeFunction(getDebugTime);
120 }
121
122 virtual ~SchedulerTestingPlatformSupport()
123 {
124 WTF::setMonotonicallyIncreasingTimeFunction(0);
73 } 125 }
74 126
75 // blink::Platform implementation. 127 // blink::Platform implementation.
76 virtual blink::WebThread* currentThread() OVERRIDE 128 virtual blink::WebThread* currentThread() OVERRIDE
77 { 129 {
78 return &m_mainThread; 130 return &m_mainThread;
79 } 131 }
80 132
81 virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) OVERRIDE 133 virtual void setSharedTimerFiredFunction(SharedTimerFunction timerFunction) OVERRIDE
82 { 134 {
83 m_sharedTimerFunction = timerFunction; 135 m_sharedTimerFunction = timerFunction;
84 } 136 }
85 137
138 virtual double monotonicallyIncreasingTime() OVERRIDE
139 {
140 return s_debugTime;
141 }
142
86 virtual void setSharedTimerFireInterval(double) 143 virtual void setSharedTimerFireInterval(double)
87 { 144 {
88 m_sharedTimerFireInterval = 0; 145 m_sharedTimerFireInterval = 0;
89 m_sharedTimerRunning = true; 146 m_sharedTimerRunning = true;
90 } 147 }
91 148
92 virtual void stopSharedTimer() 149 virtual void stopSharedTimer()
93 { 150 {
94 m_sharedTimerRunning = false; 151 m_sharedTimerRunning = false;
95 } 152 }
(...skipping 16 matching lines...) Expand all
112 void triggerSharedTimer() 169 void triggerSharedTimer()
113 { 170 {
114 m_sharedTimerFunction(); 171 m_sharedTimerFunction();
115 } 172 }
116 173
117 size_t numPendingMainThreadTasks() const 174 size_t numPendingMainThreadTasks() const
118 { 175 {
119 return m_mainThread.numPendingMainThreadTasks(); 176 return m_mainThread.numPendingMainThreadTasks();
120 } 177 }
121 178
179 double nextDelayedTaskDeadlineOrMinusOne() const
180 {
181 return m_mainThread.nextDelayedTaskDeadlineOrMinusOne();
182 }
183
184 static void setDebugTime(double time)
185 {
186 s_debugTime = time;
187 }
188
122 private: 189 private:
190 static double getDebugTime(void)
191 {
192 return s_debugTime;
193 }
123 TestMainThread m_mainThread; 194 TestMainThread m_mainThread;
124 SharedTimerFunction m_sharedTimerFunction; 195 SharedTimerFunction m_sharedTimerFunction;
125 bool m_sharedTimerRunning; 196 bool m_sharedTimerRunning;
126 double m_sharedTimerFireInterval; 197 double m_sharedTimerFireInterval;
198
199 static double s_debugTime;
127 }; 200 };
128 201
202 double SchedulerTestingPlatformSupport::s_debugTime = 0;
203
129 class SchedulerTest : public testing::Test { 204 class SchedulerTest : public testing::Test {
130 public: 205 public:
131 SchedulerTest() 206 SchedulerTest()
132 : m_reentrantCount(0) 207 : m_reentrantCount(0)
133 , m_maxRecursion(4) 208 , m_maxRecursion(4)
134 { 209 {
135 Scheduler::initializeOnMainThread(); 210 Scheduler::initializeOnMainThread();
136 m_scheduler = Scheduler::shared(); 211 m_scheduler = Scheduler::shared();
137 } 212 }
138 213
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 1, &result)); 283 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 1, &result));
209 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 2, &result)); 284 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 2, &result));
210 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 3, &result)); 285 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 3, &result));
211 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 4, &result)); 286 m_scheduler->postTask(FROM_HERE, WTF::bind(&orderedTestTask, 4, &result));
212 runPendingTasks(); 287 runPendingTasks();
213 EXPECT_EQ(0x1234, result); 288 EXPECT_EQ(0x1234, result);
214 } 289 }
215 290
216 TEST_F(SchedulerTest, TestPostMixedTaskTypes) 291 TEST_F(SchedulerTest, TestPostMixedTaskTypes)
217 { 292 {
293 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
218 int result = 0; 294 int result = 0;
219 m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 1, &result)); 295 m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 1, &result));
220 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&unorderedTestTask, 2, &resu lt)); 296 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&unorderedTestTask, 2, &resu lt));
221 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&unorderedTestTask, 4, &result)); 297 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&unorderedTestTask, 4, &result));
222 m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 8, &result)); 298 m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 8, &result));
299 m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&unorderedTestTask, 16, &resul t));
300 SchedulerTestingPlatformSupport::setDebugTime(1001.0);
223 runPendingTasks(); 301 runPendingTasks();
224 EXPECT_EQ(15, result); 302 EXPECT_EQ(31, result);
225 } 303 }
226 304
227 int s_sharedTimerTickCount; 305 int s_sharedTimerTickCount;
228 void sharedTimerFunction() 306 void sharedTimerFunction()
229 { 307 {
230 s_sharedTimerTickCount++; 308 s_sharedTimerTickCount++;
231 } 309 }
232 310
233 TEST_F(SchedulerTest, TestSharedTimer) 311 TEST_F(SchedulerTest, TestSharedTimer)
234 { 312 {
(...skipping 20 matching lines...) Expand all
255 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); 333 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult));
256 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); 334 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult));
257 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); 335 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult));
258 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult)); 336 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&idleTestTask, 1, &re sult));
259 runPendingTasks(); 337 runPendingTasks();
260 EXPECT_EQ(4, result); 338 EXPECT_EQ(4, result);
261 } 339 }
262 340
263 TEST_F(SchedulerTest, TestTaskPrioritization) 341 TEST_F(SchedulerTest, TestTaskPrioritization)
264 { 342 {
343 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
344 m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector , this, std::string("IPC1")));
345 m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector , this, std::string("IPC2")));
265 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L1"))); 346 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L1")));
266 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L2"))); 347 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, t his, std::string("L2")));
267 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I1"))); 348 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I1")));
268 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C1"))); 349 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C1")));
269 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I2"))); 350 m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVect or, this, std::string("I2")));
270 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C2"))); 351 m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendT oVector, this, std::string("C2")));
352 SchedulerTestingPlatformSupport::setDebugTime(1001.0);
271 353
272 runPendingTasks(); 354 runPendingTasks();
273 EXPECT_THAT(m_order, testing::ElementsAre( 355 EXPECT_THAT(m_order, testing::ElementsAre(
274 std::string("I1"), std::string("C1"), std::string("I2"), std::string("C2 "), std::string("L1"), std::string("L2"))); 356 std::string("I1"), std::string("C1"), std::string("I2"), std::string("C2 "), std::string("L1"), std::string("L2"),
357 std::string("IPC1"), std::string("IPC2")));
275 } 358 }
276 359
277 TEST_F(SchedulerTest, TestRentrantTask) 360 TEST_F(SchedulerTest, TestRentrantTask)
278 { 361 {
279 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorRee ntrantTask, this)); 362 m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVectorRee ntrantTask, this));
280 runPendingTasks(); 363 runPendingTasks();
281 364
282 EXPECT_THAT(m_reentrantOrder, testing::ElementsAre(0, 1, 2, 3, 4)); 365 EXPECT_THAT(m_reentrantOrder, testing::ElementsAre(0, 1, 2, 3, 4));
283 } 366 }
284 367
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 m_scheduler->setSharedTimerFireInterval(0); 469 m_scheduler->setSharedTimerFireInterval(0);
387 m_platformSupport.triggerSharedTimer(); 470 m_platformSupport.triggerSharedTimer();
388 471
389 EXPECT_EQ(1, s_dummyTaskCount); 472 EXPECT_EQ(1, s_dummyTaskCount);
390 473
391 // Clean up. 474 // Clean up.
392 m_scheduler->stopSharedTimer(); 475 m_scheduler->stopSharedTimer();
393 m_scheduler->setSharedTimerFiredFunction(nullptr); 476 m_scheduler->setSharedTimerFiredFunction(nullptr);
394 } 477 }
395 478
479 TEST_F(SchedulerTest, TestNextPredictedCompositorStart_initialState)
480 {
481 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
482 EXPECT_EQ(0, m_scheduler->nextPredictedCompositorStart());
483 }
484
485 TEST_F(SchedulerTest, TestNextPredictedCompositorDeadline_initialState)
486 {
487 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
488 EXPECT_EQ(0, m_scheduler->nextPredictedCompositorDeadline());
489 }
490
491 TEST_F(SchedulerTest, TestNextPredictedCompositorStart_afterWillBeginFrame)
492 {
493 m_scheduler->willBeginFrame(blink::WebBeginFrameArgs(999.8, 999.9, 0.2));
494
495 // NOTE nextPredictedCompositorStart attempts to return a time in the future .
496 SchedulerTestingPlatformSupport::setDebugTime(999.999);
497 EXPECT_DOUBLE_EQ(1000.0, m_scheduler->nextPredictedCompositorStart());
498
499 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
500 EXPECT_DOUBLE_EQ(1000.2, m_scheduler->nextPredictedCompositorStart());
501 }
502
503 TEST_F(SchedulerTest, TestNextPredictedCompositorDeadline_afterWillBeginFrame)
504 {
505 m_scheduler->willBeginFrame(blink::WebBeginFrameArgs(999.8, 999.9, 0.2));
506
507 // NOTE nextPredictedCompositorStart attempts to return a time in the future .
508 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
509 EXPECT_DOUBLE_EQ(1000.1, m_scheduler->nextPredictedCompositorDeadline());
510
511 SchedulerTestingPlatformSupport::setDebugTime(1000.2);
512 EXPECT_DOUBLE_EQ(1000.3, m_scheduler->nextPredictedCompositorDeadline());
513 }
514
515 TEST_F(SchedulerTest, TestLowPriorityTasksPostedAtNextComposiorDeadline)
516 {
517 m_scheduler->willBeginFrame(blink::WebBeginFrameArgs(999.8, 999.9, 0.2));
518 SchedulerTestingPlatformSupport::setDebugTime(1000.0);
519
520 m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&dummyTask));
521 EXPECT_DOUBLE_EQ(1000.1, m_platformSupport.nextDelayedTaskDeadlineOrMinusOne ());
522 }
523
396 } // namespace 524 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698