| Index: Source/platform/scheduler/SchedulerTest.cpp
|
| diff --git a/Source/platform/scheduler/SchedulerTest.cpp b/Source/platform/scheduler/SchedulerTest.cpp
|
| index 557e0386c2b070ffab155b9a6b0ebbdb7b79e976..95057dc6cbf6ed72040226d449f805de6982d353 100644
|
| --- a/Source/platform/scheduler/SchedulerTest.cpp
|
| +++ b/Source/platform/scheduler/SchedulerTest.cpp
|
| @@ -8,13 +8,17 @@
|
| #include "platform/TestingPlatformSupport.h"
|
| #include "platform/TraceLocation.h"
|
| #include "public/platform/Platform.h"
|
| +#include "public/platform/WebBeginFrameArgs.h"
|
| #include "public/platform/WebThread.h"
|
| +#include "wtf/CurrentTime.h"
|
|
|
| #include <gmock/gmock.h>
|
| #include <gtest/gtest.h>
|
| +#include <queue>
|
| #include <string>
|
| #include <vector>
|
|
|
| +using blink::Platform;
|
| using blink::Scheduler;
|
|
|
| namespace {
|
| @@ -29,7 +33,8 @@ public:
|
|
|
| virtual void postDelayedTask(Task* task, long long delayMs) OVERRIDE
|
| {
|
| - ASSERT_NOT_REACHED();
|
| + long long deadline = static_cast<long long>(Platform::current()->monotonicallyIncreasingTime() * 1000.0) + delayMs;
|
| + m_pendingDelayedTasks.push(DelayedTask(deadline, adoptPtr(task)));
|
| }
|
|
|
| virtual bool isCurrentThread() const OVERRIDE
|
| @@ -51,6 +56,12 @@ public:
|
| {
|
| while (!m_pendingTasks.isEmpty())
|
| m_pendingTasks.takeFirst()->run();
|
| +
|
| + long long timeMs = static_cast<long long>(Platform::current()->monotonicallyIncreasingTime() * 1000.0);
|
| + while (!m_pendingDelayedTasks.empty() && m_pendingDelayedTasks.top().m_deadline <= timeMs) {
|
| + m_pendingDelayedTasks.top().run();
|
| + m_pendingDelayedTasks.pop();
|
| + }
|
| }
|
|
|
| size_t numPendingMainThreadTasks() const
|
| @@ -58,8 +69,43 @@ public:
|
| return m_pendingTasks.size();
|
| }
|
|
|
| + double nextDelayedTaskDeadlineOrMinusOne() const
|
| + {
|
| + if (m_pendingDelayedTasks.empty())
|
| + return -1;
|
| +
|
| + return static_cast<double>(m_pendingDelayedTasks.top().m_deadline) * 0.001;
|
| + }
|
| +
|
| private:
|
| + class DelayedTask {
|
| + public:
|
| + DelayedTask(long long deadline, PassOwnPtr<WebThread::Task> task)
|
| + : m_deadline(deadline)
|
| + , m_task(task.leakPtr())
|
| + {
|
| + }
|
| +
|
| + void run() const
|
| + {
|
| + m_task->run();
|
| + delete m_task;
|
| + }
|
| +
|
| + bool operator<(const DelayedTask& other) const
|
| + {
|
| + return m_deadline > other.m_deadline;
|
| + }
|
| +
|
| + long long m_deadline;
|
| +
|
| + // NOTE we can't use OwnPtr<> here because the std::priority_queue uses the copy constructor
|
| + // and c++11 style move semantics are not allowed yet.
|
| + WebThread::Task* m_task;
|
| + };
|
| +
|
| WTF::Deque<OwnPtr<Task> > m_pendingTasks;
|
| + std::priority_queue<DelayedTask> m_pendingDelayedTasks;
|
| };
|
|
|
| class SchedulerTestingPlatformSupport : blink::TestingPlatformSupport {
|
| @@ -70,6 +116,12 @@ public:
|
| , m_sharedTimerRunning(false)
|
| , m_sharedTimerFireInterval(0)
|
| {
|
| + WTF::setMonotonicallyIncreasingTimeFunction(getDebugTime);
|
| + }
|
| +
|
| + virtual ~SchedulerTestingPlatformSupport()
|
| + {
|
| + WTF::setMonotonicallyIncreasingTimeFunction(0);
|
| }
|
|
|
| // blink::Platform implementation.
|
| @@ -83,6 +135,11 @@ public:
|
| m_sharedTimerFunction = timerFunction;
|
| }
|
|
|
| + virtual double monotonicallyIncreasingTime() OVERRIDE
|
| + {
|
| + return s_debugTime;
|
| + }
|
| +
|
| virtual void setSharedTimerFireInterval(double)
|
| {
|
| m_sharedTimerFireInterval = 0;
|
| @@ -119,13 +176,31 @@ public:
|
| return m_mainThread.numPendingMainThreadTasks();
|
| }
|
|
|
| + double nextDelayedTaskDeadlineOrMinusOne() const
|
| + {
|
| + return m_mainThread.nextDelayedTaskDeadlineOrMinusOne();
|
| + }
|
| +
|
| + static void setDebugTime(double time)
|
| + {
|
| + s_debugTime = time;
|
| + }
|
| +
|
| private:
|
| + static double getDebugTime(void)
|
| + {
|
| + return s_debugTime;
|
| + }
|
| TestMainThread m_mainThread;
|
| SharedTimerFunction m_sharedTimerFunction;
|
| bool m_sharedTimerRunning;
|
| double m_sharedTimerFireInterval;
|
| +
|
| + static double s_debugTime;
|
| };
|
|
|
| +double SchedulerTestingPlatformSupport::s_debugTime = 0;
|
| +
|
| class SchedulerTest : public testing::Test {
|
| public:
|
| SchedulerTest()
|
| @@ -215,13 +290,16 @@ TEST_F(SchedulerTest, TestPostTask)
|
|
|
| TEST_F(SchedulerTest, TestPostMixedTaskTypes)
|
| {
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| int result = 0;
|
| m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 1, &result));
|
| m_scheduler->postInputTask(FROM_HERE, WTF::bind(&unorderedTestTask, 2, &result));
|
| m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&unorderedTestTask, 4, &result));
|
| m_scheduler->postTask(FROM_HERE, WTF::bind(&unorderedTestTask, 8, &result));
|
| + m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&unorderedTestTask, 16, &result));
|
| + SchedulerTestingPlatformSupport::setDebugTime(1001.0);
|
| runPendingTasks();
|
| - EXPECT_EQ(15, result);
|
| + EXPECT_EQ(31, result);
|
| }
|
|
|
| int s_sharedTimerTickCount;
|
| @@ -262,16 +340,21 @@ TEST_F(SchedulerTest, TestIdleTask)
|
|
|
| TEST_F(SchedulerTest, TestTaskPrioritization)
|
| {
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| + m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("IPC1")));
|
| + m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("IPC2")));
|
| m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("L1")));
|
| m_scheduler->postTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("L2")));
|
| m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("I1")));
|
| m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("C1")));
|
| m_scheduler->postInputTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("I2")));
|
| m_scheduler->postCompositorTask(FROM_HERE, WTF::bind(&SchedulerTest::appendToVector, this, std::string("C2")));
|
| + SchedulerTestingPlatformSupport::setDebugTime(1001.0);
|
|
|
| runPendingTasks();
|
| EXPECT_THAT(m_order, testing::ElementsAre(
|
| - std::string("I1"), std::string("C1"), std::string("I2"), std::string("C2"), std::string("L1"), std::string("L2")));
|
| + std::string("I1"), std::string("C1"), std::string("I2"), std::string("C2"), std::string("L1"), std::string("L2"),
|
| + std::string("IPC1"), std::string("IPC2")));
|
| }
|
|
|
| TEST_F(SchedulerTest, TestRentrantTask)
|
| @@ -393,4 +476,49 @@ TEST_F(SchedulerTest, HighPriorityTasksOnlyRunOncePerSharedTimerFiring)
|
| m_scheduler->setSharedTimerFiredFunction(nullptr);
|
| }
|
|
|
| +TEST_F(SchedulerTest, TestNextPredictedCompositorStart_initialState)
|
| +{
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| + EXPECT_EQ(0, m_scheduler->nextPredictedCompositorStart());
|
| +}
|
| +
|
| +TEST_F(SchedulerTest, TestNextPredictedCompositorDeadline_initialState)
|
| +{
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| + EXPECT_EQ(0, m_scheduler->nextPredictedCompositorDeadline());
|
| +}
|
| +
|
| +TEST_F(SchedulerTest, TestNextPredictedCompositorStart_afterWillBeginFrame)
|
| +{
|
| + m_scheduler->willBeginFrame(blink::WebBeginFrameArgs(999.8, 999.9, 0.2));
|
| +
|
| + // NOTE nextPredictedCompositorStart attempts to return a time in the future.
|
| + SchedulerTestingPlatformSupport::setDebugTime(999.999);
|
| + EXPECT_DOUBLE_EQ(1000.0, m_scheduler->nextPredictedCompositorStart());
|
| +
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| + EXPECT_DOUBLE_EQ(1000.2, m_scheduler->nextPredictedCompositorStart());
|
| +}
|
| +
|
| +TEST_F(SchedulerTest, TestNextPredictedCompositorDeadline_afterWillBeginFrame)
|
| +{
|
| + m_scheduler->willBeginFrame(blink::WebBeginFrameArgs(999.8, 999.9, 0.2));
|
| +
|
| + // NOTE nextPredictedCompositorStart attempts to return a time in the future.
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| + EXPECT_DOUBLE_EQ(1000.1, m_scheduler->nextPredictedCompositorDeadline());
|
| +
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.2);
|
| + EXPECT_DOUBLE_EQ(1000.3, m_scheduler->nextPredictedCompositorDeadline());
|
| +}
|
| +
|
| +TEST_F(SchedulerTest, TestLowPriorityTasksPostedAtNextComposiorDeadline)
|
| +{
|
| + m_scheduler->willBeginFrame(blink::WebBeginFrameArgs(999.8, 999.9, 0.2));
|
| + SchedulerTestingPlatformSupport::setDebugTime(1000.0);
|
| +
|
| + m_scheduler->postIpcTask(FROM_HERE, WTF::bind(&dummyTask));
|
| + EXPECT_DOUBLE_EQ(1000.1, m_platformSupport.nextDelayedTaskDeadlineOrMinusOne());
|
| +}
|
| +
|
| } // namespace
|
|
|