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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc

Issue 2812703002: Revert of [scheduler] Add TaskQueue::Observer (Closed)
Patch Set: Manual Revert Created 3 years, 8 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 "platform/scheduler/renderer/task_queue_throttler.h" 5 #include "platform/scheduler/renderer/task_queue_throttler.h"
6 6
7 #include <cstdint> 7 #include <cstdint>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 } // namespace 73 } // namespace
74 74
75 TaskQueueThrottler::TaskQueueThrottler( 75 TaskQueueThrottler::TaskQueueThrottler(
76 RendererSchedulerImpl* renderer_scheduler, 76 RendererSchedulerImpl* renderer_scheduler,
77 const char* tracing_category) 77 const char* tracing_category)
78 : task_runner_(renderer_scheduler->ControlTaskRunner()), 78 : task_runner_(renderer_scheduler->ControlTaskRunner()),
79 renderer_scheduler_(renderer_scheduler), 79 renderer_scheduler_(renderer_scheduler),
80 tick_clock_(renderer_scheduler->tick_clock()), 80 tick_clock_(renderer_scheduler->tick_clock()),
81 tracing_category_(tracing_category), 81 tracing_category_(tracing_category),
82 time_domain_(new ThrottledTimeDomain(tracing_category)), 82 time_domain_(new ThrottledTimeDomain(this, tracing_category)),
83 allow_throttling_(true), 83 allow_throttling_(true),
84 weak_factory_(this) { 84 weak_factory_(this) {
85 pump_throttled_tasks_closure_.Reset(base::Bind( 85 pump_throttled_tasks_closure_.Reset(base::Bind(
86 &TaskQueueThrottler::PumpThrottledTasks, weak_factory_.GetWeakPtr())); 86 &TaskQueueThrottler::PumpThrottledTasks, weak_factory_.GetWeakPtr()));
87 forward_immediate_work_callback_ = 87 forward_immediate_work_callback_ =
88 base::Bind(&TaskQueueThrottler::OnQueueNextWakeUpChanged, 88 base::Bind(&TaskQueueThrottler::OnTimeDomainHasImmediateWork,
89 weak_factory_.GetWeakPtr()); 89 weak_factory_.GetWeakPtr());
90 90
91 renderer_scheduler_->RegisterTimeDomain(time_domain_.get()); 91 renderer_scheduler_->RegisterTimeDomain(time_domain_.get());
92 } 92 }
93 93
94 TaskQueueThrottler::~TaskQueueThrottler() { 94 TaskQueueThrottler::~TaskQueueThrottler() {
95 // It's possible for queues to be still throttled, so we need to tidy up 95 // It's possible for queues to be still throttled, so we need to tidy up
96 // before unregistering the time domain. 96 // before unregistering the time domain.
97 for (const TaskQueueMap::value_type& map_entry : queue_details_) { 97 for (const TaskQueueMap::value_type& map_entry : queue_details_) {
98 TaskQueue* task_queue = map_entry.first; 98 TaskQueue* task_queue = map_entry.first;
99 if (IsThrottled(task_queue)) { 99 if (IsThrottled(task_queue)) {
100 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); 100 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain());
101 task_queue->RemoveFence(); 101 task_queue->RemoveFence();
102 } 102 }
103 if (map_entry.second.throttling_ref_count != 0)
104 task_queue->SetObserver(nullptr);
105 } 103 }
106 104
107 renderer_scheduler_->UnregisterTimeDomain(time_domain_.get()); 105 renderer_scheduler_->UnregisterTimeDomain(time_domain_.get());
108 } 106 }
109 107
110 void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) { 108 void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) {
111 DCHECK_NE(task_queue, task_runner_.get()); 109 DCHECK_NE(task_queue, task_runner_.get());
112 110
113 std::pair<TaskQueueMap::iterator, bool> insert_result = 111 std::pair<TaskQueueMap::iterator, bool> insert_result =
114 queue_details_.insert(std::make_pair(task_queue, Metadata())); 112 queue_details_.insert(std::make_pair(task_queue, Metadata()));
115 insert_result.first->second.throttling_ref_count++; 113 insert_result.first->second.throttling_ref_count++;
116 114
117 // If ref_count is 1, the task queue is newly throttled. 115 // If ref_count is 1, the task queue is newly throttled.
118 if (insert_result.first->second.throttling_ref_count != 1) 116 if (insert_result.first->second.throttling_ref_count != 1)
119 return; 117 return;
120 118
121 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueThrottled", 119 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueThrottled",
122 "task_queue", task_queue); 120 "task_queue", task_queue);
123 121
124 task_queue->SetObserver(this);
125
126 if (!allow_throttling_) 122 if (!allow_throttling_)
127 return; 123 return;
128 124
129 task_queue->SetTimeDomain(time_domain_.get()); 125 task_queue->SetTimeDomain(time_domain_.get());
130 // This blocks any tasks from |task_queue| until PumpThrottledTasks() to 126 // This blocks any tasks from |task_queue| until PumpThrottledTasks() to
131 // enforce task alignment. 127 // enforce task alignment.
132 task_queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); 128 task_queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
133 129
134 if (!task_queue->IsQueueEnabled()) 130 if (!task_queue->IsQueueEnabled())
135 return; 131 return;
136 132
137 if (!task_queue->IsEmpty()) { 133 if (!task_queue->IsEmpty()) {
138 LazyNow lazy_now(tick_clock_); 134 if (task_queue->HasPendingImmediateWork()) {
139 OnQueueNextWakeUpChanged(task_queue, 135 OnTimeDomainHasImmediateWork(task_queue);
140 NextTaskRunTime(&lazy_now, task_queue).value()); 136 } else {
137 OnTimeDomainHasDelayedWork(task_queue);
138 }
141 } 139 }
142 } 140 }
143 141
144 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { 142 void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) {
145 TaskQueueMap::iterator iter = queue_details_.find(task_queue); 143 TaskQueueMap::iterator iter = queue_details_.find(task_queue);
146 144
147 if (iter == queue_details_.end() || 145 if (iter == queue_details_.end() ||
148 --iter->second.throttling_ref_count != 0) { 146 --iter->second.throttling_ref_count != 0) {
149 return; 147 return;
150 } 148 }
151 149
152 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUnthrottled", 150 TRACE_EVENT1(tracing_category_, "TaskQueueThrottler_TaskQueueUnthrottled",
153 "task_queue", task_queue); 151 "task_queue", task_queue);
154 152
155 task_queue->SetObserver(nullptr);
156
157 MaybeDeleteQueueMetadata(iter); 153 MaybeDeleteQueueMetadata(iter);
158 154
159 if (!allow_throttling_) 155 if (!allow_throttling_)
160 return; 156 return;
161 157
162 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); 158 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain());
163 task_queue->RemoveFence(); 159 task_queue->RemoveFence();
164 } 160 }
165 161
166 bool TaskQueueThrottler::IsThrottled(TaskQueue* task_queue) const { 162 bool TaskQueueThrottler::IsThrottled(TaskQueue* task_queue) const {
(...skipping 13 matching lines...) Expand all
180 176
181 LazyNow lazy_now(tick_clock_); 177 LazyNow lazy_now(tick_clock_);
182 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools; 178 std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools;
183 for (BudgetPool* budget_pool : budget_pools) { 179 for (BudgetPool* budget_pool : budget_pools) {
184 budget_pool->RemoveQueue(lazy_now.Now(), task_queue); 180 budget_pool->RemoveQueue(lazy_now.Now(), task_queue);
185 } 181 }
186 182
187 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't 183 // Iterator may have been deleted by BudgetPool::RemoveQueue, so don't
188 // use it here. 184 // use it here.
189 queue_details_.erase(task_queue); 185 queue_details_.erase(task_queue);
190
191 // NOTE: Observer is automatically unregistered when unregistering task queue.
192 } 186 }
193 187
194 void TaskQueueThrottler::OnQueueNextWakeUpChanged( 188 void TaskQueueThrottler::OnTimeDomainHasImmediateWork(TaskQueue* queue) {
195 TaskQueue* queue, 189 // Forward to the main thread if called from another thread
196 base::TimeTicks next_wake_up) {
197 if (!task_runner_->RunsTasksOnCurrentThread()) { 190 if (!task_runner_->RunsTasksOnCurrentThread()) {
198 task_runner_->PostTask( 191 task_runner_->PostTask(FROM_HERE,
199 FROM_HERE, 192 base::Bind(forward_immediate_work_callback_, queue));
200 base::Bind(forward_immediate_work_callback_, queue, next_wake_up));
201 return; 193 return;
202 } 194 }
203
204 TRACE_EVENT0(tracing_category_, 195 TRACE_EVENT0(tracing_category_,
205 "TaskQueueThrottler::OnQueueNextWakeUpChanged"); 196 "TaskQueueThrottler::OnTimeDomainHasImmediateWork");
206 197
207 // We don't expect this to get called for disabled queues, but we can't DCHECK 198 // We don't expect this to get called for disabled queues, but we can't DCHECK
208 // because of the above thread hop. Just bail out if the queue is disabled. 199 // because of the above thread hop. Just bail out if the queue is disabled.
209 if (!queue->IsQueueEnabled()) 200 if (!queue->IsQueueEnabled())
210 return; 201 return;
211 202
212 base::TimeTicks now = tick_clock_->NowTicks(); 203 base::TimeTicks now = tick_clock_->NowTicks();
213 MaybeSchedulePumpThrottledTasks( 204 base::TimeTicks next_allowed_run_time = GetNextAllowedRunTime(now, queue);
214 FROM_HERE, now, 205 MaybeSchedulePumpThrottledTasks(FROM_HERE, now, next_allowed_run_time);
215 std::max(GetNextAllowedRunTime(now, queue), next_wake_up)); 206 }
207
208 void TaskQueueThrottler::OnTimeDomainHasDelayedWork(TaskQueue* queue) {
209 TRACE_EVENT0(tracing_category_,
210 "TaskQueueThrottler::OnTimeDomainHasDelayedWork");
211 DCHECK(queue->IsQueueEnabled());
212 base::TimeTicks now = tick_clock_->NowTicks();
213 LazyNow lazy_now(now);
214
215 base::Optional<base::TimeTicks> next_scheduled_delayed_task =
216 NextTaskRunTime(&lazy_now, queue);
217 DCHECK(next_scheduled_delayed_task);
218 MaybeSchedulePumpThrottledTasks(FROM_HERE, now,
219 next_scheduled_delayed_task.value());
216 } 220 }
217 221
218 void TaskQueueThrottler::PumpThrottledTasks() { 222 void TaskQueueThrottler::PumpThrottledTasks() {
219 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler::PumpThrottledTasks"); 223 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler::PumpThrottledTasks");
220 pending_pump_throttled_tasks_runtime_.reset(); 224 pending_pump_throttled_tasks_runtime_.reset();
221 225
222 LazyNow lazy_now(tick_clock_); 226 LazyNow lazy_now(tick_clock_);
223 base::Optional<base::TimeTicks> next_scheduled_delayed_task; 227 base::Optional<base::TimeTicks> next_scheduled_delayed_task;
224 228
225 for (const TaskQueueMap::value_type& map_entry : queue_details_) { 229 for (const TaskQueueMap::value_type& map_entry : queue_details_) {
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME); 488 queue->InsertFence(TaskQueue::InsertFencePosition::BEGINNING_OF_TIME);
485 queue->SetTimeDomain(time_domain_.get()); 489 queue->SetTimeDomain(time_domain_.get());
486 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue); 490 SchedulePumpQueue(FROM_HERE, lazy_now.Now(), queue);
487 } 491 }
488 492
489 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling"); 493 TRACE_EVENT0(tracing_category_, "TaskQueueThrottler_EnableThrottling");
490 } 494 }
491 495
492 } // namespace scheduler 496 } // namespace scheduler
493 } // namespace blink 497 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698