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

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

Issue 656463004: Use the scheduling mechanism provided by the platform (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Mike's comments. 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 a5fd7ce7c4e45a18316a3b6dc7ff7bbba81a5af1..967271dd962718285b4a82870ac6d3d7c0ae7a84 100644
--- a/Source/platform/scheduler/Scheduler.cpp
+++ b/Source/platform/scheduler/Scheduler.cpp
@@ -5,102 +5,34 @@
#include "config.h"
#include "platform/scheduler/Scheduler.h"
-#include "platform/PlatformThreadData.h"
-#include "platform/RuntimeEnabledFeatures.h"
-#include "platform/Task.h"
-#include "platform/ThreadTimers.h"
-#include "platform/TraceEvent.h"
+#include "platform/TraceLocation.h"
#include "public/platform/Platform.h"
-#include "wtf/MainThread.h"
+#include "public/platform/WebScheduler.h"
namespace blink {
-namespace {
-
-// The time we should stay in CompositorPriority mode for, after a touch event.
-double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1;
-
-} // namespace
-
-// Typically only created from compositor or render threads.
-// Note if the scheduler gets shutdown, this may be run after.
-class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Task {
+class IdleTaskRunner : public WebScheduler::IdleTask {
public:
- MainThreadPendingHighPriorityTaskRunner(
- const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
- : m_task(internal::TracedStandardTask::Create(task, location, traceName))
+ explicit IdleTaskRunner(const Scheduler::IdleTask& task)
+ : m_task(task)
{
- ASSERT(Scheduler::shared());
}
- // WebThread::Task implementation.
- virtual void run() override
+ virtual ~IdleTaskRunner()
{
- m_task->run();
- if (Scheduler* scheduler = Scheduler::shared()) {
- scheduler->updatePolicy();
- scheduler->didRunHighPriorityTask();
- }
}
-private:
- OwnPtr<internal::TracedStandardTask> m_task;
-};
-
-// Can be created from any thread.
-// Note if the scheduler gets shutdown, this may be run after.
-class Scheduler::MainThreadPendingTaskRunner : public WebThread::Task {
-public:
- MainThreadPendingTaskRunner(
- const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
- : m_task(internal::TracedStandardTask::Create(task, location, traceName))
+ // WebScheduler::IdleTask implementation.
+ void run(double deadlineSeconds) override
{
- ASSERT(Scheduler::shared());
+ m_task(deadlineSeconds);
}
-
- // WebThread::Task implementation.
- virtual void run() override
- {
- m_task->run();
- if (Scheduler* scheduler = Scheduler::shared()) {
- scheduler->updatePolicy();
- }
- }
-
private:
- OwnPtr<internal::TracedStandardTask> m_task;
-};
-
-
-// Can be created from any thread.
-// Note if the scheduler gets shutdown, this may be run after.
-class Scheduler::MainThreadPendingIdleTaskRunner : public WebThread::Task {
-public:
- MainThreadPendingIdleTaskRunner()
- {
- ASSERT(Scheduler::shared());
- }
-
- // WebThread::Task implementation.
- virtual void run() override
- {
- if (Scheduler* scheduler = Scheduler::shared()) {
- scheduler->maybeRunPendingIdleTask();
- // If possible, run the next idle task by reposting on the main thread.
- scheduler->maybePostMainThreadPendingIdleTask();
- }
- }
-
+ Scheduler::IdleTask m_task;
};
-
Scheduler* Scheduler::s_sharedScheduler = nullptr;
-void Scheduler::initializeOnMainThread()
-{
- s_sharedScheduler = new Scheduler();
-}
-
void Scheduler::shutdown()
{
delete s_sharedScheduler;
@@ -109,213 +41,33 @@ void Scheduler::shutdown()
Scheduler* Scheduler::shared()
{
+ if (!s_sharedScheduler)
+ s_sharedScheduler = new Scheduler(Platform::current()->scheduler());
return s_sharedScheduler;
}
-Scheduler::Scheduler()
- : m_sharedTimerFunction(nullptr)
- , m_mainThread(blink::Platform::current()->currentThread())
- , m_estimatedNextBeginFrameSeconds(0)
- , m_highPriorityTaskCount(0)
- , m_highPriorityTaskRunnerPosted(false)
- , m_compositorPriorityPolicyEndTimeSeconds(0)
- , m_schedulerPolicy(Normal)
+Scheduler::Scheduler(WebScheduler* webScheduler)
+ : m_webScheduler(webScheduler)
{
}
Scheduler::~Scheduler()
{
-}
-
-void Scheduler::willBeginFrame(double estimatedNextBeginFrameSeconds)
-{
- ASSERT(isMainThread());
- m_currentFrameCommitted = false;
- m_estimatedNextBeginFrameSeconds = estimatedNextBeginFrameSeconds;
- // TODO: Schedule a deferred task here to run idle work if didCommitFrameToCompositor never gets called.
-}
-
-void Scheduler::didCommitFrameToCompositor()
-{
- ASSERT(isMainThread());
- m_currentFrameCommitted = true;
- flushIncomingIdleTasks();
- maybePostMainThreadPendingIdleTask();
-}
-
-void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, const Task& task, const char* traceName)
-{
- m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner(task, location, traceName));
- atomicIncrement(&m_highPriorityTaskCount);
- 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);
-}
-
-void Scheduler::postIdleTaskInternal(const TraceLocation& location, const IdleTask& idleTask, const char* traceName)
-{
- Locker<Mutex> lock(m_incomingIdleTasksMutex);
- m_incomingIdleTasks.append(internal::TracedIdleTask::Create(idleTask, location, traceName));
-}
-
-void Scheduler::postTask(const TraceLocation& location, const Task& task)
-{
- m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Scheduler::MainThreadTask"));
-}
-
-void Scheduler::postInputTask(const TraceLocation& location, const Task& task)
-{
- postHighPriorityTaskInternal(location, task, "Scheduler::InputTask");
-}
-
-void Scheduler::didReceiveInputEvent()
-{
- // FIXME: We probably want an explicit Disabled policy rather than disabling CompositorPriority.
- if (RuntimeEnabledFeatures::blinkSchedulerEnabled())
- enterSchedulerPolicy(CompositorPriority);
-}
-
-void Scheduler::postCompositorTask(const TraceLocation& location, const Task& task)
-{
- postHighPriorityTaskInternal(location, task, "Scheduler::CompositorTask");
-}
-
-void Scheduler::postIpcTask(const TraceLocation& location, const Task& task)
-{
- // FIXME: we want IPCs to be high priority, but we can't currently do that because some of them can take a very long
- // time to process. These need refactoring but we need to add some infrastructure to identify them.
- m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Scheduler::IpcTask"));
+ if (m_webScheduler)
+ m_webScheduler->shutdown();
}
void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idleTask)
{
- postIdleTaskInternal(location, idleTask, "Scheduler::IdleTask");
-}
-
-bool Scheduler::maybePostMainThreadPendingIdleTask()
-{
- ASSERT(isMainThread());
- TRACE_EVENT0("blink", "Scheduler::maybePostMainThreadPendingIdleTask");
- if (canRunIdleTask()) {
- if (!m_pendingIdleTasks.isEmpty()) {
- m_mainThread->postTask(new MainThreadPendingIdleTaskRunner());
- return true;
- }
- }
- return false;
-}
-
-void Scheduler::tickSharedTimer()
-{
- TRACE_EVENT0("blink", "Scheduler::tickSharedTimer");
- m_sharedTimerFunction();
-}
-
-void Scheduler::updatePolicy()
-{
- ASSERT(isMainThread());
- 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);
-}
-
-void Scheduler::sharedTimerAdapter()
-{
- shared()->tickSharedTimer();
-}
-
-void Scheduler::setSharedTimerFiredFunction(void (*function)())
-{
- m_sharedTimerFunction = function;
- blink::Platform::current()->setSharedTimerFiredFunction(function ? &Scheduler::sharedTimerAdapter : nullptr);
-}
-
-void Scheduler::setSharedTimerFireInterval(double interval)
-{
- blink::Platform::current()->setSharedTimerFireInterval(interval);
-}
-
-void Scheduler::stopSharedTimer()
-{
- blink::Platform::current()->stopSharedTimer();
+ if (m_webScheduler)
+ m_webScheduler->postIdleTask(location.toWebTraceLocation(), new IdleTaskRunner(idleTask));
}
bool Scheduler::shouldYieldForHighPriorityWork() const
{
- // It's only worthwhile yielding in CompositorPriority mode.
- if (schedulerPolicy() != CompositorPriority)
- return false;
-
- // 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
- // should be cheaper.
- // NOTE it's possible the barrier read is overkill here, since delayed yielding isn't a big deal.
- return acquireLoad(&m_highPriorityTaskCount) != 0;
-}
-
-bool Scheduler::maybeRunPendingIdleTask()
-{
- ASSERT(isMainThread());
- if (!canRunIdleTask() || m_pendingIdleTasks.isEmpty())
- return false;
-
- m_pendingIdleTasks.takeFirst()->run();
- return true;
-}
-
-void Scheduler::flushIncomingIdleTasks()
-{
- ASSERT(isMainThread());
- Locker<Mutex> lock(m_incomingIdleTasksMutex);
- while (!m_incomingIdleTasks.isEmpty())
- m_pendingIdleTasks.append(m_incomingIdleTasks.takeFirst());
-}
-
-double Scheduler::currentFrameDeadlineForIdleTasks() const
-{
- ASSERT(isMainThread());
- // TODO: Make idle time more fine-grain chunks when in Compositor priority.
- return m_estimatedNextBeginFrameSeconds;
-}
-
-bool Scheduler::canRunIdleTask() const
-{
- ASSERT(isMainThread());
- return m_currentFrameCommitted
- && !shouldYieldForHighPriorityWork()
- && (m_estimatedNextBeginFrameSeconds > Platform::current()->monotonicallyIncreasingTime());
-}
-
-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_policyStateMutex);
- enterSchedulerPolicyLocked(schedulerPolicy);
-}
-
-void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy)
-{
- ASSERT(m_policyStateMutex.locked());
- if (schedulerPolicy == CompositorPriority)
- m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotonicallyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds;
-
- releaseStore(&m_schedulerPolicy, schedulerPolicy);
- TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolicy", schedulerPolicy);
+ if (m_webScheduler)
+ return m_webScheduler->shouldYieldForHighPriorityWork();
+ return false;
}
} // namespace blink
« 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