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

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

Issue 559973003: Adds the concept of Policies to the Blink Scheduler (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Change the test time funcstions to be non-static 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 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 4a447721f58921b8fe0500568ed583f76288b5c8..eb6c698604630c429e1374f82446497987a24b74 100644
--- a/Source/platform/scheduler/Scheduler.cpp
+++ b/Source/platform/scheduler/Scheduler.cpp
@@ -18,6 +18,9 @@ namespace blink {
namespace {
+// The time we should stay in CompositorPriority mode for, after a touch event.
+double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1;
+
// Can be created from any thread.
// Note if the scheduler gets shutdown, this may be run after.
class MainThreadIdleTaskAdapter : public WebThread::Task {
@@ -63,6 +66,8 @@ public:
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();
}
};
@@ -86,7 +91,7 @@ public:
// FIXME: This check should't be necessary, tasks should not outlive blink.
ASSERT(scheduler);
if (scheduler)
- Scheduler::shared()->swapQueuesAndRunPendingTasks();
+ Scheduler::shared()->runPendingHighPriorityTasksIfInCompositorPriority();
m_task.run();
}
@@ -114,8 +119,10 @@ Scheduler* Scheduler::shared()
Scheduler::Scheduler()
: m_sharedTimerFunction(nullptr)
, m_mainThread(blink::Platform::current()->currentThread())
+ , m_compositorPriorityPolicyEndTimeSeconds(0)
, m_highPriorityTaskCount(0)
, m_highPriorityTaskRunnerPosted(false)
+ , m_schedulerPolicy(Normal)
{
}
@@ -153,6 +160,7 @@ void Scheduler::postInputTask(const TraceLocation& location, const Task& task)
m_pendingHighPriorityTasks.append(TracedTask(task, location));
atomicIncrement(&m_highPriorityTaskCount);
maybePostMainThreadPendingHighPriorityTaskRunner();
+ TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
}
void Scheduler::postCompositorTask(const TraceLocation& location, const Task& task)
@@ -161,6 +169,7 @@ void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta
m_pendingHighPriorityTasks.append(TracedTask(task, location));
atomicIncrement(&m_highPriorityTaskCount);
maybePostMainThreadPendingHighPriorityTaskRunner();
+ TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPriorityTasks", m_highPriorityTaskCount);
}
void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner()
@@ -182,13 +191,22 @@ 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 = swapQueuesAndRunPendingTasks();
+ 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)
- swapQueuesAndRunPendingTasks();
+ runPendingHighPriorityTasksIfInCompositorPriority();
+}
+
+bool Scheduler::runPendingHighPriorityTasksIfInCompositorPriority()
+{
+ ASSERT(isMainThread());
+ if (schedulerPolicy() != CompositorPriority)
+ return false;
+
+ return swapQueuesAndRunPendingTasks();
}
bool Scheduler::swapQueuesAndRunPendingTasks()
@@ -199,6 +217,7 @@ bool Scheduler::swapQueuesAndRunPendingTasks()
// 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);
}
@@ -212,10 +231,21 @@ void Scheduler::swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting()
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());
+
+ // 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");
@@ -227,6 +257,7 @@ bool Scheduler::executeHighPriorityTasks(Deque<TracedTask>& highPriorityTasks)
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;
}
@@ -253,6 +284,10 @@ void Scheduler::stopSharedTimer()
bool Scheduler::shouldYieldForHighPriorityWork() const
{
+ // It's only worthwhile yielding in CompositorPriority mode.
+ if (schedulerPolicy() != CompositorPriority)
+ return false;
+
return hasPendingHighPriorityWork();
}
@@ -266,6 +301,31 @@ bool Scheduler::hasPendingHighPriorityWork() const
return acquireLoad(&m_highPriorityTaskCount) != 0;
}
+Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const
+{
+ ASSERT(isMainThread());
+ // It's important not to miss the transition from normal to low latency mode, otherwise we're likely to
+ // delay the processing of input tasks. Since that transition is triggered by a different thread, we
+ // need either a lock or a memory barrier, and the memory barrier is probably cheaper.
+ return static_cast<SchedulerPolicy>(acquireLoad(&m_schedulerPolicy));
+}
+
+void Scheduler::enterSchedulerPolicy(SchedulerPolicy schedulerPolicy)
+{
+ Locker<Mutex> lock(m_pendingTasksMutex);
+ enterSchedulerPolicyLocked(schedulerPolicy);
+}
+
+void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy)
+{
+ ASSERT(m_pendingTasksMutex.locked());
+ if (schedulerPolicy == CompositorPriority)
+ m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotonicallyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds;
+
+ releaseStore(&m_schedulerPolicy, schedulerPolicy);
+ TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolicy", schedulerPolicy);
+}
+
void Scheduler::TracedTask::run()
{
TRACE_EVENT2("blink", "TracedTask::run",
« 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