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

Side by Side Diff: components/scheduler/child/task_queue_manager.cc

Issue 1259583006: Reland: Explicitly track the scheduler task enqueueing order in a new field (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix the DCHECK Created 5 years, 4 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/scheduler/child/task_queue_manager.h" 5 #include "components/scheduler/child/task_queue_manager.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 97 }
98 98
99 void TaskQueueManager::UnregisterAsUpdatableTaskQueue( 99 void TaskQueueManager::UnregisterAsUpdatableTaskQueue(
100 internal::TaskQueueImpl* queue) { 100 internal::TaskQueueImpl* queue) {
101 DCHECK(main_thread_checker_.CalledOnValidThread()); 101 DCHECK(main_thread_checker_.CalledOnValidThread());
102 updatable_queue_set_.erase(queue); 102 updatable_queue_set_.erase(queue);
103 } 103 }
104 104
105 void TaskQueueManager::UpdateWorkQueues( 105 void TaskQueueManager::UpdateWorkQueues(
106 bool should_trigger_wakeup, 106 bool should_trigger_wakeup,
107 const base::PendingTask* previous_task) { 107 const internal::TaskQueueImpl::Task* previous_task) {
108 DCHECK(main_thread_checker_.CalledOnValidThread()); 108 DCHECK(main_thread_checker_.CalledOnValidThread());
109 internal::LazyNow lazy_now(this); 109 internal::LazyNow lazy_now(this);
110 110
111 // Insert any newly updatable queues into the updatable_queue_set_. 111 // Insert any newly updatable queues into the updatable_queue_set_.
112 { 112 {
113 base::AutoLock lock(newly_updatable_lock_); 113 base::AutoLock lock(newly_updatable_lock_);
114 while (!newly_updatable_.empty()) { 114 while (!newly_updatable_.empty()) {
115 updatable_queue_set_.insert(newly_updatable_.back()); 115 updatable_queue_set_.insert(newly_updatable_.back());
116 newly_updatable_.pop_back(); 116 newly_updatable_.pop_back();
117 } 117 }
118 } 118 }
119 119
120 auto iter = updatable_queue_set_.begin(); 120 auto iter = updatable_queue_set_.begin();
121 while (iter != updatable_queue_set_.end()) { 121 while (iter != updatable_queue_set_.end()) {
122 internal::TaskQueueImpl* queue = *iter++; 122 internal::TaskQueueImpl* queue = *iter++;
123 // NOTE Update work queue may erase itself from |updatable_queue_set_|. 123 // NOTE Update work queue may erase itself from |updatable_queue_set_|.
124 // This is fine, erasing an element won't invalidate any interator, as long 124 // This is fine, erasing an element won't invalidate any interator, as long
125 // as the iterator isn't the element being delated. 125 // as the iterator isn't the element being delated.
126 if (queue->work_queue().empty()) 126 if (queue->work_queue().empty())
127 queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task); 127 queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task);
128 if (!queue->work_queue().empty()) {
129 // Currently we should not be getting tasks with delayed run times in any
130 // of the work queues.
131 DCHECK(queue->work_queue().front().delayed_run_time.is_null());
132 }
133 } 128 }
134 } 129 }
135 130
136 void TaskQueueManager::MaybePostDoWorkOnMainRunner() { 131 void TaskQueueManager::MaybePostDoWorkOnMainRunner() {
137 bool on_main_thread = main_task_runner_->BelongsToCurrentThread(); 132 bool on_main_thread = main_task_runner_->BelongsToCurrentThread();
138 if (on_main_thread) { 133 if (on_main_thread) {
139 // We only want one pending DoWork posted from the main thread, or we risk 134 // We only want one pending DoWork posted from the main thread, or we risk
140 // an explosion of pending DoWorks which could starve out everything else. 135 // an explosion of pending DoWorks which could starve out everything else.
141 if (pending_dowork_count_ > 0) { 136 if (pending_dowork_count_ > 0) {
142 return; 137 return;
143 } 138 }
144 pending_dowork_count_++; 139 pending_dowork_count_++;
145 main_task_runner_->PostTask(FROM_HERE, do_work_from_main_thread_closure_); 140 main_task_runner_->PostTask(FROM_HERE, do_work_from_main_thread_closure_);
146 } else { 141 } else {
147 main_task_runner_->PostTask(FROM_HERE, do_work_from_other_thread_closure_); 142 main_task_runner_->PostTask(FROM_HERE, do_work_from_other_thread_closure_);
148 } 143 }
149 } 144 }
150 145
151 void TaskQueueManager::DoWork(bool posted_from_main_thread) { 146 void TaskQueueManager::DoWork(bool posted_from_main_thread) {
152 if (posted_from_main_thread) { 147 if (posted_from_main_thread) {
153 pending_dowork_count_--; 148 pending_dowork_count_--;
154 DCHECK_GE(pending_dowork_count_, 0); 149 DCHECK_GE(pending_dowork_count_, 0);
155 } 150 }
156 DCHECK(main_thread_checker_.CalledOnValidThread()); 151 DCHECK(main_thread_checker_.CalledOnValidThread());
157 152
158 // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a 153 // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a
159 // pump-after-wakeup queue. 154 // pump-after-wakeup queue.
160 UpdateWorkQueues(false, nullptr); 155 UpdateWorkQueues(false, nullptr);
161 156
162 base::PendingTask previous_task((tracked_objects::Location()), 157 internal::TaskQueueImpl::Task previous_task;
163 (base::Closure()));
164 for (int i = 0; i < work_batch_size_; i++) { 158 for (int i = 0; i < work_batch_size_; i++) {
165 internal::TaskQueueImpl* queue; 159 internal::TaskQueueImpl* queue;
166 if (!SelectQueueToService(&queue)) 160 if (!SelectQueueToService(&queue))
167 return; 161 return;
168 // Note that this function won't post another call to DoWork if one is 162 // Note that this function won't post another call to DoWork if one is
169 // already pending, so it is safe to call it in a loop. 163 // already pending, so it is safe to call it in a loop.
170 MaybePostDoWorkOnMainRunner(); 164 MaybePostDoWorkOnMainRunner();
171 165
172 if (ProcessTaskFromWorkQueue(queue, &previous_task)) 166 if (ProcessTaskFromWorkQueue(queue, &previous_task))
173 return; // The TaskQueueManager got deleted, we must bail out. 167 return; // The TaskQueueManager got deleted, we must bail out.
(...skipping 11 matching lines...) Expand all
185 179
186 bool TaskQueueManager::SelectQueueToService( 180 bool TaskQueueManager::SelectQueueToService(
187 internal::TaskQueueImpl** out_queue) { 181 internal::TaskQueueImpl** out_queue) {
188 bool should_run = selector_.SelectQueueToService(out_queue); 182 bool should_run = selector_.SelectQueueToService(out_queue);
189 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 183 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
190 disabled_by_default_tracing_category_, "TaskQueueManager", this, 184 disabled_by_default_tracing_category_, "TaskQueueManager", this,
191 AsValueWithSelectorResult(should_run, *out_queue)); 185 AsValueWithSelectorResult(should_run, *out_queue));
192 return should_run; 186 return should_run;
193 } 187 }
194 188
195 void TaskQueueManager::DidQueueTask(const base::PendingTask& pending_task) { 189 void TaskQueueManager::DidQueueTask(
190 const internal::TaskQueueImpl::Task& pending_task) {
196 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); 191 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task);
197 } 192 }
198 193
199 bool TaskQueueManager::ProcessTaskFromWorkQueue( 194 bool TaskQueueManager::ProcessTaskFromWorkQueue(
200 internal::TaskQueueImpl* queue, 195 internal::TaskQueueImpl* queue,
201 base::PendingTask* out_previous_task) { 196 internal::TaskQueueImpl::Task* out_previous_task) {
202 DCHECK(main_thread_checker_.CalledOnValidThread()); 197 DCHECK(main_thread_checker_.CalledOnValidThread());
203 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); 198 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_);
204 base::PendingTask pending_task = queue->TakeTaskFromWorkQueue(); 199 // TODO(alexclarke): consider std::move() when allowed.
200 internal::TaskQueueImpl::Task pending_task = queue->TakeTaskFromWorkQueue();
205 201
206 if (queue->GetQuiescenceMonitored()) 202 if (queue->GetQuiescenceMonitored())
207 task_was_run_on_quiescence_monitored_queue_ = true; 203 task_was_run_on_quiescence_monitored_queue_ = true;
208 204
209 if (!pending_task.nestable && main_task_runner_->IsNested()) { 205 if (!pending_task.nestable && main_task_runner_->IsNested()) {
210 // Defer non-nestable work to the main task runner. NOTE these tasks can be 206 // Defer non-nestable work to the main task runner. NOTE these tasks can be
211 // arbitrarily delayed so the additional delay should not be a problem. 207 // arbitrarily delayed so the additional delay should not be a problem.
212 main_task_runner_->PostNonNestableTask(pending_task.posted_from, 208 main_task_runner_->PostNonNestableTask(pending_task.posted_from,
213 pending_task.task); 209 pending_task.task);
214 } else { 210 } else {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 state->EndArray(); 305 state->EndArray();
310 return state; 306 return state;
311 } 307 }
312 308
313 void TaskQueueManager::OnTaskQueueEnabled() { 309 void TaskQueueManager::OnTaskQueueEnabled() {
314 DCHECK(main_thread_checker_.CalledOnValidThread()); 310 DCHECK(main_thread_checker_.CalledOnValidThread());
315 MaybePostDoWorkOnMainRunner(); 311 MaybePostDoWorkOnMainRunner();
316 } 312 }
317 313
318 } // namespace scheduler 314 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/child/task_queue_manager.h ('k') | components/scheduler/child/task_queue_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698