blob: 2467766d4857b3f0e13684574993d0670f2a8e3a [file] [log] [blame]
// 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