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

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

Issue 1441073006: Move throttling of background timers into the renderer scheduler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Last few changes Sami requested Created 5 years 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/base/task_queue_impl.h" 5 #include "components/scheduler/base/task_queue_impl.h"
6 6
7 #include "components/scheduler/base/task_queue_manager.h" 7 #include "components/scheduler/base/task_queue_manager.h"
8 #include "components/scheduler/base/task_queue_manager_delegate.h" 8 #include "components/scheduler/base/task_queue_manager_delegate.h"
9 #include "components/scheduler/base/time_domain.h" 9 #include "components/scheduler/base/time_domain.h"
10 10
11 namespace scheduler { 11 namespace scheduler {
12 namespace internal { 12 namespace internal {
13 13
14 TaskQueueImpl::TaskQueueImpl( 14 TaskQueueImpl::TaskQueueImpl(
15 TaskQueueManager* task_queue_manager, 15 TaskQueueManager* task_queue_manager,
16 const scoped_refptr<TimeDomain>& time_domain, 16 TimeDomain* time_domain,
17 const Spec& spec, 17 const Spec& spec,
18 const char* disabled_by_default_tracing_category, 18 const char* disabled_by_default_tracing_category,
19 const char* disabled_by_default_verbose_tracing_category) 19 const char* disabled_by_default_verbose_tracing_category)
20 : thread_id_(base::PlatformThread::CurrentId()), 20 : thread_id_(base::PlatformThread::CurrentId()),
21 any_thread_(task_queue_manager, spec.pump_policy, time_domain), 21 any_thread_(task_queue_manager, spec.pump_policy, time_domain),
22 name_(spec.name), 22 name_(spec.name),
23 disabled_by_default_tracing_category_( 23 disabled_by_default_tracing_category_(
24 disabled_by_default_tracing_category), 24 disabled_by_default_tracing_category),
25 disabled_by_default_verbose_tracing_category_( 25 disabled_by_default_verbose_tracing_category_(
26 disabled_by_default_verbose_tracing_category), 26 disabled_by_default_verbose_tracing_category),
27 main_thread_only_(task_queue_manager), 27 main_thread_only_(task_queue_manager),
28 wakeup_policy_(spec.wakeup_policy), 28 wakeup_policy_(spec.wakeup_policy),
29 should_monitor_quiescence_(spec.should_monitor_quiescence), 29 should_monitor_quiescence_(spec.should_monitor_quiescence),
30 should_notify_observers_(spec.should_notify_observers) { 30 should_notify_observers_(spec.should_notify_observers) {
31 DCHECK(time_domain.get()); 31 DCHECK(time_domain);
32 time_domain->RegisterQueue(this);
32 } 33 }
33 34
34 TaskQueueImpl::~TaskQueueImpl() {} 35 TaskQueueImpl::~TaskQueueImpl() {
36 base::AutoLock lock(any_thread_lock_);
37 if (any_thread().time_domain)
38 any_thread().time_domain->UnregisterQueue(this);
39 }
35 40
36 TaskQueueImpl::Task::Task() 41 TaskQueueImpl::Task::Task()
37 : PendingTask(tracked_objects::Location(), 42 : PendingTask(tracked_objects::Location(),
38 base::Closure(), 43 base::Closure(),
39 base::TimeTicks(), 44 base::TimeTicks(),
40 true), 45 true),
41 #ifndef NDEBUG 46 #ifndef NDEBUG
42 enqueue_order_set_(false), 47 enqueue_order_set_(false),
43 #endif 48 #endif
44 enqueue_order_(0) { 49 enqueue_order_(0) {
45 sequence_num = 0; 50 sequence_num = 0;
46 } 51 }
47 52
48 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, 53 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
49 const base::Closure& task, 54 const base::Closure& task,
50 int sequence_number, 55 int sequence_number,
51 bool nestable) 56 bool nestable)
52 : PendingTask(posted_from, task, base::TimeTicks(), nestable), 57 : PendingTask(posted_from, task, base::TimeTicks(), nestable),
53 #ifndef NDEBUG 58 #ifndef NDEBUG
54 enqueue_order_set_(false), 59 enqueue_order_set_(false),
55 #endif 60 #endif
56 enqueue_order_(0) { 61 enqueue_order_(0) {
57 sequence_num = sequence_number; 62 sequence_num = sequence_number;
58 } 63 }
59 64
60 TaskQueueImpl::AnyThread::AnyThread( 65 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager,
61 TaskQueueManager* task_queue_manager, 66 PumpPolicy pump_policy,
62 PumpPolicy pump_policy, 67 TimeDomain* time_domain)
63 const scoped_refptr<TimeDomain>& time_domain)
64 : task_queue_manager(task_queue_manager), 68 : task_queue_manager(task_queue_manager),
65 pump_policy(pump_policy), 69 pump_policy(pump_policy),
66 time_domain(time_domain) {} 70 time_domain(time_domain) {}
67 71
68 TaskQueueImpl::AnyThread::~AnyThread() {} 72 TaskQueueImpl::AnyThread::~AnyThread() {}
69 73
70 TaskQueueImpl::MainThreadOnly::MainThreadOnly( 74 TaskQueueImpl::MainThreadOnly::MainThreadOnly(
71 TaskQueueManager* task_queue_manager) 75 TaskQueueManager* task_queue_manager)
72 : task_queue_manager(task_queue_manager), 76 : task_queue_manager(task_queue_manager),
73 set_index(0) {} 77 set_index(0) {}
74 78
75 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} 79 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
76 80
77 void TaskQueueImpl::UnregisterTaskQueue() { 81 void TaskQueueImpl::UnregisterTaskQueue() {
78 base::AutoLock lock(any_thread_lock_); 82 base::AutoLock lock(any_thread_lock_);
79 if (!any_thread().task_queue_manager) 83 if (!any_thread().task_queue_manager)
80 return; 84 return;
81 any_thread().time_domain->UnregisterQueue(this); 85 if (any_thread().time_domain)
86 any_thread().time_domain->UnregisterQueue(this);
82 any_thread().time_domain = nullptr; 87 any_thread().time_domain = nullptr;
83 any_thread().task_queue_manager->UnregisterTaskQueue(this); 88 any_thread().task_queue_manager->UnregisterTaskQueue(this);
84 89
85 any_thread().task_queue_manager = nullptr; 90 any_thread().task_queue_manager = nullptr;
86 main_thread_only().task_queue_manager = nullptr; 91 main_thread_only().task_queue_manager = nullptr;
87 any_thread().delayed_task_queue = std::priority_queue<Task>(); 92 any_thread().delayed_task_queue = std::priority_queue<Task>();
88 any_thread().incoming_queue = std::queue<Task>(); 93 any_thread().incoming_queue = std::queue<Task>();
89 main_thread_only().work_queue = std::queue<Task>(); 94 main_thread_only().work_queue = std::queue<Task>();
90 } 95 }
91 96
92 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { 97 bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
93 base::AutoLock lock(any_thread_lock_); 98 base::AutoLock lock(any_thread_lock_);
94 return base::PlatformThread::CurrentId() == thread_id_; 99 return base::PlatformThread::CurrentId() == thread_id_;
95 } 100 }
96 101
97 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, 102 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
98 const base::Closure& task, 103 const base::Closure& task,
99 base::TimeDelta delay) { 104 base::TimeDelta delay) {
100 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); 105 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL);
101 } 106 }
102 107
103 bool TaskQueueImpl::PostNonNestableDelayedTask( 108 bool TaskQueueImpl::PostNonNestableDelayedTask(
104 const tracked_objects::Location& from_here, 109 const tracked_objects::Location& from_here,
105 const base::Closure& task, 110 const base::Closure& task,
106 base::TimeDelta delay) { 111 base::TimeDelta delay) {
107 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); 112 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE);
108 } 113 }
109 114
110 bool TaskQueueImpl::PostDelayedTaskAt(
111 const tracked_objects::Location& from_here,
112 const base::Closure& task,
113 base::TimeTicks desired_run_time) {
114 base::AutoLock lock(any_thread_lock_);
115 if (!any_thread().task_queue_manager)
116 return false;
117 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow());
118 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time,
119 TaskType::NORMAL);
120 }
121
122 bool TaskQueueImpl::PostDelayedTaskImpl( 115 bool TaskQueueImpl::PostDelayedTaskImpl(
123 const tracked_objects::Location& from_here, 116 const tracked_objects::Location& from_here,
124 const base::Closure& task, 117 const base::Closure& task,
125 base::TimeDelta delay, 118 base::TimeDelta delay,
126 TaskType task_type) { 119 TaskType task_type) {
127 base::AutoLock lock(any_thread_lock_); 120 base::AutoLock lock(any_thread_lock_);
128 if (!any_thread().task_queue_manager) 121 if (!any_thread().task_queue_manager)
129 return false; 122 return false;
130 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); 123 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow());
131 base::TimeTicks desired_run_time; 124 base::TimeTicks desired_run_time;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 any_thread().task_queue_manager->DidQueueTask(thread_hop_task); 162 any_thread().task_queue_manager->DidQueueTask(thread_hop_task);
170 EnqueueTaskLocked(thread_hop_task); 163 EnqueueTaskLocked(thread_hop_task);
171 } 164 }
172 return true; 165 return true;
173 } 166 }
174 pending_task.set_enqueue_order(pending_task.sequence_num); 167 pending_task.set_enqueue_order(pending_task.sequence_num);
175 EnqueueTaskLocked(pending_task); 168 EnqueueTaskLocked(pending_task);
176 return true; 169 return true;
177 } 170 }
178 171
179 void TaskQueueImpl::ScheduleDelayedWorkTask( 172 void TaskQueueImpl::ScheduleDelayedWorkTask(TimeDomain* time_domain,
180 const scoped_refptr<TimeDomain> time_domain, 173 base::TimeTicks desired_run_time) {
181 base::TimeTicks desired_run_time) {
182 DCHECK(main_thread_checker_.CalledOnValidThread()); 174 DCHECK(main_thread_checker_.CalledOnValidThread());
183 LazyNow lazy_now(time_domain->CreateLazyNow()); 175 LazyNow lazy_now(time_domain->CreateLazyNow());
184 time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now); 176 time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now);
185 } 177 }
186 178
187 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { 179 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) {
188 base::AutoLock lock(any_thread_lock_); 180 base::AutoLock lock(any_thread_lock_);
189 if (!any_thread().task_queue_manager) 181 if (!any_thread().task_queue_manager)
190 return; 182 return;
191 183
(...skipping 20 matching lines...) Expand all
212 return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this); 204 return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this);
213 } 205 }
214 206
215 TaskQueue::QueueState TaskQueueImpl::GetQueueState() const { 207 TaskQueue::QueueState TaskQueueImpl::GetQueueState() const {
216 if (!main_thread_only().work_queue.empty()) 208 if (!main_thread_only().work_queue.empty())
217 return QueueState::HAS_WORK; 209 return QueueState::HAS_WORK;
218 210
219 { 211 {
220 base::AutoLock lock(any_thread_lock_); 212 base::AutoLock lock(any_thread_lock_);
221 if (any_thread().incoming_queue.empty()) { 213 if (any_thread().incoming_queue.empty()) {
222 return QueueState::EMPTY; 214 if (any_thread().delayed_task_queue.empty())
215 return QueueState::EMPTY;
216 else
217 return QueueState::NO_IMMEDIATE_WORK;
223 } else { 218 } else {
224 return QueueState::NEEDS_PUMPING; 219 return QueueState::NEEDS_PUMPING;
225 } 220 }
226 } 221 }
227 } 222 }
228 223
229 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) { 224 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) {
230 // A null task is passed when UpdateQueue is called before any task is run. 225 // A null task is passed when UpdateQueue is called before any task is run.
231 // In this case we don't want to pump an after_wakeup queue, so return true 226 // In this case we don't want to pump an after_wakeup queue, so return true
232 // here. 227 // here.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 493 }
499 494
500 void TaskQueueImpl::NotifyDidProcessTask( 495 void TaskQueueImpl::NotifyDidProcessTask(
501 const base::PendingTask& pending_task) { 496 const base::PendingTask& pending_task) {
502 DCHECK(should_notify_observers_); 497 DCHECK(should_notify_observers_);
503 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, 498 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver,
504 main_thread_only().task_observers, 499 main_thread_only().task_observers,
505 DidProcessTask(pending_task)); 500 DidProcessTask(pending_task));
506 } 501 }
507 502
508 void TaskQueueImpl::SetTimeDomain( 503 void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) {
509 const scoped_refptr<TimeDomain>& time_domain) {
510 base::AutoLock lock(any_thread_lock_); 504 base::AutoLock lock(any_thread_lock_);
511 DCHECK(main_thread_checker_.CalledOnValidThread()); 505 DCHECK(main_thread_checker_.CalledOnValidThread());
512 if (time_domain == any_thread().time_domain) 506 if (time_domain == any_thread().time_domain)
513 return; 507 return;
514 508
515 any_thread().time_domain->MigrateQueue(this, time_domain.get()); 509 if (time_domain)
510 any_thread().time_domain->MigrateQueue(this, time_domain);
516 any_thread().time_domain = time_domain; 511 any_thread().time_domain = time_domain;
517 } 512 }
518 513
519 // static 514 // static
520 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue, 515 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue,
521 base::trace_event::TracedValue* state) { 516 base::trace_event::TracedValue* state) {
522 std::queue<Task> queue_copy(queue); 517 std::queue<Task> queue_copy(queue);
523 while (!queue_copy.empty()) { 518 while (!queue_copy.empty()) {
524 TaskAsValueInto(queue_copy.front(), state); 519 TaskAsValueInto(queue_copy.front(), state);
525 queue_copy.pop(); 520 queue_copy.pop();
(...skipping 25 matching lines...) Expand all
551 state->EndDictionary(); 546 state->EndDictionary();
552 } 547 }
553 548
554 size_t TaskQueueImpl::IncomingQueueSizeForTest() const { 549 size_t TaskQueueImpl::IncomingQueueSizeForTest() const {
555 base::AutoLock lock(any_thread_lock_); 550 base::AutoLock lock(any_thread_lock_);
556 return any_thread().incoming_queue.size(); 551 return any_thread().incoming_queue.size();
557 } 552 }
558 553
559 } // namespace internal 554 } // namespace internal
560 } // namespace scheduler 555 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/base/task_queue_impl.h ('k') | components/scheduler/base/task_queue_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698