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

Unified Diff: Source/platform/scheduler/Scheduler.cpp

Issue 621363002: scheduler: Post high priority tasks directly to the message loop (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Test tweak. Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/scheduler/Scheduler.h ('k') | Source/platform/scheduler/SchedulerTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « Source/platform/scheduler/Scheduler.h ('k') | Source/platform/scheduler/SchedulerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698