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

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

Issue 2640763003: Optimize away updatable_queue_set_ (Closed)
Patch Set: Fix lock issue plus rename OnPushQueue Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/scheduler/base/work_queue.h" 5 #include "platform/scheduler/base/work_queue.h"
6 6
7 #include "platform/scheduler/base/work_queue_sets.h" 7 #include "platform/scheduler/base/work_queue_sets.h"
8 8
9 namespace blink { 9 namespace blink {
10 namespace scheduler { 10 namespace scheduler {
11 namespace internal { 11 namespace internal {
12 12
13 WorkQueue::WorkQueue(TaskQueueImpl* task_queue, const char* name) 13 WorkQueue::WorkQueue(TaskQueueImpl* task_queue,
14 const char* name,
15 QueueType queue_type)
14 : work_queue_sets_(nullptr), 16 : work_queue_sets_(nullptr),
15 task_queue_(task_queue), 17 task_queue_(task_queue),
16 work_queue_set_index_(0), 18 work_queue_set_index_(0),
17 name_(name), 19 name_(name),
18 fence_(0) {} 20 fence_(0),
21 queue_type_(queue_type) {}
19 22
20 void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const { 23 void WorkQueue::AsValueInto(base::trace_event::TracedValue* state) const {
21 for (const TaskQueueImpl::Task& task : work_queue_) { 24 for (const TaskQueueImpl::Task& task : work_queue_) {
22 TaskQueueImpl::TaskAsValueInto(task, state); 25 TaskQueueImpl::TaskAsValueInto(task, state);
23 } 26 }
24 } 27 }
25 28
26 WorkQueue::~WorkQueue() { 29 WorkQueue::~WorkQueue() {
27 DCHECK(!work_queue_sets_) << task_queue_->GetName() << " : " 30 DCHECK(!work_queue_sets_) << task_queue_->GetName() << " : "
28 << work_queue_sets_->name() << " : " << name_; 31 << work_queue_sets_->name() << " : " << name_;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 #endif 72 #endif
70 73
71 // Amoritized O(1). 74 // Amoritized O(1).
72 work_queue_.push_back(std::move(task)); 75 work_queue_.push_back(std::move(task));
73 76
74 if (!was_empty) 77 if (!was_empty)
75 return; 78 return;
76 79
77 // If we hit the fence, pretend to WorkQueueSets that we're empty. 80 // If we hit the fence, pretend to WorkQueueSets that we're empty.
78 if (work_queue_sets_ && !BlockedByFence()) 81 if (work_queue_sets_ && !BlockedByFence())
79 work_queue_sets_->OnPushQueue(this); 82 work_queue_sets_->OnTaskPushedToEmptyQueue(this);
80 } 83 }
81 84
82 void WorkQueue::PopTaskForTest() { 85 void WorkQueue::PopTaskForTest() {
83 if (work_queue_.empty()) 86 if (work_queue_.empty())
84 return; 87 return;
85 work_queue_.pop_front(); 88 work_queue_.pop_front();
86 } 89 }
87 90
88 void WorkQueue::SwapLocked(WTF::Deque<TaskQueueImpl::Task>& incoming_queue) { 91 void WorkQueue::ReloadEmptyImmediateQueue() {
89 DCHECK(work_queue_.empty()); 92 DCHECK(work_queue_.empty());
90 work_queue_.swap(incoming_queue); 93
94 work_queue_ = task_queue_->TakeImmediateIncomingQueue();
91 if (work_queue_.empty()) 95 if (work_queue_.empty())
92 return; 96 return;
97
93 // If we hit the fence, pretend to WorkQueueSets that we're empty. 98 // If we hit the fence, pretend to WorkQueueSets that we're empty.
94 if (work_queue_sets_ && !BlockedByFence()) 99 if (work_queue_sets_ && !BlockedByFence())
95 work_queue_sets_->OnPushQueue(this); 100 work_queue_sets_->OnTaskPushedToEmptyQueue(this);
96 } 101 }
97 102
98 TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() { 103 TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() {
99 DCHECK(work_queue_sets_); 104 DCHECK(work_queue_sets_);
100 DCHECK(!work_queue_.empty()); 105 DCHECK(!work_queue_.empty());
101 106
102 // Skip over canceled tasks, except for the last one since we always return 107 // Skip over canceled tasks, except for the last one since we always return
103 // something. 108 // something.
104 while (work_queue_.size() > 1u && work_queue_.front().task.IsCancelled()) { 109 while (work_queue_.size() > 1u && work_queue_.front().task.IsCancelled()) {
105 work_queue_.pop_front(); 110 work_queue_.pop_front();
106 } 111 }
107 112
108 TaskQueueImpl::Task pending_task = work_queue_.takeFirst(); 113 TaskQueueImpl::Task pending_task = work_queue_.takeFirst();
114 // NB immediate tasks have a different pipeline to delayed ones.
115 if (queue_type_ == QueueType::IMMEDIATE && work_queue_.empty()) {
116 // Short-circuit the queue reload so that OnPopQueue does the right thing.
117 work_queue_ = task_queue_->TakeImmediateIncomingQueue();
118 }
119 // OnPopQueue calls GetFrontTaskEnqueueOrder which checks BlockedByFence() so
120 // we don't need to here.
109 work_queue_sets_->OnPopQueue(this); 121 work_queue_sets_->OnPopQueue(this);
110 task_queue_->TraceQueueSize(false); 122 task_queue_->TraceQueueSize(false);
111 return pending_task; 123 return pending_task;
112 } 124 }
113 125
114 void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) { 126 void WorkQueue::AssignToWorkQueueSets(WorkQueueSets* work_queue_sets) {
115 work_queue_sets_ = work_queue_sets; 127 work_queue_sets_ = work_queue_sets;
116 } 128 }
117 129
118 void WorkQueue::AssignSetIndex(size_t work_queue_set_index) { 130 void WorkQueue::AssignSetIndex(size_t work_queue_set_index) {
119 work_queue_set_index_ = work_queue_set_index; 131 work_queue_set_index_ = work_queue_set_index;
120 } 132 }
121 133
122 bool WorkQueue::InsertFence(EnqueueOrder fence) { 134 bool WorkQueue::InsertFence(EnqueueOrder fence) {
123 DCHECK_NE(fence, 0u); 135 DCHECK_NE(fence, 0u);
124 DCHECK(fence >= fence_ || fence == 1u); 136 DCHECK(fence >= fence_ || fence == 1u);
125 bool was_blocked_by_fence = BlockedByFence(); 137 bool was_blocked_by_fence = BlockedByFence();
126 fence_ = fence; 138 fence_ = fence;
127 // Moving the fence forward may unblock some tasks. 139 // Moving the fence forward may unblock some tasks.
128 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence && 140 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence &&
129 !BlockedByFence()) { 141 !BlockedByFence()) {
130 work_queue_sets_->OnPushQueue(this); 142 work_queue_sets_->OnTaskPushedToEmptyQueue(this);
131 return true; 143 return true;
132 } 144 }
133 // Fence insertion may have blocked all tasks in this work queue. 145 // Fence insertion may have blocked all tasks in this work queue.
134 if (BlockedByFence()) 146 if (BlockedByFence())
135 work_queue_sets_->OnQueueBlocked(this); 147 work_queue_sets_->OnQueueBlocked(this);
136 return false; 148 return false;
137 } 149 }
138 150
139 bool WorkQueue::RemoveFence() { 151 bool WorkQueue::RemoveFence() {
140 bool was_blocked_by_fence = BlockedByFence(); 152 bool was_blocked_by_fence = BlockedByFence();
141 fence_ = 0; 153 fence_ = 0;
142 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence) { 154 if (work_queue_sets_ && !work_queue_.empty() && was_blocked_by_fence) {
143 work_queue_sets_->OnPushQueue(this); 155 work_queue_sets_->OnTaskPushedToEmptyQueue(this);
144 return true; 156 return true;
145 } 157 }
146 return false; 158 return false;
147 } 159 }
148 160
149 bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const { 161 bool WorkQueue::ShouldRunBefore(const WorkQueue* other_queue) const {
150 DCHECK(!work_queue_.empty()); 162 DCHECK(!work_queue_.empty());
151 DCHECK(!other_queue->work_queue_.empty()); 163 DCHECK(!other_queue->work_queue_.empty());
152 EnqueueOrder enqueue_order = 0; 164 EnqueueOrder enqueue_order = 0;
153 EnqueueOrder other_enqueue_order = 0; 165 EnqueueOrder other_enqueue_order = 0;
154 bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order); 166 bool have_task = GetFrontTaskEnqueueOrder(&enqueue_order);
155 bool have_other_task = 167 bool have_other_task =
156 other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order); 168 other_queue->GetFrontTaskEnqueueOrder(&other_enqueue_order);
157 DCHECK(have_task); 169 DCHECK(have_task);
158 DCHECK(have_other_task); 170 DCHECK(have_other_task);
159 return enqueue_order < other_enqueue_order; 171 return enqueue_order < other_enqueue_order;
160 } 172 }
161 173
162 } // namespace internal 174 } // namespace internal
163 } // namespace scheduler 175 } // namespace scheduler
164 } // namespace blink 176 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698