Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(784)

Unified Diff: third_party/WebKit/Source/platform/scheduler/base/work_queue.cc

Issue 2319053004: [Reland] Make canceling Timers fast. (Closed)
Patch Set: Rebased Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
diff --git a/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc b/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
index be7f403174cd70943a8fc9db29cc8542536d06b9..71f6796f76e05118d9c2d20800825a54e06114dc 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
@@ -10,20 +10,25 @@ namespace blink {
namespace scheduler {
namespace internal {
-WorkQueue::WorkQueue(TaskQueueImpl* task_queue,
- const char* name,
- TaskQueueImpl::Task::ComparatorFn comparator)
- : work_queue_(comparator),
- work_queue_sets_(nullptr),
+WorkQueue::WorkQueue(TaskQueueImpl* task_queue, const char* name)
+ : work_queue_sets_(nullptr),
task_queue_(task_queue),
work_queue_set_index_(0),
name_(name),
fence_(0) {}
void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const {
- for (const TaskQueueImpl::Task& task : work_queue_) {
- TaskQueueImpl::TaskAsValueInto(task, state);
+ // Remove const to search |work_queue_| in the destructive manner. Restore the
+ // content from |visited| later.
+ std::queue<TaskQueueImpl::Task>* mutable_queue =
+ const_cast<std::queue<TaskQueueImpl::Task>*>(&work_queue_);
+ std::queue<TaskQueueImpl::Task> visited;
+ while (!mutable_queue->empty()) {
+ TaskQueueImpl::TaskAsValueInto(mutable_queue->front(), state);
+ visited.push(std::move(mutable_queue->front()));
+ mutable_queue->pop();
}
+ *mutable_queue = std::move(visited);
}
WorkQueue::~WorkQueue() {
@@ -34,13 +39,13 @@ WorkQueue::~WorkQueue() {
const TaskQueueImpl::Task* WorkQueue::GetFrontTask() const {
if (work_queue_.empty())
return nullptr;
- return &*work_queue_.begin();
+ return &work_queue_.front();
}
const TaskQueueImpl::Task* WorkQueue::GetBackTask() const {
if (work_queue_.empty())
return nullptr;
- return &*work_queue_.rbegin();
+ return &work_queue_.back();
}
bool WorkQueue::BlockedByFence() const {
@@ -50,18 +55,18 @@ bool WorkQueue::BlockedByFence() const {
// If the queue is empty then any future tasks will have a higher enqueue
// order and will be blocked. The queue is also blocked if the head is past
// the fence.
- return work_queue_.empty() || work_queue_.begin()->enqueue_order() > fence_;
+ return work_queue_.empty() || work_queue_.front().enqueue_order() > fence_;
}
bool WorkQueue::GetFrontTaskEnqueueOrder(EnqueueOrder* enqueue_order) const {
if (work_queue_.empty() || BlockedByFence())
return false;
// Quick sanity check.
- DCHECK_LE(work_queue_.begin()->enqueue_order(),
- work_queue_.rbegin()->enqueue_order())
- << task_queue_->GetName() << " : "
- << work_queue_sets_->name() << " : " << name_;
- *enqueue_order = work_queue_.begin()->enqueue_order();
+ DCHECK_LE(work_queue_.front().enqueue_order(),
+ work_queue_.back().enqueue_order())
+ << task_queue_->GetName() << " : " << work_queue_sets_->name() << " : "
+ << name_;
+ *enqueue_order = work_queue_.front().enqueue_order();
return true;
}
@@ -71,15 +76,8 @@ void WorkQueue::Push(TaskQueueImpl::Task task) {
DCHECK(task.enqueue_order_set());
#endif
- // We expect |task| to be inserted at the end. Amoritized O(1).
- work_queue_.insert(work_queue_.end(), std::move(task));
- DCHECK_EQ(task.enqueue_order(), work_queue_.rbegin()->enqueue_order())
- << task_queue_->GetName() << " : "
- << work_queue_sets_->name() << " : " << name_
- << "task [scheduled_run_time_" << task.delayed_run_time << ", "
- << task.sequence_num <<
- "] rbegin() [" << work_queue_.rbegin()->delayed_run_time << ", "
- << work_queue_.rbegin()->sequence_num << "]";
+ // Amoritized O(1).
+ work_queue_.push(std::move(task));
if (!was_empty)
return;
@@ -89,37 +87,13 @@ void WorkQueue::Push(TaskQueueImpl::Task task) {
work_queue_sets_->OnPushQueue(this);
}
-bool WorkQueue::CancelTask(const TaskQueueImpl::Task& key) {
- TaskQueueImpl::ComparatorQueue::iterator it = work_queue_.find(key);
- if (it == work_queue_.end())
- return false;
-
- if (it == work_queue_.begin()) {
- EnqueueOrder erased_task_enqueue_order = it->enqueue_order();
- work_queue_.erase(it);
- // We can't guarantee this WorkQueue is the lowest value in the WorkQueueSet
- // so we need to use OnQueueHeadChanged instead of OnPopQueue for
- // correctness.
- if (!BlockedByFence())
- work_queue_sets_->OnQueueHeadChanged(this, erased_task_enqueue_order);
- } else {
- work_queue_.erase(it);
- }
- task_queue_->TraceQueueSize(false);
- return true;
-}
-
-bool WorkQueue::IsTaskPending(const TaskQueueImpl::Task& key) const {
- return work_queue_.find(key) != work_queue_.end();
-}
-
void WorkQueue::PopTaskForTest() {
if (work_queue_.empty())
return;
- work_queue_.erase(work_queue_.begin());
+ work_queue_.pop();
}
-void WorkQueue::SwapLocked(TaskQueueImpl::ComparatorQueue& incoming_queue) {
+void WorkQueue::SwapLocked(std::queue<TaskQueueImpl::Task>& incoming_queue) {
DCHECK(work_queue_.empty());
std::swap(work_queue_, incoming_queue);
if (work_queue_.empty())
@@ -132,10 +106,16 @@ void WorkQueue::SwapLocked(TaskQueueImpl::ComparatorQueue& incoming_queue) {
TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() {
DCHECK(work_queue_sets_);
DCHECK(!work_queue_.empty());
- TaskQueueImpl::ComparatorQueue::iterator it = work_queue_.begin();
+
+ // Skip over canceled tasks, except for the last one since we always return
+ // something.
+ while (work_queue_.size() > 1u && work_queue_.front().task.IsCancelled()) {
+ work_queue_.pop();
+ }
+
TaskQueueImpl::Task pending_task =
- std::move(const_cast<TaskQueueImpl::Task&>(*it));
- work_queue_.erase(it);
+ std::move(const_cast<TaskQueueImpl::Task&>(work_queue_.front()));
+ work_queue_.pop();
work_queue_sets_->OnPopQueue(this);
task_queue_->TraceQueueSize(false);
return pending_task;

Powered by Google App Engine
This is Rietveld 408576698