| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef Scheduler_h |
| #define Scheduler_h |
| |
| #include "platform/PlatformExport.h" |
| #include "platform/TraceLocation.h" |
| #include "wtf/DoubleBufferedDeque.h" |
| #include "wtf/Functional.h" |
| #include "wtf/Noncopyable.h" |
| #include "wtf/ThreadingPrimitives.h" |
| |
| namespace blink { |
| class WebThread; |
| } |
| |
| namespace blink { |
| |
| // The scheduler is an opinionated gateway for arranging work to be run on the |
| // main thread. It decides which tasks get priority over others based on a |
| // scheduling policy and the overall system state. |
| class PLATFORM_EXPORT Scheduler { |
| WTF_MAKE_NONCOPYABLE(Scheduler); |
| public: |
| typedef Function<void()> Task; |
| // An IdleTask is passed an allotted time in CLOCK_MONOTONIC milliseconds and is expected to complete within this timeframe. |
| typedef Function<void(double allottedTimeMs)> IdleTask; |
| |
| static Scheduler* shared(); |
| static void initializeOnMainThread(); |
| static void shutdown(); |
| |
| // The following entrypoints are used to schedule different types of tasks |
| // to be run on the main thread. They can be called from any thread. |
| void postInputTask(const TraceLocation&, const Task&); |
| void postCompositorTask(const TraceLocation&, const Task&); |
| void postTask(const TraceLocation&, const Task&); // For generic (low priority) tasks. |
| void postIdleTask(const TraceLocation&, const IdleTask&); // For non-critical tasks which may be reordered relative to other task types. |
| |
| // Returns true if there is high priority work pending on the main thread |
| // and the caller should yield to let the scheduler service that work. |
| // Can be called on any thread. |
| bool shouldYieldForHighPriorityWork() const; |
| |
| // The shared timer can be used to schedule a periodic callback which may |
| // get preempted by higher priority work. |
| void setSharedTimerFiredFunction(void (*function)()); |
| void setSharedTimerFireInterval(double); |
| void stopSharedTimer(); |
| |
| private: |
| class MainThreadPendingTaskRunner; |
| class MainThreadPendingHighPriorityTaskRunner; |
| friend class MainThreadPendingTaskRunner; |
| friend class MainThreadPendingHighPriorityTaskRunner; |
| |
| Scheduler(); |
| ~Scheduler(); |
| |
| void scheduleIdleTask(const TraceLocation&, const IdleTask&); |
| |
| static void sharedTimerAdapter(); |
| void tickSharedTimer(); |
| |
| bool hasPendingHighPriorityWork() const; |
| void runHighPriorityTasks(); |
| |
| static Scheduler* s_sharedScheduler; |
| |
| class TracedTask { |
| public: |
| TracedTask(const Task& task, const TraceLocation& location) |
| : m_task(task) |
| , m_location(location) { } |
| |
| void run(); |
| |
| private: |
| Task m_task; |
| TraceLocation m_location; |
| }; |
| |
| // Should only be accessed from the main thread. |
| void (*m_sharedTimerFunction)(); |
| |
| // These members can be accessed from any thread. |
| WebThread* m_mainThread; |
| |
| // This mutex protects calls to the pending task queues. |
| Mutex m_pendingTasksMutex; |
| DoubleBufferedDeque<TracedTask> m_pendingInputTasks; |
| DoubleBufferedDeque<TracedTask> m_pendingCompositorTasks; |
| |
| volatile int m_highPriorityTaskCount; |
| }; |
| |
| } // namespace blink |
| |
| #endif // Scheduler_h |