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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc

Issue 2353473003: Revert of Prevent redundant DoWorks due to canceled delayed tasks (Closed)
Patch Set: Created 4 years, 3 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/base/task_queue_impl.h" 5 #include "platform/scheduler/base/task_queue_impl.h"
6 6
7 #include "base/trace_event/blame_context.h" 7 #include "base/trace_event/blame_context.h"
8 #include "platform/scheduler/base/task_queue_manager.h" 8 #include "platform/scheduler/base/task_queue_manager.h"
9 #include "platform/scheduler/base/task_queue_manager_delegate.h" 9 #include "platform/scheduler/base/task_queue_manager_delegate.h"
10 #include "platform/scheduler/base/time_domain.h" 10 #include "platform/scheduler/base/time_domain.h"
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 Task(from_here, task, time_domain_delayed_run_time, sequence_number, 210 Task(from_here, task, time_domain_delayed_run_time, sequence_number,
211 task_type != TaskType::NON_NESTABLE)); 211 task_type != TaskType::NON_NESTABLE));
212 } 212 }
213 return true; 213 return true;
214 } 214 }
215 215
216 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( 216 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread(
217 Task pending_task, base::TimeTicks now) { 217 Task pending_task, base::TimeTicks now) {
218 main_thread_only().task_queue_manager->DidQueueTask(pending_task); 218 main_thread_only().task_queue_manager->DidQueueTask(pending_task);
219 219
220 // Schedule a later call to MoveReadyDelayedTasksToDelayedWorkQueue.
220 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; 221 base::TimeTicks delayed_run_time = pending_task.delayed_run_time;
221 bool queue_was_empty = main_thread_only().delayed_incoming_queue.empty();
222 base::TimeTicks previous_next_run_time;
223 if (!queue_was_empty) {
224 previous_next_run_time =
225 main_thread_only().delayed_incoming_queue.top().delayed_run_time;
226 }
227 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 222 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
228 223 main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time,
229 // Make sure the next wakeup (and only the next wakeup) is registered with the 224 now);
230 // TimeDomain.
231 if (queue_was_empty || delayed_run_time < previous_next_run_time) {
232 main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time,
233 now);
234 if (!queue_was_empty) {
235 main_thread_only().time_domain->CancelDelayedWork(this,
236 previous_next_run_time);
237 }
238 }
239 TraceQueueSize(false); 225 TraceQueueSize(false);
240 } 226 }
241 227
242 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { 228 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
243 any_thread().task_queue_manager->DidQueueTask(pending_task); 229 any_thread().task_queue_manager->DidQueueTask(pending_task);
244 230
245 int thread_hop_task_sequence_number = 231 int thread_hop_task_sequence_number =
246 any_thread().task_queue_manager->GetNextSequenceNumber(); 232 any_thread().task_queue_manager->GetNextSequenceNumber();
247 PushOntoImmediateIncomingQueueLocked( 233 PushOntoImmediateIncomingQueueLocked(
248 FROM_HERE, 234 FROM_HERE,
249 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, 235 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this,
250 base::Passed(&pending_task)), 236 base::Passed(&pending_task)),
251 base::TimeTicks(), 237 base::TimeTicks(),
252 thread_hop_task_sequence_number, 238 thread_hop_task_sequence_number,
253 false); 239 false);
254 } 240 }
255 241
256 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( 242 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
257 const tracked_objects::Location& posted_from, 243 const tracked_objects::Location& posted_from,
258 const base::Closure& task, 244 const base::Closure& task,
259 base::TimeTicks desired_run_time, 245 base::TimeTicks desired_run_time,
260 EnqueueOrder sequence_number, 246 EnqueueOrder sequence_number,
261 bool nestable) { 247 bool nestable) {
262 if (any_thread().immediate_incoming_queue.empty()) 248 if (any_thread().immediate_incoming_queue.empty())
263 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); 249 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this);
264 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make 250 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
265 // it run. 251 // it run.
266 if (any_thread().immediate_incoming_queue.empty()) { 252 if (any_thread().immediate_incoming_queue.empty()) {
267 // There's no point posting a DoWork for a disabled queue, however we can 253 // There's no point posting a DoWork for a disabled queue, however we can
268 // only tell if it's disabled from the main thread. 254 // only tell if it's disabled from the main thread.
269 if (base::PlatformThread::CurrentId() == thread_id_) { 255 if (base::PlatformThread::CurrentId() == thread_id_) {
270 if (main_thread_only().is_enabled && !BlockedByFenceLocked()) 256 if (main_thread_only().is_enabled && !BlockedByFenceLocked())
271 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); 257 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
272 } else { 258 } else {
273 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); 259 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
274 } 260 }
275 } 261 }
276 any_thread().immediate_incoming_queue.emplace( 262 any_thread().immediate_incoming_queue.emplace(
277 posted_from, task, desired_run_time, sequence_number, nestable, sequence_n umber); 263 posted_from, task, desired_run_time, sequence_number, nestable, sequence_n umber);
278 any_thread().task_queue_manager->DidQueueTask( any_thread().immediate_incoming _queue.back()); 264 any_thread().task_queue_manager->DidQueueTask( any_thread().immediate_incoming _queue.back());
279 TraceQueueSize(true); 265 TraceQueueSize(true);
280 } 266 }
281 267
282 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { 268 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) {
283 DCHECK(main_thread_checker_.CalledOnValidThread()); 269 DCHECK(main_thread_checker_.CalledOnValidThread());
284 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; 270 base::TimeTicks delayed_run_time = pending_task.delayed_run_time;
285 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); 271 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
272 // Make sure |delayed_run_time| isn't in the past.
286 if (delayed_run_time < time_domain_now) { 273 if (delayed_run_time < time_domain_now) {
287 // If |delayed_run_time| is in the past then push it onto the work queue
288 // immediately. To ensure the right task ordering we need to temporarily
289 // push it onto the |delayed_incoming_queue|.
290 delayed_run_time = time_domain_now; 274 delayed_run_time = time_domain_now;
291 pending_task.delayed_run_time = time_domain_now; 275 pending_task.delayed_run_time = time_domain_now;
292 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 276 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
293 LazyNow lazy_now(time_domain_now); 277 LazyNow lazy_now(time_domain_now);
294 WakeUpForDelayedWork(&lazy_now); 278 MoveReadyDelayedTasksToDelayedWorkQueue(&lazy_now);
295 } else { 279 } else {
296 // If |delayed_run_time| is in the future we can queue it as normal. 280 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
297 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), 281 main_thread_only().time_domain->ScheduleDelayedWork(
298 time_domain_now); 282 this, delayed_run_time, main_thread_only().time_domain->Now());
299 } 283 }
300 TraceQueueSize(false); 284 TraceQueueSize(false);
301 } 285 }
302 286
303 void TaskQueueImpl::SetQueueEnabled(bool enabled) { 287 void TaskQueueImpl::SetQueueEnabled(bool enabled) {
304 if (main_thread_only().is_enabled == enabled) 288 if (main_thread_only().is_enabled == enabled)
305 return; 289 return;
306 main_thread_only().is_enabled = enabled; 290 main_thread_only().is_enabled = enabled;
307 if (!main_thread_only().task_queue_manager) 291 if (!main_thread_only().task_queue_manager)
308 return; 292 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 main_thread_only().delayed_incoming_queue.top().delayed_run_time <= 327 main_thread_only().delayed_incoming_queue.top().delayed_run_time <=
344 main_thread_only().time_domain->CreateLazyNow().Now()) { 328 main_thread_only().time_domain->CreateLazyNow().Now()) {
345 return true; 329 return true;
346 } 330 }
347 331
348 // Finally tasks on |immediate_incoming_queue| count as immediate work. 332 // Finally tasks on |immediate_incoming_queue| count as immediate work.
349 base::AutoLock lock(any_thread_lock_); 333 base::AutoLock lock(any_thread_lock_);
350 return !any_thread().immediate_incoming_queue.empty(); 334 return !any_thread().immediate_incoming_queue.empty();
351 } 335 }
352 336
353 void TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) { 337 void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) {
354 // Enqueue all delayed tasks that should be running now, skipping any that 338 // Enqueue all delayed tasks that should be running now, skipping any that
355 // have been canceled. 339 // have been canceled.
356 while (!main_thread_only().delayed_incoming_queue.empty()) { 340 while (!main_thread_only().delayed_incoming_queue.empty()) {
357 // TODO(alexclarke): Use extract() when C++17 is allowed. 341 // TODO(alexclarke): Use extract() when C++17 is allowed.
358 Task& task = 342 Task& task =
359 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); 343 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top());
360 if (task.task.IsCancelled()) { 344 if (task.task.IsCancelled()) {
361 main_thread_only().delayed_incoming_queue.pop(); 345 main_thread_only().delayed_incoming_queue.pop();
362 continue; 346 continue;
363 } 347 }
364 if (task.delayed_run_time > lazy_now->Now()) 348 if (task.delayed_run_time > lazy_now->Now())
365 break; 349 break;
366 task.set_enqueue_order( 350 task.set_enqueue_order(
367 main_thread_only().task_queue_manager->GetNextSequenceNumber()); 351 main_thread_only().task_queue_manager->GetNextSequenceNumber());
368 main_thread_only().delayed_work_queue->Push(std::move(task)); 352 main_thread_only().delayed_work_queue->Push(std::move(task));
369 main_thread_only().delayed_incoming_queue.pop(); 353 main_thread_only().delayed_incoming_queue.pop();
370 } 354 }
371
372 // Make sure the next wake up is scheduled.
373 if (!main_thread_only().delayed_incoming_queue.empty()) {
374 main_thread_only().time_domain->ScheduleDelayedWork(
375 this, main_thread_only().delayed_incoming_queue.top().delayed_run_time,
376 lazy_now->Now());
377 }
378 } 355 }
379 356
380 bool TaskQueueImpl::MaybeUpdateImmediateWorkQueues() { 357 bool TaskQueueImpl::MaybeUpdateImmediateWorkQueues() {
381 if (!main_thread_only().task_queue_manager) 358 if (!main_thread_only().task_queue_manager)
382 return false; 359 return false;
383 360
384 if (!main_thread_only().immediate_work_queue->Empty()) 361 if (!main_thread_only().immediate_work_queue->Empty())
385 return true; 362 return true;
386 363
387 base::AutoLock lock(any_thread_lock_); 364 base::AutoLock lock(any_thread_lock_);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 main_thread_only().immediate_work_queue->Size()); 445 main_thread_only().immediate_work_queue->Size());
469 state->SetInteger("delayed_work_queue_size", 446 state->SetInteger("delayed_work_queue_size",
470 main_thread_only().delayed_work_queue->Size()); 447 main_thread_only().delayed_work_queue->Size());
471 if (!main_thread_only().delayed_incoming_queue.empty()) { 448 if (!main_thread_only().delayed_incoming_queue.empty()) {
472 base::TimeDelta delay_to_next_task = 449 base::TimeDelta delay_to_next_task =
473 (main_thread_only().delayed_incoming_queue.top().delayed_run_time - 450 (main_thread_only().delayed_incoming_queue.top().delayed_run_time -
474 main_thread_only().time_domain->CreateLazyNow().Now()); 451 main_thread_only().time_domain->CreateLazyNow().Now());
475 state->SetDouble("delay_to_next_task_ms", 452 state->SetDouble("delay_to_next_task_ms",
476 delay_to_next_task.InMillisecondsF()); 453 delay_to_next_task.InMillisecondsF());
477 } 454 }
478 if (main_thread_only().current_fence)
479 state->SetInteger("current_fence", main_thread_only().current_fence);
480 if (verbose_tracing_enabled) { 455 if (verbose_tracing_enabled) {
481 state->BeginArray("immediate_incoming_queue"); 456 state->BeginArray("immediate_incoming_queue");
482 QueueAsValueInto(any_thread().immediate_incoming_queue, state); 457 QueueAsValueInto(any_thread().immediate_incoming_queue, state);
483 state->EndArray(); 458 state->EndArray();
484 state->BeginArray("delayed_work_queue"); 459 state->BeginArray("delayed_work_queue");
485 main_thread_only().delayed_work_queue->AsValueInto(state); 460 main_thread_only().delayed_work_queue->AsValueInto(state);
486 state->EndArray(); 461 state->EndArray();
487 state->BeginArray("immediate_work_queue"); 462 state->BeginArray("immediate_work_queue");
488 main_thread_only().immediate_work_queue->AsValueInto(state); 463 main_thread_only().immediate_work_queue->AsValueInto(state);
489 state->EndArray(); 464 state->EndArray();
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 state->SetBoolean("is_cancelled", task.task.IsCancelled()); 670 state->SetBoolean("is_cancelled", task.task.IsCancelled());
696 state->SetDouble( 671 state->SetDouble(
697 "delayed_run_time", 672 "delayed_run_time",
698 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); 673 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
699 state->EndDictionary(); 674 state->EndDictionary();
700 } 675 }
701 676
702 } // namespace internal 677 } // namespace internal
703 } // namespace scheduler 678 } // namespace scheduler
704 } // namespace blink 679 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698