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; |