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

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: Removed refcounting from TimeDomain 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() {}
Sami 2015/11/26 19:27:50 nit: DCHECK that we no longer have a time domain?
alex clarke (OOO till 29th) 2015/11/27 10:01:59 I added a de-register here too. It was needed in
35 36
36 TaskQueueImpl::Task::Task() 37 TaskQueueImpl::Task::Task()
37 : PendingTask(tracked_objects::Location(), 38 : PendingTask(tracked_objects::Location(),
38 base::Closure(), 39 base::Closure(),
39 base::TimeTicks(), 40 base::TimeTicks(),
40 true), 41 true),
41 #ifndef NDEBUG 42 #ifndef NDEBUG
42 enqueue_order_set_(false), 43 enqueue_order_set_(false),
43 #endif 44 #endif
44 enqueue_order_(0) { 45 enqueue_order_(0) {
45 sequence_num = 0; 46 sequence_num = 0;
46 } 47 }
47 48
48 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, 49 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
49 const base::Closure& task, 50 const base::Closure& task,
50 int sequence_number, 51 int sequence_number,
51 bool nestable) 52 bool nestable)
52 : PendingTask(posted_from, task, base::TimeTicks(), nestable), 53 : PendingTask(posted_from, task, base::TimeTicks(), nestable),
53 #ifndef NDEBUG 54 #ifndef NDEBUG
54 enqueue_order_set_(false), 55 enqueue_order_set_(false),
55 #endif 56 #endif
56 enqueue_order_(0) { 57 enqueue_order_(0) {
57 sequence_num = sequence_number; 58 sequence_num = sequence_number;
58 } 59 }
59 60
60 TaskQueueImpl::AnyThread::AnyThread( 61 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager,
61 TaskQueueManager* task_queue_manager, 62 PumpPolicy pump_policy,
62 PumpPolicy pump_policy, 63 TimeDomain* time_domain)
63 const scoped_refptr<TimeDomain>& time_domain)
64 : task_queue_manager(task_queue_manager), 64 : task_queue_manager(task_queue_manager),
65 pump_policy(pump_policy), 65 pump_policy(pump_policy),
66 time_domain(time_domain) {} 66 time_domain(time_domain) {}
67 67
68 TaskQueueImpl::AnyThread::~AnyThread() {} 68 TaskQueueImpl::AnyThread::~AnyThread() {}
69 69
70 TaskQueueImpl::MainThreadOnly::MainThreadOnly( 70 TaskQueueImpl::MainThreadOnly::MainThreadOnly(
71 TaskQueueManager* task_queue_manager) 71 TaskQueueManager* task_queue_manager)
72 : task_queue_manager(task_queue_manager), 72 : task_queue_manager(task_queue_manager),
73 set_index(0) {} 73 set_index(0) {}
74 74
75 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} 75 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
76 76
77 void TaskQueueImpl::UnregisterTaskQueue() { 77 void TaskQueueImpl::UnregisterTaskQueue() {
78 base::AutoLock lock(any_thread_lock_); 78 base::AutoLock lock(any_thread_lock_);
79 if (!any_thread().task_queue_manager) 79 if (!any_thread().task_queue_manager)
80 return; 80 return;
81 any_thread().time_domain->UnregisterQueue(this); 81 if (any_thread().time_domain)
82 any_thread().time_domain->UnregisterQueue(this);
82 any_thread().time_domain = nullptr; 83 any_thread().time_domain = nullptr;
83 any_thread().task_queue_manager->UnregisterTaskQueue(this); 84 any_thread().task_queue_manager->UnregisterTaskQueue(this);
84 85
85 any_thread().task_queue_manager = nullptr; 86 any_thread().task_queue_manager = nullptr;
86 main_thread_only().task_queue_manager = nullptr; 87 main_thread_only().task_queue_manager = nullptr;
87 any_thread().delayed_task_queue = std::priority_queue<Task>(); 88 any_thread().delayed_task_queue = std::priority_queue<Task>();
88 any_thread().incoming_queue = std::queue<Task>(); 89 any_thread().incoming_queue = std::queue<Task>();
89 main_thread_only().work_queue = std::queue<Task>(); 90 main_thread_only().work_queue = std::queue<Task>();
90 } 91 }
91 92
92 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { 93 bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
93 base::AutoLock lock(any_thread_lock_); 94 base::AutoLock lock(any_thread_lock_);
94 return base::PlatformThread::CurrentId() == thread_id_; 95 return base::PlatformThread::CurrentId() == thread_id_;
95 } 96 }
96 97
97 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, 98 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
98 const base::Closure& task, 99 const base::Closure& task,
99 base::TimeDelta delay) { 100 base::TimeDelta delay) {
100 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); 101 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL);
101 } 102 }
102 103
103 bool TaskQueueImpl::PostNonNestableDelayedTask( 104 bool TaskQueueImpl::PostNonNestableDelayedTask(
104 const tracked_objects::Location& from_here, 105 const tracked_objects::Location& from_here,
105 const base::Closure& task, 106 const base::Closure& task,
106 base::TimeDelta delay) { 107 base::TimeDelta delay) {
107 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); 108 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE);
108 } 109 }
109 110
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( 111 bool TaskQueueImpl::PostDelayedTaskImpl(
123 const tracked_objects::Location& from_here, 112 const tracked_objects::Location& from_here,
124 const base::Closure& task, 113 const base::Closure& task,
125 base::TimeDelta delay, 114 base::TimeDelta delay,
126 TaskType task_type) { 115 TaskType task_type) {
127 base::AutoLock lock(any_thread_lock_); 116 base::AutoLock lock(any_thread_lock_);
128 if (!any_thread().task_queue_manager) 117 if (!any_thread().task_queue_manager)
129 return false; 118 return false;
130 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); 119 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow());
131 base::TimeTicks desired_run_time; 120 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); 158 any_thread().task_queue_manager->DidQueueTask(thread_hop_task);
170 EnqueueTaskLocked(thread_hop_task); 159 EnqueueTaskLocked(thread_hop_task);
171 } 160 }
172 return true; 161 return true;
173 } 162 }
174 pending_task.set_enqueue_order(pending_task.sequence_num); 163 pending_task.set_enqueue_order(pending_task.sequence_num);
175 EnqueueTaskLocked(pending_task); 164 EnqueueTaskLocked(pending_task);
176 return true; 165 return true;
177 } 166 }
178 167
179 void TaskQueueImpl::ScheduleDelayedWorkTask( 168 void TaskQueueImpl::ScheduleDelayedWorkTask(TimeDomain* time_domain,
180 const scoped_refptr<TimeDomain> time_domain, 169 base::TimeTicks desired_run_time) {
181 base::TimeTicks desired_run_time) {
182 DCHECK(main_thread_checker_.CalledOnValidThread()); 170 DCHECK(main_thread_checker_.CalledOnValidThread());
183 LazyNow lazy_now(time_domain->CreateLazyNow()); 171 LazyNow lazy_now(time_domain->CreateLazyNow());
184 time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now); 172 time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now);
185 } 173 }
186 174
187 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { 175 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) {
188 base::AutoLock lock(any_thread_lock_); 176 base::AutoLock lock(any_thread_lock_);
189 if (!any_thread().task_queue_manager) 177 if (!any_thread().task_queue_manager)
190 return; 178 return;
191 179
(...skipping 20 matching lines...) Expand all
212 return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this); 200 return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this);
213 } 201 }
214 202
215 TaskQueue::QueueState TaskQueueImpl::GetQueueState() const { 203 TaskQueue::QueueState TaskQueueImpl::GetQueueState() const {
216 if (!main_thread_only().work_queue.empty()) 204 if (!main_thread_only().work_queue.empty())
217 return QueueState::HAS_WORK; 205 return QueueState::HAS_WORK;
218 206
219 { 207 {
220 base::AutoLock lock(any_thread_lock_); 208 base::AutoLock lock(any_thread_lock_);
221 if (any_thread().incoming_queue.empty()) { 209 if (any_thread().incoming_queue.empty()) {
222 return QueueState::EMPTY; 210 if (any_thread().delayed_task_queue.empty())
211 return QueueState::EMPTY;
212 else
213 return QueueState::NO_IMMEDIATE_WORK;
223 } else { 214 } else {
224 return QueueState::NEEDS_PUMPING; 215 return QueueState::NEEDS_PUMPING;
225 } 216 }
226 } 217 }
227 } 218 }
228
Sami 2015/11/26 19:27:50 Intentional?
alex clarke (OOO till 29th) 2015/11/27 10:01:59 Done.
229 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) { 219 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) {
230 // A null task is passed when UpdateQueue is called before any task is run. 220 // 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 221 // In this case we don't want to pump an after_wakeup queue, so return true
232 // here. 222 // here.
233 if (!task) 223 if (!task)
234 return true; 224 return true;
235 225
236 // Return false if there are no task in the incoming queue. 226 // Return false if there are no task in the incoming queue.
237 if (any_thread().incoming_queue.empty()) 227 if (any_thread().incoming_queue.empty())
238 return false; 228 return false;
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 488 }
499 489
500 void TaskQueueImpl::NotifyDidProcessTask( 490 void TaskQueueImpl::NotifyDidProcessTask(
501 const base::PendingTask& pending_task) { 491 const base::PendingTask& pending_task) {
502 DCHECK(should_notify_observers_); 492 DCHECK(should_notify_observers_);
503 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, 493 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver,
504 main_thread_only().task_observers, 494 main_thread_only().task_observers,
505 DidProcessTask(pending_task)); 495 DidProcessTask(pending_task));
506 } 496 }
507 497
508 void TaskQueueImpl::SetTimeDomain( 498 void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) {
509 const scoped_refptr<TimeDomain>& time_domain) {
510 base::AutoLock lock(any_thread_lock_); 499 base::AutoLock lock(any_thread_lock_);
511 DCHECK(main_thread_checker_.CalledOnValidThread()); 500 DCHECK(main_thread_checker_.CalledOnValidThread());
512 if (time_domain == any_thread().time_domain) 501 if (time_domain == any_thread().time_domain)
513 return; 502 return;
514 503
515 any_thread().time_domain->MigrateQueue(this, time_domain.get()); 504 if (time_domain)
505 any_thread().time_domain->MigrateQueue(this, time_domain);
516 any_thread().time_domain = time_domain; 506 any_thread().time_domain = time_domain;
517 } 507 }
518 508
519 // static 509 // static
520 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue, 510 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue,
521 base::trace_event::TracedValue* state) { 511 base::trace_event::TracedValue* state) {
522 std::queue<Task> queue_copy(queue); 512 std::queue<Task> queue_copy(queue);
523 while (!queue_copy.empty()) { 513 while (!queue_copy.empty()) {
524 TaskAsValueInto(queue_copy.front(), state); 514 TaskAsValueInto(queue_copy.front(), state);
525 queue_copy.pop(); 515 queue_copy.pop();
(...skipping 25 matching lines...) Expand all
551 state->EndDictionary(); 541 state->EndDictionary();
552 } 542 }
553 543
554 size_t TaskQueueImpl::IncomingQueueSizeForTest() const { 544 size_t TaskQueueImpl::IncomingQueueSizeForTest() const {
555 base::AutoLock lock(any_thread_lock_); 545 base::AutoLock lock(any_thread_lock_);
556 return any_thread().incoming_queue.size(); 546 return any_thread().incoming_queue.size();
557 } 547 }
558 548
559 } // namespace internal 549 } // namespace internal
560 } // namespace scheduler 550 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698