Home | History | Annotate | Download | only in scheduler
      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