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

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

Issue 2781323003: [scheduler] Split lock in TaskQueueImpl. (Closed)
Patch Set: Addressed comments 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/base/task_queue_impl.h" 5 #include "platform/scheduler/base/task_queue_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 set_index(0), 165 set_index(0),
166 is_enabled_refcount(0), 166 is_enabled_refcount(0),
167 voter_refcount(0), 167 voter_refcount(0),
168 blame_context(nullptr), 168 blame_context(nullptr),
169 current_fence(0) {} 169 current_fence(0) {}
170 170
171 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} 171 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
172 172
173 void TaskQueueImpl::UnregisterTaskQueue() { 173 void TaskQueueImpl::UnregisterTaskQueue() {
174 base::AutoLock lock(any_thread_lock_); 174 base::AutoLock lock(any_thread_lock_);
175 base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
175 if (main_thread_only().time_domain) 176 if (main_thread_only().time_domain)
176 main_thread_only().time_domain->UnregisterQueue(this); 177 main_thread_only().time_domain->UnregisterQueue(this);
177 if (!any_thread().task_queue_manager) 178 if (!any_thread().task_queue_manager)
178 return; 179 return;
179 any_thread().time_domain = nullptr; 180 any_thread().time_domain = nullptr;
180 main_thread_only().time_domain = nullptr; 181 main_thread_only().time_domain = nullptr;
181 any_thread().task_queue_manager->UnregisterTaskQueue(this); 182 any_thread().task_queue_manager->UnregisterTaskQueue(this);
182 183
183 any_thread().task_queue_manager = nullptr; 184 any_thread().task_queue_manager = nullptr;
184 main_thread_only().task_queue_manager = nullptr; 185 main_thread_only().task_queue_manager = nullptr;
185 main_thread_only().delayed_incoming_queue = std::priority_queue<Task>(); 186 main_thread_only().delayed_incoming_queue = std::priority_queue<Task>();
186 any_thread().immediate_incoming_queue.clear(); 187 immediate_incoming_queue().clear();
187 main_thread_only().immediate_work_queue.reset(); 188 main_thread_only().immediate_work_queue.reset();
188 main_thread_only().delayed_work_queue.reset(); 189 main_thread_only().delayed_work_queue.reset();
189 } 190 }
190 191
191 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { 192 bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
192 return base::PlatformThread::CurrentId() == thread_id_; 193 return base::PlatformThread::CurrentId() == thread_id_;
193 } 194 }
194 195
195 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, 196 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
196 base::Closure task, 197 base::Closure task,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 // is requested if the queue is enabled. Note we still want to schedule a 283 // is requested if the queue is enabled. Note we still want to schedule a
283 // wakeup even if blocked by a fence, because we'd break throttling logic 284 // wakeup even if blocked by a fence, because we'd break throttling logic
284 // otherwise. 285 // otherwise.
285 base::TimeTicks next_delayed_task = 286 base::TimeTicks next_delayed_task =
286 main_thread_only().delayed_incoming_queue.top().delayed_run_time; 287 main_thread_only().delayed_incoming_queue.top().delayed_run_time;
287 if (next_delayed_task == delayed_run_time && IsQueueEnabled()) { 288 if (next_delayed_task == delayed_run_time && IsQueueEnabled()) {
288 main_thread_only().time_domain->ScheduleDelayedWork( 289 main_thread_only().time_domain->ScheduleDelayedWork(
289 this, {delayed_run_time, pending_task.sequence_num}, now); 290 this, {delayed_run_time, pending_task.sequence_num}, now);
290 } 291 }
291 292
292 TraceQueueSize(false); 293 TraceQueueSize();
293 } 294 }
294 295
295 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { 296 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
296 any_thread().task_queue_manager->DidQueueTask(pending_task); 297 any_thread().task_queue_manager->DidQueueTask(pending_task);
297 298
298 int thread_hop_task_sequence_number = 299 int thread_hop_task_sequence_number =
299 any_thread().task_queue_manager->GetNextSequenceNumber(); 300 any_thread().task_queue_manager->GetNextSequenceNumber();
300 PushOntoImmediateIncomingQueueLocked( 301 PushOntoImmediateIncomingQueueLocked(
301 FROM_HERE, 302 FROM_HERE,
302 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, 303 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this,
(...skipping 14 matching lines...) Expand all
317 delayed_run_time = time_domain_now; 318 delayed_run_time = time_domain_now;
318 pending_task.delayed_run_time = time_domain_now; 319 pending_task.delayed_run_time = time_domain_now;
319 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 320 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
320 LazyNow lazy_now(time_domain_now); 321 LazyNow lazy_now(time_domain_now);
321 WakeUpForDelayedWork(&lazy_now); 322 WakeUpForDelayedWork(&lazy_now);
322 } else { 323 } else {
323 // If |delayed_run_time| is in the future we can queue it as normal. 324 // If |delayed_run_time| is in the future we can queue it as normal.
324 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), 325 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task),
325 time_domain_now); 326 time_domain_now);
326 } 327 }
327 TraceQueueSize(false); 328 TraceQueueSize();
328 } 329 }
329 330
330 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( 331 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
331 const tracked_objects::Location& posted_from, 332 const tracked_objects::Location& posted_from,
332 base::Closure task, 333 base::Closure task,
333 base::TimeTicks desired_run_time, 334 base::TimeTicks desired_run_time,
334 EnqueueOrder sequence_number, 335 EnqueueOrder sequence_number,
335 bool nestable) { 336 bool nestable) {
336 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make 337 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
337 // it run. 338 // it run.
338 if (any_thread().immediate_incoming_queue.empty()) { 339 bool is_immediate_incoming_queue_empty;
Sami 2017/04/03 14:29:36 s/is/was/
altimin 2017/04/03 14:47:09 Done.
340 Task* queued_task;
341
342 {
343 base::AutoLock lock(immediate_incoming_queue_lock_);
344 is_immediate_incoming_queue_empty = immediate_incoming_queue().empty();
345 immediate_incoming_queue().emplace_back(posted_from, std::move(task),
346 desired_run_time, sequence_number,
347 nestable, sequence_number);
348 queued_task = &immediate_incoming_queue().back();
349 }
350
351 if (is_immediate_incoming_queue_empty) {
339 // However there's no point posting a DoWork for a blocked queue. NB we can 352 // However there's no point posting a DoWork for a blocked queue. NB we can
340 // only tell if it's disabled from the main thread. 353 // only tell if it's disabled from the main thread.
341 bool queue_is_blocked = 354 bool queue_is_blocked =
342 RunsTasksOnCurrentThread() && 355 RunsTasksOnCurrentThread() &&
343 (!IsQueueEnabled() || main_thread_only().current_fence); 356 (!IsQueueEnabled() || main_thread_only().current_fence);
344 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork( 357 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork(
345 this, sequence_number, queue_is_blocked); 358 this, sequence_number, queue_is_blocked);
346 any_thread().time_domain->OnQueueHasImmediateWork(this); 359 any_thread().time_domain->OnQueueHasImmediateWork(this);
347 } 360 }
348 any_thread().immediate_incoming_queue.emplace_back( 361
349 posted_from, std::move(task), desired_run_time, sequence_number, nestable, 362 any_thread().task_queue_manager->DidQueueTask(*queued_task);
Sami 2017/04/03 14:29:36 Let's do this while holding the lock so queued_tas
altimin 2017/04/03 14:47:09 Done.
350 sequence_number); 363 TraceQueueSize();
351 any_thread().task_queue_manager->DidQueueTask(
352 any_thread().immediate_incoming_queue.back());
353 TraceQueueSize(true);
354 } 364 }
355 365
356 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { 366 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
357 if (!main_thread_only().immediate_work_queue->Empty()) 367 if (!main_thread_only().immediate_work_queue->Empty())
358 return; 368 return;
359 369
360 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue(); 370 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue();
361 } 371 }
362 372
363 WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() { 373 WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() {
364 base::AutoLock lock(any_thread_lock_); 374 base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
365 WTF::Deque<TaskQueueImpl::Task> queue; 375 WTF::Deque<TaskQueueImpl::Task> queue;
366 queue.swap(any_thread().immediate_incoming_queue); 376 queue.swap(immediate_incoming_queue());
367 return queue; 377 return queue;
368 } 378 }
369 379
370 bool TaskQueueImpl::IsEmpty() const { 380 bool TaskQueueImpl::IsEmpty() const {
371 if (!main_thread_only().delayed_work_queue->Empty() || 381 if (!main_thread_only().delayed_work_queue->Empty() ||
372 !main_thread_only().delayed_incoming_queue.empty() || 382 !main_thread_only().delayed_incoming_queue.empty() ||
373 !main_thread_only().immediate_work_queue->Empty()) { 383 !main_thread_only().immediate_work_queue->Empty()) {
374 return false; 384 return false;
375 } 385 }
376 386
377 base::AutoLock lock(any_thread_lock_); 387 base::AutoLock lock(immediate_incoming_queue_lock_);
378 return any_thread().immediate_incoming_queue.empty(); 388 return immediate_incoming_queue().empty();
379 } 389 }
380 390
381 size_t TaskQueueImpl::GetNumberOfPendingTasks() const { 391 size_t TaskQueueImpl::GetNumberOfPendingTasks() const {
382 size_t task_count = 0; 392 size_t task_count = 0;
383 task_count += main_thread_only().delayed_work_queue->Size(); 393 task_count += main_thread_only().delayed_work_queue->Size();
384 task_count += main_thread_only().delayed_incoming_queue.size(); 394 task_count += main_thread_only().delayed_incoming_queue.size();
385 task_count += main_thread_only().immediate_work_queue->Size(); 395 task_count += main_thread_only().immediate_work_queue->Size();
386 396
387 base::AutoLock lock(any_thread_lock_); 397 base::AutoLock lock(immediate_incoming_queue_lock_);
388 task_count += any_thread().immediate_incoming_queue.size(); 398 task_count += immediate_incoming_queue().size();
389 return task_count; 399 return task_count;
390 } 400 }
391 401
392 bool TaskQueueImpl::HasPendingImmediateWork() const { 402 bool TaskQueueImpl::HasPendingImmediateWork() const {
393 // Any work queue tasks count as immediate work. 403 // Any work queue tasks count as immediate work.
394 if (!main_thread_only().delayed_work_queue->Empty() || 404 if (!main_thread_only().delayed_work_queue->Empty() ||
395 !main_thread_only().immediate_work_queue->Empty()) { 405 !main_thread_only().immediate_work_queue->Empty()) {
396 return true; 406 return true;
397 } 407 }
398 408
399 // Tasks on |delayed_incoming_queue| that could run now, count as 409 // Tasks on |delayed_incoming_queue| that could run now, count as
400 // immediate work. 410 // immediate work.
401 if (!main_thread_only().delayed_incoming_queue.empty() && 411 if (!main_thread_only().delayed_incoming_queue.empty() &&
402 main_thread_only().delayed_incoming_queue.top().delayed_run_time <= 412 main_thread_only().delayed_incoming_queue.top().delayed_run_time <=
403 main_thread_only().time_domain->CreateLazyNow().Now()) { 413 main_thread_only().time_domain->CreateLazyNow().Now()) {
404 return true; 414 return true;
405 } 415 }
406 416
407 // Finally tasks on |immediate_incoming_queue| count as immediate work. 417 // Finally tasks on |immediate_incoming_queue| count as immediate work.
408 base::AutoLock lock(any_thread_lock_); 418 base::AutoLock lock(immediate_incoming_queue_lock_);
409 return !any_thread().immediate_incoming_queue.empty(); 419 return !immediate_incoming_queue().empty();
410 } 420 }
411 421
412 base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() { 422 base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() {
413 // Note we don't scheduled a wakeup for disabled queues. 423 // Note we don't scheduled a wakeup for disabled queues.
414 if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled()) 424 if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled())
415 return base::nullopt; 425 return base::nullopt;
416 426
417 return main_thread_only().delayed_incoming_queue.top().delayed_run_time; 427 return main_thread_only().delayed_incoming_queue.top().delayed_run_time;
418 } 428 }
419 429
(...skipping 19 matching lines...) Expand all
439 // Make sure the next wake up is scheduled. 449 // Make sure the next wake up is scheduled.
440 if (!main_thread_only().delayed_incoming_queue.empty()) { 450 if (!main_thread_only().delayed_incoming_queue.empty()) {
441 return DelayedWakeUp{ 451 return DelayedWakeUp{
442 main_thread_only().delayed_incoming_queue.top().delayed_run_time, 452 main_thread_only().delayed_incoming_queue.top().delayed_run_time,
443 main_thread_only().delayed_incoming_queue.top().sequence_num}; 453 main_thread_only().delayed_incoming_queue.top().sequence_num};
444 } 454 }
445 455
446 return base::nullopt; 456 return base::nullopt;
447 } 457 }
448 458
449 void TaskQueueImpl::TraceQueueSize(bool is_locked) const { 459 void TaskQueueImpl::TraceQueueSize() const {
450 bool is_tracing; 460 bool is_tracing;
451 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, 461 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
452 &is_tracing); 462 &is_tracing);
453 if (!is_tracing) 463 if (!is_tracing)
454 return; 464 return;
455 465
456 // It's only safe to access the work queues from the main thread. 466 // It's only safe to access the work queues from the main thread.
457 // TODO(alexclarke): We should find another way of tracing this 467 // TODO(alexclarke): We should find another way of tracing this
458 if (base::PlatformThread::CurrentId() != thread_id_) 468 if (base::PlatformThread::CurrentId() != thread_id_)
459 return; 469 return;
460 470
461 if (!is_locked) 471 base::AutoLock lock(immediate_incoming_queue_lock_);
462 any_thread_lock_.Acquire();
463 else
464 any_thread_lock_.AssertAcquired();
465 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(), 472 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(),
466 any_thread().immediate_incoming_queue.size() + 473 immediate_incoming_queue().size() +
467 main_thread_only().immediate_work_queue->Size() + 474 main_thread_only().immediate_work_queue->Size() +
468 main_thread_only().delayed_work_queue->Size() + 475 main_thread_only().delayed_work_queue->Size() +
469 main_thread_only().delayed_incoming_queue.size()); 476 main_thread_only().delayed_incoming_queue.size());
470 if (!is_locked)
471 any_thread_lock_.Release();
472 } 477 }
473 478
474 const char* TaskQueueImpl::GetName() const { 479 const char* TaskQueueImpl::GetName() const {
475 return name_; 480 return name_;
476 } 481 }
477 482
478 TaskQueue::QueueType TaskQueueImpl::GetQueueType() const { 483 TaskQueue::QueueType TaskQueueImpl::GetQueueType() const {
479 return type_; 484 return type_;
480 } 485 }
481 486
482 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { 487 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
483 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority()) 488 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority())
484 return; 489 return;
485 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this, 490 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this,
486 priority); 491 priority);
487 } 492 }
488 493
489 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const { 494 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
490 size_t set_index = immediate_work_queue()->work_queue_set_index(); 495 size_t set_index = immediate_work_queue()->work_queue_set_index();
491 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index()); 496 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index());
492 return static_cast<TaskQueue::QueuePriority>(set_index); 497 return static_cast<TaskQueue::QueuePriority>(set_index);
493 } 498 }
494 499
495 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { 500 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
496 base::AutoLock lock(any_thread_lock_); 501 base::AutoLock lock(any_thread_lock_);
502 base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
497 state->BeginDictionary(); 503 state->BeginDictionary();
498 state->SetString("name", GetName()); 504 state->SetString("name", GetName());
499 state->SetString( 505 state->SetString(
500 "task_queue_id", 506 "task_queue_id",
501 base::StringPrintf("%" PRIx64, static_cast<uint64_t>( 507 base::StringPrintf("%" PRIx64, static_cast<uint64_t>(
502 reinterpret_cast<uintptr_t>(this)))); 508 reinterpret_cast<uintptr_t>(this))));
503 state->SetBoolean("enabled", IsQueueEnabled()); 509 state->SetBoolean("enabled", IsQueueEnabled());
504 state->SetString("time_domain_name", 510 state->SetString("time_domain_name",
505 main_thread_only().time_domain->GetName()); 511 main_thread_only().time_domain->GetName());
506 bool verbose_tracing_enabled = false; 512 bool verbose_tracing_enabled = false;
507 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 513 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
508 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); 514 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
509 state->SetInteger("immediate_incoming_queue_size", 515 state->SetInteger("immediate_incoming_queue_size",
510 any_thread().immediate_incoming_queue.size()); 516 immediate_incoming_queue().size());
511 state->SetInteger("delayed_incoming_queue_size", 517 state->SetInteger("delayed_incoming_queue_size",
512 main_thread_only().delayed_incoming_queue.size()); 518 main_thread_only().delayed_incoming_queue.size());
513 state->SetInteger("immediate_work_queue_size", 519 state->SetInteger("immediate_work_queue_size",
514 main_thread_only().immediate_work_queue->Size()); 520 main_thread_only().immediate_work_queue->Size());
515 state->SetInteger("delayed_work_queue_size", 521 state->SetInteger("delayed_work_queue_size",
516 main_thread_only().delayed_work_queue->Size()); 522 main_thread_only().delayed_work_queue->Size());
517 if (!main_thread_only().delayed_incoming_queue.empty()) { 523 if (!main_thread_only().delayed_incoming_queue.empty()) {
518 base::TimeDelta delay_to_next_task = 524 base::TimeDelta delay_to_next_task =
519 (main_thread_only().delayed_incoming_queue.top().delayed_run_time - 525 (main_thread_only().delayed_incoming_queue.top().delayed_run_time -
520 main_thread_only().time_domain->CreateLazyNow().Now()); 526 main_thread_only().time_domain->CreateLazyNow().Now());
521 state->SetDouble("delay_to_next_task_ms", 527 state->SetDouble("delay_to_next_task_ms",
522 delay_to_next_task.InMillisecondsF()); 528 delay_to_next_task.InMillisecondsF());
523 } 529 }
524 if (main_thread_only().current_fence) 530 if (main_thread_only().current_fence)
525 state->SetInteger("current_fence", main_thread_only().current_fence); 531 state->SetInteger("current_fence", main_thread_only().current_fence);
526 if (verbose_tracing_enabled) { 532 if (verbose_tracing_enabled) {
527 state->BeginArray("immediate_incoming_queue"); 533 state->BeginArray("immediate_incoming_queue");
528 QueueAsValueInto(any_thread().immediate_incoming_queue, state); 534 QueueAsValueInto(immediate_incoming_queue(), state);
529 state->EndArray(); 535 state->EndArray();
530 state->BeginArray("delayed_work_queue"); 536 state->BeginArray("delayed_work_queue");
531 main_thread_only().delayed_work_queue->AsValueInto(state); 537 main_thread_only().delayed_work_queue->AsValueInto(state);
532 state->EndArray(); 538 state->EndArray();
533 state->BeginArray("immediate_work_queue"); 539 state->BeginArray("immediate_work_queue");
534 main_thread_only().immediate_work_queue->AsValueInto(state); 540 main_thread_only().immediate_work_queue->AsValueInto(state);
535 state->EndArray(); 541 state->EndArray();
536 state->BeginArray("delayed_incoming_queue"); 542 state->BeginArray("delayed_incoming_queue");
537 QueueAsValueInto(main_thread_only().delayed_incoming_queue, state); 543 QueueAsValueInto(main_thread_only().delayed_incoming_queue, state);
538 state->EndArray(); 544 state->EndArray();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 631
626 // Tasks posted after this point will have a strictly higher enqueue order 632 // Tasks posted after this point will have a strictly higher enqueue order
627 // and will be blocked from running. 633 // and will be blocked from running.
628 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence( 634 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence(
629 main_thread_only().current_fence); 635 main_thread_only().current_fence);
630 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence( 636 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence(
631 main_thread_only().current_fence); 637 main_thread_only().current_fence);
632 638
633 if (!task_unblocked && previous_fence && 639 if (!task_unblocked && previous_fence &&
634 previous_fence < main_thread_only().current_fence) { 640 previous_fence < main_thread_only().current_fence) {
635 base::AutoLock lock(any_thread_lock_); 641 base::AutoLock lock(immediate_incoming_queue_lock_);
636 if (!any_thread().immediate_incoming_queue.empty() && 642 if (!immediate_incoming_queue().empty() &&
637 any_thread().immediate_incoming_queue.front().enqueue_order() > 643 immediate_incoming_queue().front().enqueue_order() > previous_fence &&
638 previous_fence && 644 immediate_incoming_queue().front().enqueue_order() <
639 any_thread().immediate_incoming_queue.front().enqueue_order() <
640 main_thread_only().current_fence) { 645 main_thread_only().current_fence) {
641 task_unblocked = true; 646 task_unblocked = true;
642 } 647 }
643 } 648 }
644 649
645 if (IsQueueEnabled() && task_unblocked) { 650 if (IsQueueEnabled() && task_unblocked) {
646 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( 651 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
647 FROM_HERE); 652 FROM_HERE);
648 } 653 }
649 } 654 }
650 655
651 void TaskQueueImpl::RemoveFence() { 656 void TaskQueueImpl::RemoveFence() {
652 if (!main_thread_only().task_queue_manager) 657 if (!main_thread_only().task_queue_manager)
653 return; 658 return;
654 659
655 EnqueueOrder previous_fence = main_thread_only().current_fence; 660 EnqueueOrder previous_fence = main_thread_only().current_fence;
656 main_thread_only().current_fence = 0; 661 main_thread_only().current_fence = 0;
657 662
658 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence(); 663 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence();
659 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); 664 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
660 665
661 if (!task_unblocked && previous_fence) { 666 if (!task_unblocked && previous_fence) {
662 base::AutoLock lock(any_thread_lock_); 667 base::AutoLock lock(immediate_incoming_queue_lock_);
663 if (!any_thread().immediate_incoming_queue.empty() && 668 if (!immediate_incoming_queue().empty() &&
664 any_thread().immediate_incoming_queue.front().enqueue_order() > 669 immediate_incoming_queue().front().enqueue_order() > previous_fence) {
665 previous_fence) {
666 task_unblocked = true; 670 task_unblocked = true;
667 } 671 }
668 } 672 }
669 673
670 if (IsQueueEnabled() && task_unblocked) { 674 if (IsQueueEnabled() && task_unblocked) {
671 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( 675 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
672 FROM_HERE); 676 FROM_HERE);
673 } 677 }
674 } 678 }
675 679
676 bool TaskQueueImpl::BlockedByFence() const { 680 bool TaskQueueImpl::BlockedByFence() const {
677 if (!main_thread_only().current_fence) 681 if (!main_thread_only().current_fence)
678 return false; 682 return false;
679 683
680 if (!main_thread_only().immediate_work_queue->BlockedByFence() || 684 if (!main_thread_only().immediate_work_queue->BlockedByFence() ||
681 !main_thread_only().delayed_work_queue->BlockedByFence()) { 685 !main_thread_only().delayed_work_queue->BlockedByFence()) {
682 return false; 686 return false;
683 } 687 }
684 688
685 base::AutoLock lock(any_thread_lock_); 689 base::AutoLock lock(immediate_incoming_queue_lock_);
686 if (any_thread().immediate_incoming_queue.empty()) 690 if (immediate_incoming_queue().empty())
687 return true; 691 return true;
688 692
689 return any_thread().immediate_incoming_queue.front().enqueue_order() > 693 return immediate_incoming_queue().front().enqueue_order() >
690 main_thread_only().current_fence; 694 main_thread_only().current_fence;
691 } 695 }
692 696
693 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const { 697 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const {
694 if (!IsQueueEnabled()) 698 if (!IsQueueEnabled())
695 return false; 699 return false;
696 700
697 if (!main_thread_only().current_fence) 701 if (!main_thread_only().current_fence)
698 return true; 702 return true;
699 703
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 812
809 void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) { 813 void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) {
810 if (!main_thread_only().task_queue_manager) 814 if (!main_thread_only().task_queue_manager)
811 return; 815 return;
812 816
813 if (enable) { 817 if (enable) {
814 // Check if there's any immediate work on either queue. 818 // Check if there's any immediate work on either queue.
815 bool immediate_queues_empty = 819 bool immediate_queues_empty =
816 main_thread_only().immediate_work_queue->Empty(); 820 main_thread_only().immediate_work_queue->Empty();
817 if (immediate_queues_empty) { 821 if (immediate_queues_empty) {
818 base::AutoLock lock(any_thread_lock_); 822 base::AutoLock lock(immediate_incoming_queue_lock_);
819 immediate_queues_empty = any_thread().immediate_incoming_queue.empty(); 823 immediate_queues_empty = immediate_incoming_queue().empty();
820 } 824 }
821 // Avoid holding the lock while we fire the notification. 825 // Avoid holding the lock while we fire the notification.
822 if (!immediate_queues_empty) 826 if (!immediate_queues_empty)
823 main_thread_only().time_domain->OnQueueHasImmediateWork(this); 827 main_thread_only().time_domain->OnQueueHasImmediateWork(this);
824 828
825 if (!main_thread_only().delayed_incoming_queue.empty()) { 829 if (!main_thread_only().delayed_incoming_queue.empty()) {
826 main_thread_only().time_domain->ScheduleDelayedWork( 830 main_thread_only().time_domain->ScheduleDelayedWork(
827 this, 831 this,
828 {main_thread_only().delayed_incoming_queue.top().delayed_run_time, 832 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
829 main_thread_only().delayed_incoming_queue.top().sequence_num}, 833 main_thread_only().delayed_incoming_queue.top().sequence_num},
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 this, 879 this,
876 {main_thread_only().delayed_incoming_queue.top().delayed_run_time, 880 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
877 main_thread_only().delayed_incoming_queue.top().sequence_num}, 881 main_thread_only().delayed_incoming_queue.top().sequence_num},
878 main_thread_only().time_domain->Now()); 882 main_thread_only().time_domain->Now());
879 } 883 }
880 } 884 }
881 } 885 }
882 886
883 void TaskQueueImpl::PushImmediateIncomingTaskForTest( 887 void TaskQueueImpl::PushImmediateIncomingTaskForTest(
884 TaskQueueImpl::Task&& task) { 888 TaskQueueImpl::Task&& task) {
885 base::AutoLock lock(any_thread_lock_); 889 base::AutoLock lock(immediate_incoming_queue_lock_);
886 any_thread().immediate_incoming_queue.push_back(std::move(task)); 890 immediate_incoming_queue().push_back(std::move(task));
887 } 891 }
888 892
889 } // namespace internal 893 } // namespace internal
890 } // namespace scheduler 894 } // namespace scheduler
891 } // namespace blink 895 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698