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

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

Issue 1106213002: Adds a SHUTDOWN_TASK_QUEUE and a PreShutdown api to the scheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review comments. Created 5 years, 7 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 "components/scheduler/child/scheduler_helper.h" 5 #include "components/scheduler/child/scheduler_helper.h"
6 6
7 #include "base/synchronization/waitable_event.h"
7 #include "base/trace_event/trace_event.h" 8 #include "base/trace_event/trace_event.h"
8 #include "base/trace_event/trace_event_argument.h" 9 #include "base/trace_event/trace_event_argument.h"
9 #include "components/scheduler/child/nestable_single_thread_task_runner.h" 10 #include "components/scheduler/child/nestable_single_thread_task_runner.h"
10 #include "components/scheduler/child/time_source.h" 11 #include "components/scheduler/child/time_source.h"
11 12
12 namespace scheduler { 13 namespace scheduler {
13 14
14 SchedulerHelper::SchedulerHelper( 15 SchedulerHelper::SchedulerHelper(
15 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, 16 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
16 SchedulerHelperDelegate* scheduler_helper_delegate, 17 SchedulerHelperDelegate* scheduler_helper_delegate,
17 const char* tracing_category, 18 const char* tracing_category,
18 const char* disabled_by_default_tracing_category, 19 const char* disabled_by_default_tracing_category,
19 const char* idle_period_tracing_name, 20 const char* idle_period_tracing_name,
20 size_t total_task_queue_count, 21 size_t total_task_queue_count,
21 base::TimeDelta required_quiescence_duration_before_long_idle_period) 22 base::TimeDelta required_quiescence_duration_before_long_idle_period)
22 : task_queue_selector_(new PrioritizingTaskQueueSelector()), 23 : task_queue_selector_(new PrioritizingTaskQueueSelector()),
23 task_queue_manager_( 24 task_queue_manager_(
24 new TaskQueueManager(total_task_queue_count, 25 new TaskQueueManager(total_task_queue_count,
25 main_task_runner, 26 main_task_runner,
26 task_queue_selector_.get(), 27 task_queue_selector_.get(),
27 disabled_by_default_tracing_category)), 28 disabled_by_default_tracing_category)),
28 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), 29 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD),
29 scheduler_helper_delegate_(scheduler_helper_delegate), 30 scheduler_helper_delegate_(scheduler_helper_delegate),
30 control_task_runner_( 31 control_task_runner_(
31 task_queue_manager_->TaskRunnerForQueue(QueueId::CONTROL_TASK_QUEUE)), 32 task_queue_manager_->TaskRunnerForQueue(QueueId::CONTROL_TASK_QUEUE)),
32 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue( 33 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue(
33 QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE)), 34 QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
34 default_task_runner_( 35 default_task_runner_(
35 task_queue_manager_->TaskRunnerForQueue(QueueId::DEFAULT_TASK_QUEUE)), 36 task_queue_manager_->TaskRunnerForQueue(QueueId::DEFAULT_TASK_QUEUE)),
37 shutdown_task_runner_(task_queue_manager_->TaskRunnerForQueue(
38 QueueId::SHUTDOWN_TASK_QUEUE)),
39 total_task_queue_count_(total_task_queue_count),
40 in_preshutdown_(false),
36 quiescence_monitored_task_queue_mask_( 41 quiescence_monitored_task_queue_mask_(
37 ((1ull << total_task_queue_count) - 1ull) & 42 ((1ull << total_task_queue_count) - 1ull) &
38 ~(1ull << QueueId::IDLE_TASK_QUEUE) & 43 ~(1ull << QueueId::IDLE_TASK_QUEUE) &
39 ~(1ull << QueueId::CONTROL_TASK_QUEUE) & 44 ~(1ull << QueueId::CONTROL_TASK_QUEUE) &
40 ~(1ull << QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE)), 45 ~(1ull << QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
41 required_quiescence_duration_before_long_idle_period_( 46 required_quiescence_duration_before_long_idle_period_(
42 required_quiescence_duration_before_long_idle_period), 47 required_quiescence_duration_before_long_idle_period),
43 time_source_(new TimeSource), 48 time_source_(new TimeSource),
44 tracing_category_(tracing_category), 49 tracing_category_(tracing_category),
45 disabled_by_default_tracing_category_( 50 disabled_by_default_tracing_category_(
(...skipping 10 matching lines...) Expand all
56 enable_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind( 61 enable_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind(
57 &SchedulerHelper::EnableLongIdlePeriodAfterWakeup, weak_scheduler_ptr_)); 62 &SchedulerHelper::EnableLongIdlePeriodAfterWakeup, weak_scheduler_ptr_));
58 63
59 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( 64 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
60 task_queue_manager_->TaskRunnerForQueue(QueueId::IDLE_TASK_QUEUE), 65 task_queue_manager_->TaskRunnerForQueue(QueueId::IDLE_TASK_QUEUE),
61 control_task_after_wakeup_runner_, 66 control_task_after_wakeup_runner_,
62 base::Bind(&SchedulerHelper::CurrentIdleTaskDeadlineCallback, 67 base::Bind(&SchedulerHelper::CurrentIdleTaskDeadlineCallback,
63 weak_scheduler_ptr_), 68 weak_scheduler_ptr_),
64 tracing_category)); 69 tracing_category));
65 70
66 task_queue_selector_->SetQueuePriority( 71 SetQueuePriority(QueueId::CONTROL_TASK_QUEUE,
67 QueueId::CONTROL_TASK_QUEUE, 72 PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
68 PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
69 73
70 task_queue_selector_->SetQueuePriority( 74 SetQueuePriority(QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE,
71 QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE, 75 PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
72 PrioritizingTaskQueueSelector::CONTROL_PRIORITY);
73 task_queue_manager_->SetPumpPolicy( 76 task_queue_manager_->SetPumpPolicy(
74 QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE, 77 QueueId::CONTROL_TASK_AFTER_WAKEUP_QUEUE,
75 TaskQueueManager::PumpPolicy::AFTER_WAKEUP); 78 TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
76 79
77 task_queue_selector_->DisableQueue(QueueId::IDLE_TASK_QUEUE); 80 DisableQueue(QueueId::IDLE_TASK_QUEUE);
78 task_queue_manager_->SetPumpPolicy(QueueId::IDLE_TASK_QUEUE, 81 task_queue_manager_->SetPumpPolicy(QueueId::IDLE_TASK_QUEUE,
79 TaskQueueManager::PumpPolicy::MANUAL); 82 TaskQueueManager::PumpPolicy::MANUAL);
80 83
81 for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) { 84 for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) {
82 task_queue_manager_->SetQueueName( 85 task_queue_manager_->SetQueueName(
83 i, TaskQueueIdToString(static_cast<QueueId>(i))); 86 i, TaskQueueIdToString(static_cast<QueueId>(i)));
84 } 87 }
85 88
86 // TODO(skyostil): Increase this to 4 (crbug.com/444764). 89 // TODO(skyostil): Increase this to 4 (crbug.com/444764).
87 task_queue_manager_->SetWorkBatchSize(1); 90 task_queue_manager_->SetWorkBatchSize(1);
88 } 91 }
89 92
90 SchedulerHelper::~SchedulerHelper() { 93 SchedulerHelper::~SchedulerHelper() {
91 } 94 }
92 95
93 SchedulerHelper::SchedulerHelperDelegate::SchedulerHelperDelegate() { 96 SchedulerHelper::SchedulerHelperDelegate::SchedulerHelperDelegate() {
94 } 97 }
95 98
96 SchedulerHelper::SchedulerHelperDelegate::~SchedulerHelperDelegate() { 99 SchedulerHelper::SchedulerHelperDelegate::~SchedulerHelperDelegate() {
97 } 100 }
98 101
102 void SchedulerHelper::PreShutdown() {
103 CheckOnValidThread();
104 DCHECK(!in_preshutdown_);
105 TRACE_EVENT0(disabled_by_default_tracing_category_, "PreShutdown");
106 // Disable everything except the shutdown task queue.
107 for (size_t i = 0; i < total_task_queue_count_; i++) {
108 if (i == SHUTDOWN_TASK_QUEUE)
109 continue;
110 DisableQueue(i);
111 }
112 // Ensure that the queues don't get re-enabled.
113 in_preshutdown_ = true;
114 }
115
99 void SchedulerHelper::Shutdown() { 116 void SchedulerHelper::Shutdown() {
100 CheckOnValidThread(); 117 CheckOnValidThread();
101 task_queue_manager_.reset(); 118 task_queue_manager_.reset();
102 } 119 }
103 120
104 scoped_refptr<base::SingleThreadTaskRunner> 121 scoped_refptr<base::SingleThreadTaskRunner>
105 SchedulerHelper::DefaultTaskRunner() { 122 SchedulerHelper::DefaultTaskRunner() {
106 CheckOnValidThread(); 123 CheckOnValidThread();
107 return default_task_runner_; 124 return default_task_runner_;
108 } 125 }
109 126
110 scoped_refptr<SingleThreadIdleTaskRunner> SchedulerHelper::IdleTaskRunner() { 127 scoped_refptr<SingleThreadIdleTaskRunner> SchedulerHelper::IdleTaskRunner() {
111 CheckOnValidThread(); 128 CheckOnValidThread();
112 return idle_task_runner_; 129 return idle_task_runner_;
113 } 130 }
114 131
115 scoped_refptr<base::SingleThreadTaskRunner> 132 scoped_refptr<base::SingleThreadTaskRunner>
133 SchedulerHelper::ShutdownTaskRunner() {
134 return shutdown_task_runner_;
135 }
136
137 scoped_refptr<base::SingleThreadTaskRunner>
116 SchedulerHelper::ControlTaskRunner() { 138 SchedulerHelper::ControlTaskRunner() {
117 return control_task_runner_; 139 return control_task_runner_;
118 } 140 }
119 141
120 void SchedulerHelper::CurrentIdleTaskDeadlineCallback( 142 void SchedulerHelper::CurrentIdleTaskDeadlineCallback(
121 base::TimeTicks* deadline_out) const { 143 base::TimeTicks* deadline_out) const {
122 CheckOnValidThread(); 144 CheckOnValidThread();
123 *deadline_out = idle_period_deadline_; 145 *deadline_out = idle_period_deadline_;
124 } 146 }
125 147
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 269
248 void SchedulerHelper::StartIdlePeriod(IdlePeriodState new_state, 270 void SchedulerHelper::StartIdlePeriod(IdlePeriodState new_state,
249 base::TimeTicks now, 271 base::TimeTicks now,
250 base::TimeTicks idle_period_deadline, 272 base::TimeTicks idle_period_deadline,
251 bool post_end_idle_period) { 273 bool post_end_idle_period) {
252 DCHECK_GT(idle_period_deadline, now); 274 DCHECK_GT(idle_period_deadline, now);
253 TRACE_EVENT_ASYNC_BEGIN0(tracing_category_, idle_period_tracing_name_, this); 275 TRACE_EVENT_ASYNC_BEGIN0(tracing_category_, idle_period_tracing_name_, this);
254 CheckOnValidThread(); 276 CheckOnValidThread();
255 DCHECK(IsInIdlePeriod(new_state)); 277 DCHECK(IsInIdlePeriod(new_state));
256 278
257 task_queue_selector_->EnableQueue( 279 EnableQueue(QueueId::IDLE_TASK_QUEUE,
258 QueueId::IDLE_TASK_QUEUE, 280 PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
259 PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
260 task_queue_manager_->PumpQueue(QueueId::IDLE_TASK_QUEUE); 281 task_queue_manager_->PumpQueue(QueueId::IDLE_TASK_QUEUE);
261 idle_period_state_ = new_state; 282 idle_period_state_ = new_state;
262 283
263 idle_period_deadline_ = idle_period_deadline; 284 idle_period_deadline_ = idle_period_deadline;
264 if (post_end_idle_period) { 285 if (post_end_idle_period) {
265 control_task_runner_->PostDelayedTask(FROM_HERE, 286 control_task_runner_->PostDelayedTask(FROM_HERE,
266 end_idle_period_closure_.callback(), 287 end_idle_period_closure_.callback(),
267 idle_period_deadline_ - now); 288 idle_period_deadline_ - now);
268 } 289 }
269 } 290 }
(...skipping 16 matching lines...) Expand all
286 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing); 307 TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing);
287 if (is_tracing && !idle_period_deadline_.is_null() && 308 if (is_tracing && !idle_period_deadline_.is_null() &&
288 base::TimeTicks::Now() > idle_period_deadline_) { 309 base::TimeTicks::Now() > idle_period_deadline_) {
289 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( 310 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
290 tracing_category_, idle_period_tracing_name_, this, "DeadlineOverrun", 311 tracing_category_, idle_period_tracing_name_, this, "DeadlineOverrun",
291 idle_period_deadline_.ToInternalValue()); 312 idle_period_deadline_.ToInternalValue());
292 } 313 }
293 TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this); 314 TRACE_EVENT_ASYNC_END0(tracing_category_, idle_period_tracing_name_, this);
294 } 315 }
295 316
296 task_queue_selector_->DisableQueue(QueueId::IDLE_TASK_QUEUE); 317 DisableQueue(QueueId::IDLE_TASK_QUEUE);
297 idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD; 318 idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD;
298 idle_period_deadline_ = base::TimeTicks(); 319 idle_period_deadline_ = base::TimeTicks();
299 } 320 }
300 321
301 // static 322 // static
302 bool SchedulerHelper::IsInIdlePeriod(IdlePeriodState state) { 323 bool SchedulerHelper::IsInIdlePeriod(IdlePeriodState state) {
303 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD; 324 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD;
304 } 325 }
305 326
306 bool SchedulerHelper::CanExceedIdleDeadlineIfRequired() const { 327 bool SchedulerHelper::CanExceedIdleDeadlineIfRequired() const {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 369
349 bool SchedulerHelper::IsQueueEmpty(size_t queue_index) const { 370 bool SchedulerHelper::IsQueueEmpty(size_t queue_index) const {
350 CheckOnValidThread(); 371 CheckOnValidThread();
351 return task_queue_manager_->IsQueueEmpty(queue_index); 372 return task_queue_manager_->IsQueueEmpty(queue_index);
352 } 373 }
353 374
354 void SchedulerHelper::SetQueuePriority( 375 void SchedulerHelper::SetQueuePriority(
355 size_t queue_index, 376 size_t queue_index,
356 PrioritizingTaskQueueSelector::QueuePriority priority) { 377 PrioritizingTaskQueueSelector::QueuePriority priority) {
357 CheckOnValidThread(); 378 CheckOnValidThread();
379 if (in_preshutdown_)
380 return;
358 return task_queue_selector_->SetQueuePriority(queue_index, priority); 381 return task_queue_selector_->SetQueuePriority(queue_index, priority);
359 } 382 }
360 383
361 void SchedulerHelper::EnableQueue( 384 void SchedulerHelper::EnableQueue(
362 size_t queue_index, 385 size_t queue_index,
363 PrioritizingTaskQueueSelector::QueuePriority priority) { 386 PrioritizingTaskQueueSelector::QueuePriority priority) {
364 CheckOnValidThread(); 387 CheckOnValidThread();
388 if (in_preshutdown_)
389 return;
365 task_queue_selector_->EnableQueue(queue_index, priority); 390 task_queue_selector_->EnableQueue(queue_index, priority);
366 } 391 }
367 392
368 void SchedulerHelper::DisableQueue(size_t queue_index) { 393 void SchedulerHelper::DisableQueue(size_t queue_index) {
369 CheckOnValidThread(); 394 CheckOnValidThread();
395 if (in_preshutdown_)
396 return;
370 task_queue_selector_->DisableQueue(queue_index); 397 task_queue_selector_->DisableQueue(queue_index);
371 } 398 }
372 399
373 bool SchedulerHelper::IsQueueEnabled(size_t queue_index) const { 400 bool SchedulerHelper::IsQueueEnabled(size_t queue_index) const {
374 CheckOnValidThread(); 401 CheckOnValidThread();
375 return task_queue_selector_->IsQueueEnabled(queue_index); 402 return task_queue_selector_->IsQueueEnabled(queue_index);
376 } 403 }
377 404
378 // static 405 // static
379 const char* SchedulerHelper::TaskQueueIdToString(QueueId queue_id) { 406 const char* SchedulerHelper::TaskQueueIdToString(QueueId queue_id) {
380 switch (queue_id) { 407 switch (queue_id) {
381 case DEFAULT_TASK_QUEUE: 408 case DEFAULT_TASK_QUEUE:
382 return "default_tq"; 409 return "default_tq";
383 case IDLE_TASK_QUEUE: 410 case IDLE_TASK_QUEUE:
384 return "idle_tq"; 411 return "idle_tq";
412 case SHUTDOWN_TASK_QUEUE:
413 return "shutdown_tq";
385 case CONTROL_TASK_QUEUE: 414 case CONTROL_TASK_QUEUE:
386 return "control_tq"; 415 return "control_tq";
387 case CONTROL_TASK_AFTER_WAKEUP_QUEUE: 416 case CONTROL_TASK_AFTER_WAKEUP_QUEUE:
388 return "control_after_wakeup_tq"; 417 return "control_after_wakeup_tq";
389 default: 418 default:
390 NOTREACHED(); 419 NOTREACHED();
391 return nullptr; 420 return nullptr;
392 } 421 }
393 } 422 }
394 423
(...skipping 25 matching lines...) Expand all
420 } 449 }
421 450
422 void SchedulerHelper::RemoveTaskObserver( 451 void SchedulerHelper::RemoveTaskObserver(
423 base::MessageLoop::TaskObserver* task_observer) { 452 base::MessageLoop::TaskObserver* task_observer) {
424 CheckOnValidThread(); 453 CheckOnValidThread();
425 if (task_queue_manager_) 454 if (task_queue_manager_)
426 task_queue_manager_->RemoveTaskObserver(task_observer); 455 task_queue_manager_->RemoveTaskObserver(task_observer);
427 } 456 }
428 457
429 } // namespace scheduler 458 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/child/scheduler_helper.h ('k') | components/scheduler/child/scheduler_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698