1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef Scheduler_h 6 #define Scheduler_h 7 8 #include "platform/PlatformExport.h" 9 #include "platform/scheduler/TracedTask.h" 10 #include "wtf/DoubleBufferedDeque.h" 11 #include "wtf/Functional.h" 12 #include "wtf/Noncopyable.h" 13 #include "wtf/ThreadingPrimitives.h" 14 15 namespace blink { 16 class WebThread; 17 struct WebBeginFrameArgs; 18 19 // The scheduler is an opinionated gateway for arranging work to be run on the 20 // main thread. It decides which tasks get priority over others based on a 21 // scheduling policy and the overall system state. 22 class PLATFORM_EXPORT Scheduler { 23 WTF_MAKE_NONCOPYABLE(Scheduler); 24 public: 25 typedef Function<void()> Task; 26 // An IdleTask is passed an allotted time in CLOCK_MONOTONIC milliseconds and is expected to complete within this timeframe. 27 typedef Function<void(double allottedTimeMs)> IdleTask; 28 29 static Scheduler* shared(); 30 static void initializeOnMainThread(); 31 static void shutdown(); 32 33 // Called to notify about the start of a new frame. 34 void willBeginFrame(const WebBeginFrameArgs&); 35 36 // Called to notify that a previously begun frame was committed. 37 void didCommitFrameToCompositor(); 38 39 // The following entrypoints are used to schedule different types of tasks 40 // to be run on the main thread. They can be called from any thread. 41 void postInputTask(const TraceLocation&, const Task&); 42 void postCompositorTask(const TraceLocation&, const Task&); 43 void postIpcTask(const TraceLocation&, const Task&); 44 void postTask(const TraceLocation&, const Task&); // For generic (low priority) tasks. 45 void postIdleTask(const TraceLocation&, const IdleTask&); // For non-critical tasks which may be reordered relative to other task types. 46 47 // Tells the scheduler that the system received an input event. This causes the scheduler to go into 48 // Compositor Priority mode for a short duration. 49 void didReceiveInputEvent(); 50 51 // Returns true if there is high priority work pending on the main thread 52 // and the caller should yield to let the scheduler service that work. 53 // Can be called on any thread. 54 bool shouldYieldForHighPriorityWork() const; 55 56 // The shared timer can be used to schedule a periodic callback which may 57 // get preempted by higher priority work. 58 void setSharedTimerFiredFunction(void (*function)()); 59 void setSharedTimerFireInterval(double); 60 void stopSharedTimer(); 61 62 protected: 63 class MainThreadPendingTaskRunner; 64 class MainThreadPendingHighPriorityTaskRunner; 65 friend class MainThreadPendingTaskRunner; 66 friend class MainThreadPendingHighPriorityTaskRunner; 67 68 enum SchedulerPolicy { 69 Normal, 70 CompositorPriority, 71 }; 72 73 Scheduler(); 74 virtual ~Scheduler(); 75 76 void scheduleIdleTask(const TraceLocation&, const IdleTask&); 77 void postHighPriorityTaskInternal(const TraceLocation&, const Task&, const char* traceName); 78 79 static void sharedTimerAdapter(); 80 81 // Start of main thread only members ----------------------------------- 82 83 // Only does work in CompositorPriority mode. Returns true if any work was done. 84 bool runPendingHighPriorityTasksIfInCompositorPriority(); 85 86 // Returns true if any work was done. 87 bool swapQueuesAndRunPendingTasks(); 88 89 void swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting(); 90 91 // Returns true if any work was done. 92 bool executeHighPriorityTasks(Deque<TracedTask>&); 93 94 // Return the current SchedulerPolicy. 95 SchedulerPolicy schedulerPolicy() const; 96 97 void maybeEnterNormalSchedulerPolicy(); 98 99 // Must be called while m_pendingTasksMutex is locked. 100 void maybePostMainThreadPendingHighPriorityTaskRunner(); 101 102 void tickSharedTimer(); 103 104 void (*m_sharedTimerFunction)(); 105 106 // End of main thread only members ------------------------------------- 107 108 bool hasPendingHighPriorityWork() const; 109 110 void enterSchedulerPolicyLocked(SchedulerPolicy); 111 112 void enterSchedulerPolicy(SchedulerPolicy); 113 114 static Scheduler* s_sharedScheduler; 115 116 WebThread* m_mainThread; 117 118 // This mutex protects calls to the pending task queue, m_highPriorityTaskRunnerPosted and 119 // m_compositorPriorityPolicyEndTimeSeconds. 120 Mutex m_pendingTasksMutex; 121 DoubleBufferedDeque<TracedTask> m_pendingHighPriorityTasks; 122 double m_compositorPriorityPolicyEndTimeSeconds; 123 124 // Declared volatile as it is atomically incremented. 125 volatile int m_highPriorityTaskCount; 126 127 bool m_highPriorityTaskRunnerPosted; 128 129 // Don't access m_schedulerPolicy directly, use enterSchedulerPolicyLocked and SchedulerPolicy instead. 130 volatile int m_schedulerPolicy; 131 }; 132 133 } // namespace blink 134 135 #endif // Scheduler_h 136