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

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

Issue 1898233002: Report expected task queueing time via UMA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: RenderSchedulerImpl owns all the things. Created 4 years, 5 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/base/task_queue_manager.h" 5 #include "components/scheduler/base/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"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/trace_event/trace_event.h" 12 #include "base/trace_event/trace_event.h"
13 #include "components/scheduler/base/real_time_domain.h" 13 #include "components/scheduler/base/real_time_domain.h"
14 #include "components/scheduler/base/task_queue_impl.h" 14 #include "components/scheduler/base/task_queue_impl.h"
15 #include "components/scheduler/base/task_queue_manager_delegate.h" 15 #include "components/scheduler/base/task_queue_manager_delegate.h"
16 #include "components/scheduler/base/task_queue_selector.h" 16 #include "components/scheduler/base/task_queue_selector.h"
17 #include "components/scheduler/base/task_time_tracker.h"
17 #include "components/scheduler/base/work_queue.h" 18 #include "components/scheduler/base/work_queue.h"
18 #include "components/scheduler/base/work_queue_sets.h" 19 #include "components/scheduler/base/work_queue_sets.h"
19 20
20 namespace scheduler { 21 namespace scheduler {
21 22
22 namespace { 23 namespace {
23 const size_t kRecordRecordTaskDelayHistogramsEveryNTasks = 10; 24 const size_t kRecordRecordTaskDelayHistogramsEveryNTasks = 10;
24 25
25 void RecordDelayedTaskLateness(base::TimeDelta lateness) { 26 void RecordDelayedTaskLateness(base::TimeDelta lateness) {
26 UMA_HISTOGRAM_TIMES("RendererScheduler.TaskQueueManager.DelayedTaskLateness", 27 UMA_HISTOGRAM_TIMES("RendererScheduler.TaskQueueManager.DelayedTaskLateness",
(...skipping 10 matching lines...) Expand all
37 TaskQueueManager::TaskQueueManager( 38 TaskQueueManager::TaskQueueManager(
38 scoped_refptr<TaskQueueManagerDelegate> delegate, 39 scoped_refptr<TaskQueueManagerDelegate> delegate,
39 const char* tracing_category, 40 const char* tracing_category,
40 const char* disabled_by_default_tracing_category, 41 const char* disabled_by_default_tracing_category,
41 const char* disabled_by_default_verbose_tracing_category) 42 const char* disabled_by_default_verbose_tracing_category)
42 : real_time_domain_(new RealTimeDomain(tracing_category)), 43 : real_time_domain_(new RealTimeDomain(tracing_category)),
43 delegate_(delegate), 44 delegate_(delegate),
44 task_was_run_on_quiescence_monitored_queue_(false), 45 task_was_run_on_quiescence_monitored_queue_(false),
45 work_batch_size_(1), 46 work_batch_size_(1),
46 task_count_(0), 47 task_count_(0),
48 task_time_tracker_(nullptr),
47 tracing_category_(tracing_category), 49 tracing_category_(tracing_category),
48 disabled_by_default_tracing_category_( 50 disabled_by_default_tracing_category_(
49 disabled_by_default_tracing_category), 51 disabled_by_default_tracing_category),
50 disabled_by_default_verbose_tracing_category_( 52 disabled_by_default_verbose_tracing_category_(
51 disabled_by_default_verbose_tracing_category), 53 disabled_by_default_verbose_tracing_category),
52 currently_executing_task_queue_(nullptr), 54 currently_executing_task_queue_(nullptr),
53 observer_(nullptr), 55 observer_(nullptr),
54 deletion_sentinel_(new DeletionSentinel()), 56 deletion_sentinel_(new DeletionSentinel()),
55 weak_factory_(this) { 57 weak_factory_(this) {
56 DCHECK(delegate->RunsTasksOnCurrentThread()); 58 DCHECK(delegate->RunsTasksOnCurrentThread());
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 123
122 // Add |task_queue| to |queues_to_delete_| so we can prevent it from being 124 // Add |task_queue| to |queues_to_delete_| so we can prevent it from being
123 // freed while any of our structures hold hold a raw pointer to it. 125 // freed while any of our structures hold hold a raw pointer to it.
124 queues_to_delete_.insert(task_queue); 126 queues_to_delete_.insert(task_queue);
125 queues_.erase(task_queue); 127 queues_.erase(task_queue);
126 selector_.RemoveQueue(task_queue.get()); 128 selector_.RemoveQueue(task_queue.get());
127 } 129 }
128 130
129 void TaskQueueManager::UpdateWorkQueues( 131 void TaskQueueManager::UpdateWorkQueues(
130 bool should_trigger_wakeup, 132 bool should_trigger_wakeup,
131 const internal::TaskQueueImpl::Task* previous_task) { 133 const internal::TaskQueueImpl::Task* previous_task,
134 LazyNow lazy_now) {
132 TRACE_EVENT0(disabled_by_default_tracing_category_, 135 TRACE_EVENT0(disabled_by_default_tracing_category_,
133 "TaskQueueManager::UpdateWorkQueues"); 136 "TaskQueueManager::UpdateWorkQueues");
134 137
135 for (TimeDomain* time_domain : time_domains_) { 138 for (TimeDomain* time_domain : time_domains_) {
136 time_domain->UpdateWorkQueues(should_trigger_wakeup, previous_task); 139 LazyNow lazy_now_in_domain = time_domain == real_time_domain_.get()
140 ? lazy_now
141 : time_domain->CreateLazyNow();
142 time_domain->UpdateWorkQueues(should_trigger_wakeup, previous_task,
143 lazy_now_in_domain);
137 } 144 }
138 } 145 }
139 146
140 void TaskQueueManager::MaybeScheduleImmediateWork( 147 void TaskQueueManager::MaybeScheduleImmediateWork(
141 const tracked_objects::Location& from_here) { 148 const tracked_objects::Location& from_here) {
142 bool on_main_thread = delegate_->BelongsToCurrentThread(); 149 bool on_main_thread = delegate_->BelongsToCurrentThread();
143 // De-duplicate DoWork posts. 150 // De-duplicate DoWork posts.
144 if (on_main_thread) { 151 if (on_main_thread) {
145 if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) { 152 if (!main_thread_pending_wakeups_.insert(base::TimeTicks()).second) {
146 return; 153 return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 if (from_main_thread) { 187 if (from_main_thread) {
181 main_thread_pending_wakeups_.erase(run_time); 188 main_thread_pending_wakeups_.erase(run_time);
182 } else { 189 } else {
183 base::AutoLock lock(other_thread_lock_); 190 base::AutoLock lock(other_thread_lock_);
184 other_thread_pending_wakeups_.erase(run_time); 191 other_thread_pending_wakeups_.erase(run_time);
185 } 192 }
186 193
187 if (!delegate_->IsNested()) 194 if (!delegate_->IsNested())
188 queues_to_delete_.clear(); 195 queues_to_delete_.clear();
189 196
197 LazyNow lazy_now(real_time_domain()->CreateLazyNow());
198 base::TimeTicks task_start_time;
199
200 if (!delegate_->IsNested() && task_time_tracker_)
201 task_start_time = lazy_now.Now();
202
190 // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a 203 // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a
191 // pump-after-wakeup queue. 204 // pump-after-wakeup queue.
192 UpdateWorkQueues(false, nullptr); 205 UpdateWorkQueues(false, nullptr, lazy_now);
193 206
194 internal::TaskQueueImpl::Task previous_task; 207 internal::TaskQueueImpl::Task previous_task;
208
195 for (int i = 0; i < work_batch_size_; i++) { 209 for (int i = 0; i < work_batch_size_; i++) {
196 internal::WorkQueue* work_queue; 210 internal::WorkQueue* work_queue;
197 if (!SelectWorkQueueToService(&work_queue)) { 211 if (!SelectWorkQueueToService(&work_queue)) {
198 break; 212 break;
199 } 213 }
200 214
201 bool should_trigger_wakeup = work_queue->task_queue()->wakeup_policy() == 215 bool should_trigger_wakeup = work_queue->task_queue()->wakeup_policy() ==
202 TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES; 216 TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES;
217
203 switch (ProcessTaskFromWorkQueue(work_queue, &previous_task)) { 218 switch (ProcessTaskFromWorkQueue(work_queue, &previous_task)) {
204 case ProcessTaskResult::DEFERRED: 219 case ProcessTaskResult::DEFERRED:
205 // If a task was deferred, try again with another task. Note that this 220 // If a task was deferred, try again with another task. Note that this
206 // means deferred tasks (i.e. non-nestable tasks) will never trigger 221 // means deferred tasks (i.e. non-nestable tasks) will never trigger
207 // queue wake-ups. 222 // queue wake-ups.
208 continue; 223 continue;
209 case ProcessTaskResult::EXECUTED: 224 case ProcessTaskResult::EXECUTED:
210 break; 225 break;
211 case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED: 226 case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED:
212 return; // The TaskQueueManager got deleted, we must bail out. 227 return; // The TaskQueueManager got deleted, we must bail out.
213 } 228 }
229
230 lazy_now = real_time_domain()->CreateLazyNow();
231 if (!delegate_->IsNested() && task_time_tracker_) {
232 // Only report top level task durations.
233 base::TimeTicks task_end_time = real_time_domain()->Now();
alex clarke (OOO till 29th) 2016/07/06 09:51:39 Can you do this? if (!delegate_->IsNested() && ta
tdresser 2016/07/06 13:25:34 Done.
234 task_time_tracker_->ReportTaskTime(task_start_time, task_end_time);
235 task_start_time = task_end_time;
236 lazy_now = LazyNow(task_end_time);
237 }
238
214 work_queue = nullptr; // The queue may have been unregistered. 239 work_queue = nullptr; // The queue may have been unregistered.
215 240
216 UpdateWorkQueues(should_trigger_wakeup, &previous_task); 241 UpdateWorkQueues(should_trigger_wakeup, &previous_task, lazy_now);
217 242
218 // Only run a single task per batch in nested run loops so that we can 243 // Only run a single task per batch in nested run loops so that we can
219 // properly exit the nested loop when someone calls RunLoop::Quit(). 244 // properly exit the nested loop when someone calls RunLoop::Quit().
220 if (delegate_->IsNested()) 245 if (delegate_->IsNested())
221 break; 246 break;
222 } 247 }
223 248
224 // TODO(alexclarke): Consider refactoring the above loop to terminate only 249 // TODO(alexclarke): Consider refactoring the above loop to terminate only
225 // when there's no more work left to be done, rather than posting a 250 // when there's no more work left to be done, rather than posting a
226 // continuation task. 251 // continuation task.
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 internal::WorkQueue* work_queue) { 434 internal::WorkQueue* work_queue) {
410 DCHECK(main_thread_checker_.CalledOnValidThread()); 435 DCHECK(main_thread_checker_.CalledOnValidThread());
411 DCHECK(!work_queue->Empty()); 436 DCHECK(!work_queue->Empty());
412 if (observer_) { 437 if (observer_) {
413 observer_->OnTriedToExecuteBlockedTask(*work_queue->task_queue(), 438 observer_->OnTriedToExecuteBlockedTask(*work_queue->task_queue(),
414 *work_queue->GetFrontTask()); 439 *work_queue->GetFrontTask());
415 } 440 }
416 } 441 }
417 442
418 } // namespace scheduler 443 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698