blob: 313baa9af36fc570d1abcd97e70041f30e6e8334 [file] [log] [blame]
// Copyright 2015 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.
#include "components/scheduler/base/work_queue.h"
#include "components/scheduler/base/work_queue_sets.h"
namespace scheduler {
namespace internal {
WorkQueue::WorkQueue(TaskQueueImpl* task_queue, const char* name)
: work_queue_sets_(nullptr),
task_queue_(task_queue),
work_queue_set_index_(0),
name_(name) {}
void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const {
std::queue<TaskQueueImpl::Task> queue_copy(work_queue_);
while (!queue_copy.empty()) {
TaskQueueImpl::TaskAsValueInto(queue_copy.front(), state);
queue_copy.pop();
}
}
WorkQueue::~WorkQueue() {
DCHECK(!work_queue_sets_) << task_queue_ ->GetName() << " : "
<< work_queue_sets_->name() << " : " << name_;
}
const TaskQueueImpl::Task* WorkQueue::GetFrontTask() const {
if (work_queue_.empty())
return nullptr;
return &work_queue_.front();
}
bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const {
if (work_queue_.empty())
return false;
*enqueue_order = work_queue_.front().enqueue_order();
return true;
}
void WorkQueue::Push(const TaskQueueImpl::Task& task) {
bool was_empty = work_queue_.empty();
work_queue_.push(task);
if (was_empty && work_queue_sets_)
work_queue_sets_->OnPushQueue(this);
}
void WorkQueue::PushAndSetEnqueueOrder(const TaskQueueImpl::Task& task,
EnqueueOrder enqueue_order) {
bool was_empty = work_queue_.empty();
work_queue_.push(task);
work_queue_.back().set_enqueue_order(enqueue_order);
if (was_empty && work_queue_sets_)
work_queue_sets_->OnPushQueue(this);
}
void WorkQueue::PopTaskForTest() {
work_queue_.pop();
}
void WorkQueue::SwapLocked(std::queue<TaskQueueImpl::Task>& incoming_queue) {
std::swap(work_queue_, incoming_queue);
if (!work_queue_.empty() && work_queue_sets_)
work_queue_sets_->OnPushQueue(this);
task_queue_->TraceQueueSize(true);
}
TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() {
DCHECK(work_queue_sets_);
DCHECK(!work_queue_.empty());
TaskQueueImpl::Task pending_task = std::move(work_queue_.front());
work_queue_.pop();
work_queue_sets_->OnPopQueue(this);
task_queue_->TraceQueueSize(false);
return pending_task;
}
void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) {
work_queue_sets_ = work_queue_sets;
}
void WorkQueue::AssignSetIndex(size_t work_queue_set_index) {
work_queue_set_index_ = work_queue_set_index;
}
bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const {
DCHECK(!work_queue_.empty());
DCHECK(!other_queue->work_queue_.empty());
EnqueueOrder enqueue_order = 0;
EnqueueOrder other_enqueue_order = 0;
bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order);
bool have_other_task =
other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order);
DCHECK(have_task);
DCHECK(have_other_task);
return enqueue_order < other_enqueue_order;
}
} // namespace internal
} // namespace scheduler