| Index: Source/platform/scheduler/Scheduler.cpp
|
| diff --git a/Source/platform/scheduler/Scheduler.cpp b/Source/platform/scheduler/Scheduler.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..aea7611c121818e9ab64ce0489513e105849c3e1
|
| --- /dev/null
|
| +++ b/Source/platform/scheduler/Scheduler.cpp
|
| @@ -0,0 +1,176 @@
|
| +/*
|
| + * Copyright (C) 2014 Google Inc. All rights reserved.
|
| + *
|
| + * Redistribution and use in source and binary forms, with or without
|
| + * modification, are permitted provided that the following conditions
|
| + * are met:
|
| + *
|
| + * 1. Redistributions of source code must retain the above copyright
|
| + * notice, this list of conditions and the following disclaimer.
|
| + * 2. Redistributions in binary form must reproduce the above copyright
|
| + * notice, this list of conditions and the following disclaimer in the
|
| + * documentation and/or other materials provided with the distribution.
|
| + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
| + * its contributors may be used to endorse or promote products derived
|
| + * from this software without specific prior written permission.
|
| + *
|
| + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
| + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
| + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
| + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
| + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
| + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
| + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
| + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| + */
|
| +
|
| +#include "config.h"
|
| +#include "platform/scheduler/Scheduler.h"
|
| +
|
| +#include "platform/Task.h"
|
| +#include "platform/TraceEvent.h"
|
| +#include "public/platform/Platform.h"
|
| +
|
| +namespace WebCore {
|
| +
|
| +Scheduler* Scheduler::s_currentScheduler = 0;
|
| +
|
| +void Scheduler::initializeOnMainThread()
|
| +{
|
| + s_currentScheduler = new Scheduler();
|
| +}
|
| +
|
| +void Scheduler::shutdown()
|
| +{
|
| + delete s_currentScheduler;
|
| + s_currentScheduler = nullptr;
|
| +}
|
| +
|
| +Scheduler* Scheduler::current()
|
| +{
|
| + return s_currentScheduler;
|
| +}
|
| +
|
| +Scheduler::Scheduler()
|
| + : m_mainThread(blink::Platform::current()->currentThread())
|
| + , m_sharedTimerFunction(nullptr)
|
| + , m_workScheduled(false)
|
| + , m_hasPendingBeginFrameTask(false)
|
| +{
|
| +}
|
| +
|
| +Scheduler::~Scheduler()
|
| +{
|
| + runScheduledTasks();
|
| + ASSERT(!chooseNextTask());
|
| +}
|
| +
|
| +void Scheduler::scheduleTask(TaskQueue* queue, blink::WebThread::Task* task)
|
| +{
|
| + MutexLocker lock(m_taskQueueLock);
|
| + queue->push_back(task);
|
| + if (m_workScheduled)
|
| + return;
|
| + m_workScheduled = true;
|
| + m_mainThread->postTask(new Task(WTF::bind(&Scheduler::runScheduledTasks, this)));
|
| +}
|
| +
|
| +void Scheduler::runScheduledTasks()
|
| +{
|
| + TRACE_EVENT0("blink", "Scheduler::runScheduledTasks");
|
| + {
|
| + MutexLocker lock(m_taskQueueLock);
|
| + m_workScheduled = false;
|
| + m_hasPendingBeginFrameTask = false;
|
| + }
|
| + while (OwnPtr<blink::WebThread::Task> task = chooseNextTask())
|
| + task->run();
|
| +}
|
| +
|
| +PassOwnPtr<blink::WebThread::Task> Scheduler::chooseNextTask()
|
| +{
|
| + MutexLocker lock(m_taskQueueLock);
|
| + TaskQueue* queues[] = {
|
| + &m_pendingInputTasks,
|
| + &m_pendingCompositorTasks,
|
| + &m_pendingTasks,
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(queues); i++) {
|
| + if (!queues[i]->size())
|
| + continue;
|
| + OwnPtr<blink::WebThread::Task> task = adoptPtr(queues[i]->front());
|
| + queues[i]->pop_front();
|
| + return task.release();
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +void Scheduler::runSharedTimer()
|
| +{
|
| + TRACE_EVENT0("blink", "Scheduler::runSharedTimer");
|
| + if (shouldYieldForHighPriorityWork()) {
|
| + postTask(new Task(WTF::bind(&Scheduler::runSharedTimer, this)));
|
| + return;
|
| + }
|
| + if (m_sharedTimerFunction)
|
| + m_sharedTimerFunction();
|
| +}
|
| +
|
| +void Scheduler::postTask(blink::WebThread::Task* task)
|
| +{
|
| + scheduleTask(&m_pendingTasks, task);
|
| +}
|
| +
|
| +void Scheduler::postInputTask(blink::WebThread::Task* task)
|
| +{
|
| + scheduleTask(&m_pendingInputTasks, task);
|
| +}
|
| +
|
| +void Scheduler::postCompositorTask(blink::WebThread::Task* task)
|
| +{
|
| + scheduleTask(&m_pendingCompositorTasks, task);
|
| +}
|
| +
|
| +void Scheduler::postBeginFrameTask(blink::WebThread::Task* task, double frameTime, double deadline, double interval)
|
| +{
|
| + {
|
| + MutexLocker lock(m_taskQueueLock);
|
| + m_hasPendingBeginFrameTask = true;
|
| + }
|
| + postCompositorTask(task);
|
| +}
|
| +
|
| +void Scheduler::sharedTimerAdapter()
|
| +{
|
| + current()->runSharedTimer();
|
| +}
|
| +
|
| +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();
|
| +}
|
| +
|
| +bool Scheduler::shouldYieldForHighPriorityWork()
|
| +{
|
| + // TODO: Use atomics.
|
| + MutexLocker lock(m_taskQueueLock);
|
| + bool yield = m_pendingInputTasks.size() || m_hasPendingBeginFrameTask;
|
| + TRACE_EVENT_INSTANT1("blink", "Scheduler::shouldYieldForHighPriorityWork", "yield", yield);
|
| + return yield;
|
| +}
|
| +
|
| +}
|
|
|