| Index: Source/platform/scheduler/Scheduler.cpp
|
| diff --git a/Source/platform/scheduler/Scheduler.cpp b/Source/platform/scheduler/Scheduler.cpp
|
| index c88c4203a6a7e3c9ad6a36fb3f400e6ea1a7bcc0..cdccd336e573accf1c0ee961b4eac30e30490e19 100644
|
| --- a/Source/platform/scheduler/Scheduler.cpp
|
| +++ b/Source/platform/scheduler/Scheduler.cpp
|
| @@ -51,7 +51,9 @@ private:
|
| // Note if the scheduler gets shutdown, this may be run after.
|
| class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Task {
|
| public:
|
| - MainThreadPendingHighPriorityTaskRunner()
|
| + MainThreadPendingHighPriorityTaskRunner(
|
| + const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
|
| + : m_task(task, location, traceName)
|
| {
|
| ASSERT(Scheduler::shared());
|
| }
|
| @@ -59,17 +61,16 @@ public:
|
| // WebThread::Task implementation.
|
| virtual void run() OVERRIDE
|
| {
|
| - Scheduler* scheduler = Scheduler::shared();
|
| - // FIXME: This check should't be necessary, tasks should not outlive blink.
|
| - ASSERT(scheduler);
|
| - if (!scheduler)
|
| - return;
|
| - // NOTE we must unconditionally execute high priority tasks here, since if we're not in CompositorPriority
|
| - // mode, then this is the only place where high priority tasks will be executed.
|
| - scheduler->swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting();
|
| + m_task.run();
|
| + if (Scheduler* scheduler = Scheduler::shared()) {
|
| + scheduler->updatePolicy();
|
| + scheduler->didRunHighPriorityTask();
|
| + }
|
| }
|
| -};
|
|
|
| +private:
|
| + TracedTask m_task;
|
| +};
|
|
|
| // Can be created from any thread.
|
| // Note if the scheduler gets shutdown, this may be run after.
|
| @@ -85,12 +86,10 @@ public:
|
| // WebThread::Task implementation.
|
| virtual void run() OVERRIDE
|
| {
|
| - Scheduler* scheduler = Scheduler::shared();
|
| - // FIXME: This check should't be necessary, tasks should not outlive blink.
|
| - ASSERT(scheduler);
|
| - if (scheduler)
|
| - Scheduler::shared()->runPendingHighPriorityTasksIfInCompositorPriority();
|
| m_task.run();
|
| + if (Scheduler* scheduler = Scheduler::shared()) {
|
| + scheduler->updatePolicy();
|
| + }
|
| }
|
|
|
| TracedTask m_task;
|
| @@ -117,18 +116,15 @@ Scheduler* Scheduler::shared()
|
| Scheduler::Scheduler()
|
| : m_sharedTimerFunction(nullptr)
|
| , m_mainThread(blink::Platform::current()->currentThread())
|
| - , m_compositorPriorityPolicyEndTimeSeconds(0)
|
| , m_highPriorityTaskCount(0)
|
| , m_highPriorityTaskRunnerPosted(false)
|
| + , m_compositorPriorityPolicyEndTimeSeconds(0)
|
| , m_schedulerPolicy(Normal)
|
| {
|
| }
|
|
|
| Scheduler::~Scheduler()
|
| {
|
| - while (hasPendingHighPriorityWork()) {
|
| - swapQueuesAndRunPendingTasks();
|
| - }
|
| }
|
|
|
| void Scheduler::willBeginFrame(const WebBeginFrameArgs& args)
|
| @@ -149,11 +145,14 @@ void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask&
|
|
|
| void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, const Task& task, const char* traceName)
|
| {
|
| - Locker<Mutex> lock(m_pendingTasksMutex);
|
| -
|
| - m_pendingHighPriorityTasks.append(TracedTask(task, location, traceName));
|
| + m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner(task, location, traceName));
|
| atomicIncrement(&m_highPriorityTaskCount);
|
| - maybePostMainThreadPendingHighPriorityTaskRunner();
|
| + TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
|
| +}
|
| +
|
| +void Scheduler::didRunHighPriorityTask()
|
| +{
|
| + atomicDecrement(&m_highPriorityTaskCount);
|
| TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
|
| }
|
|
|
| @@ -184,15 +183,6 @@ void Scheduler::postIpcTask(const TraceLocation& location, const Task& task)
|
| m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Scheduler::IpcTask"));
|
| }
|
|
|
| -void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner()
|
| -{
|
| - ASSERT(m_pendingTasksMutex.locked());
|
| - if (m_highPriorityTaskRunnerPosted)
|
| - return;
|
| - m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner());
|
| - m_highPriorityTaskRunnerPosted = true;
|
| -}
|
| -
|
| void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idleTask)
|
| {
|
| scheduleIdleTask(location, idleTask);
|
| @@ -201,78 +191,19 @@ void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle
|
| void Scheduler::tickSharedTimer()
|
| {
|
| TRACE_EVENT0("blink", "Scheduler::tickSharedTimer");
|
| -
|
| - // Run any high priority tasks that are queued up, otherwise the blink timers will yield immediately.
|
| - bool workDone = runPendingHighPriorityTasksIfInCompositorPriority();
|
| m_sharedTimerFunction();
|
| -
|
| - // The blink timers may have just yielded, so run any high priority tasks that where queued up
|
| - // while the blink timers were executing.
|
| - if (!workDone)
|
| - runPendingHighPriorityTasksIfInCompositorPriority();
|
| -}
|
| -
|
| -bool Scheduler::runPendingHighPriorityTasksIfInCompositorPriority()
|
| -{
|
| - ASSERT(isMainThread());
|
| - if (schedulerPolicy() != CompositorPriority)
|
| - return false;
|
| -
|
| - return swapQueuesAndRunPendingTasks();
|
| -}
|
| -
|
| -bool Scheduler::swapQueuesAndRunPendingTasks()
|
| -{
|
| - ASSERT(isMainThread());
|
| -
|
| - // These locks guard against another thread posting input or compositor tasks while we swap the buffers.
|
| - // One the buffers have been swapped we can safely access the returned deque without having to lock.
|
| - m_pendingTasksMutex.lock();
|
| - Deque<TracedTask>& highPriorityTasks = m_pendingHighPriorityTasks.swapBuffers();
|
| - maybeEnterNormalSchedulerPolicy();
|
| - m_pendingTasksMutex.unlock();
|
| - return executeHighPriorityTasks(highPriorityTasks);
|
| }
|
|
|
| -void Scheduler::swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting()
|
| +void Scheduler::updatePolicy()
|
| {
|
| ASSERT(isMainThread());
|
| -
|
| - // These locks guard against another thread posting input or compositor tasks while we swap the buffers.
|
| - // One the buffers have been swapped we can safely access the returned deque without having to lock.
|
| - m_pendingTasksMutex.lock();
|
| - Deque<TracedTask>& highPriorityTasks = m_pendingHighPriorityTasks.swapBuffers();
|
| - m_highPriorityTaskRunnerPosted = false;
|
| - maybeEnterNormalSchedulerPolicy();
|
| - m_pendingTasksMutex.unlock();
|
| - executeHighPriorityTasks(highPriorityTasks);
|
| -}
|
| -
|
| -void Scheduler::maybeEnterNormalSchedulerPolicy()
|
| -{
|
| - ASSERT(isMainThread());
|
| - ASSERT(m_pendingTasksMutex.locked());
|
| + Locker<Mutex> lock(m_policyStateMutex);
|
|
|
| // Go back to the normal scheduler policy if enough time has elapsed.
|
| if (schedulerPolicy() == CompositorPriority && Platform::current()->monotonicallyIncreasingTime() > m_compositorPriorityPolicyEndTimeSeconds)
|
| enterSchedulerPolicyLocked(Normal);
|
| }
|
|
|
| -bool Scheduler::executeHighPriorityTasks(Deque<TracedTask>& highPriorityTasks)
|
| -{
|
| - TRACE_EVENT0("blink", "Scheduler::executeHighPriorityTasks");
|
| - int highPriorityTasksExecuted = 0;
|
| - while (!highPriorityTasks.isEmpty()) {
|
| - highPriorityTasks.takeFirst().run();
|
| - highPriorityTasksExecuted++;
|
| - }
|
| -
|
| - int highPriorityTaskCount = atomicSubtract(&m_highPriorityTaskCount, highPriorityTasksExecuted);
|
| - ASSERT_UNUSED(highPriorityTaskCount, highPriorityTaskCount >= 0);
|
| - TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
|
| - return highPriorityTasksExecuted > 0;
|
| -}
|
| -
|
| void Scheduler::sharedTimerAdapter()
|
| {
|
| shared()->tickSharedTimer();
|
| @@ -300,11 +231,6 @@ bool Scheduler::shouldYieldForHighPriorityWork() const
|
| if (schedulerPolicy() != CompositorPriority)
|
| return false;
|
|
|
| - return hasPendingHighPriorityWork();
|
| -}
|
| -
|
| -bool Scheduler::hasPendingHighPriorityWork() const
|
| -{
|
| // This method is expected to be run on the main thread, but the high priority tasks will be posted by
|
| // other threads. We could use locks here, but this function is (sometimes) called a lot by
|
| // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + barrier loads here which
|
| @@ -324,13 +250,13 @@ Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const
|
|
|
| void Scheduler::enterSchedulerPolicy(SchedulerPolicy schedulerPolicy)
|
| {
|
| - Locker<Mutex> lock(m_pendingTasksMutex);
|
| + Locker<Mutex> lock(m_policyStateMutex);
|
| enterSchedulerPolicyLocked(schedulerPolicy);
|
| }
|
|
|
| void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy)
|
| {
|
| - ASSERT(m_pendingTasksMutex.locked());
|
| + ASSERT(m_policyStateMutex.locked());
|
| if (schedulerPolicy == CompositorPriority)
|
| m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotonicallyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds;
|
|
|
|
|