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

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 was_immediate_incoming_queue_empty;
340
341 {
342 base::AutoLock lock(immediate_incoming_queue_lock_);
343 was_immediate_incoming_queue_empty = immediate_incoming_queue().empty();
344 immediate_incoming_queue().emplace_back(posted_from, std::move(task),
345 desired_run_time, sequence_number,
346 nestable, sequence_number);
347 any_thread().task_queue_manager->DidQueueTask(
348 immediate_incoming_queue().back());
349 }
350
351 if (was_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 TraceQueueSize();
350 sequence_number);
351 any_thread().task_queue_manager->DidQueueTask(
352 any_thread().immediate_incoming_queue.back());
353 TraceQueueSize(true);
354 } 363 }
355 364
356 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { 365 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
357 if (!main_thread_only().immediate_work_queue->Empty()) 366 if (!main_thread_only().immediate_work_queue->Empty())
358 return; 367 return;
359 368
360 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue(); 369 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue();
361 } 370 }
362 371
363 WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() { 372 WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() {
364 base::AutoLock lock(any_thread_lock_); 373 base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
365 WTF::Deque<TaskQueueImpl::Task> queue; 374 WTF::Deque<TaskQueueImpl::Task> queue;
366 queue.swap(any_thread().immediate_incoming_queue); 375 queue.swap(immediate_incoming_queue());
367 return queue; 376 return queue;
368 } 377 }
369 378
370 bool TaskQueueImpl::IsEmpty() const { 379 bool TaskQueueImpl::IsEmpty() const {
371 if (!main_thread_only().delayed_work_queue->Empty() || 380 if (!main_thread_only().delayed_work_queue->Empty() ||
372 !main_thread_only().delayed_incoming_queue.empty() || 381 !main_thread_only().delayed_incoming_queue.empty() ||
373 !main_thread_only().immediate_work_queue->Empty()) { 382 !main_thread_only().immediate_work_queue->Empty()) {
374 return false; 383 return false;
375 } 384 }
376 385
377 base::AutoLock lock(any_thread_lock_); 386 base::AutoLock lock(immediate_incoming_queue_lock_);
378 return any_thread().immediate_incoming_queue.empty(); 387 return immediate_incoming_queue().empty();
379 } 388 }
380 389
381 size_t TaskQueueImpl::GetNumberOfPendingTasks() const { 390 size_t TaskQueueImpl::GetNumberOfPendingTasks() const {
382 size_t task_count = 0; 391 size_t task_count = 0;
383 task_count += main_thread_only().delayed_work_queue->Size(); 392 task_count += main_thread_only().delayed_work_queue->Size();
384 task_count += main_thread_only().delayed_incoming_queue.size(); 393 task_count += main_thread_only().delayed_incoming_queue.size();
385 task_count += main_thread_only().immediate_work_queue->Size(); 394 task_count += main_thread_only().immediate_work_queue->Size();
386 395
387 base::AutoLock lock(any_thread_lock_); 396 base::AutoLock lock(immediate_incoming_queue_lock_);
388 task_count += any_thread().immediate_incoming_queue.size(); 397 task_count += immediate_incoming_queue().size();
389 return task_count; 398 return task_count;
390 } 399 }
391 400
392 bool TaskQueueImpl::HasPendingImmediateWork() const { 401 bool TaskQueueImpl::HasPendingImmediateWork() const {
393 // Any work queue tasks count as immediate work. 402 // Any work queue tasks count as immediate work.
394 if (!main_thread_only().delayed_work_queue->Empty() || 403 if (!main_thread_only().delayed_work_queue->Empty() ||
395 !main_thread_only().immediate_work_queue->Empty()) { 404 !main_thread_only().immediate_work_queue->Empty()) {
396 return true; 405 return true;
397 } 406 }
398 407
399 // Tasks on |delayed_incoming_queue| that could run now, count as 408 // Tasks on |delayed_incoming_queue| that could run now, count as
400 // immediate work. 409 // immediate work.
401 if (!main_thread_only().delayed_incoming_queue.empty() && 410 if (!main_thread_only().delayed_incoming_queue.empty() &&
402 main_thread_only().delayed_incoming_queue.top().delayed_run_time <= 411 main_thread_only().delayed_incoming_queue.top().delayed_run_time <=
403 main_thread_only().time_domain->CreateLazyNow().Now()) { 412 main_thread_only().time_domain->CreateLazyNow().Now()) {
404 return true; 413 return true;
405 } 414 }
406 415
407 // Finally tasks on |immediate_incoming_queue| count as immediate work. 416 // Finally tasks on |immediate_incoming_queue| count as immediate work.
408 base::AutoLock lock(any_thread_lock_); 417 base::AutoLock lock(immediate_incoming_queue_lock_);
409 return !any_thread().immediate_incoming_queue.empty(); 418 return !immediate_incoming_queue().empty();
410 } 419 }
411 420
412 base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() { 421 base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() {
413 // Note we don't scheduled a wakeup for disabled queues. 422 // Note we don't scheduled a wakeup for disabled queues.
414 if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled()) 423 if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled())
415 return base::nullopt; 424 return base::nullopt;
416 425
417 return main_thread_only().delayed_incoming_queue.top().delayed_run_time; 426 return main_thread_only().delayed_incoming_queue.top().delayed_run_time;
418 } 427 }
419 428
(...skipping 19 matching lines...) Expand all
439 // Make sure the next wake up is scheduled. 448 // Make sure the next wake up is scheduled.
440 if (!main_thread_only().delayed_incoming_queue.empty()) { 449 if (!main_thread_only().delayed_incoming_queue.empty()) {
441 return DelayedWakeUp{ 450 return DelayedWakeUp{
442 main_thread_only().delayed_incoming_queue.top().delayed_run_time, 451 main_thread_only().delayed_incoming_queue.top().delayed_run_time,
443 main_thread_only().delayed_incoming_queue.top().sequence_num}; 452 main_thread_only().delayed_incoming_queue.top().sequence_num};
444 } 453 }
445 454
446 return base::nullopt; 455 return base::nullopt;
447 } 456 }
448 457
449 void TaskQueueImpl::TraceQueueSize(bool is_locked) const { 458 void TaskQueueImpl::TraceQueueSize() const {
450 bool is_tracing; 459 bool is_tracing;
451 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, 460 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
452 &is_tracing); 461 &is_tracing);
453 if (!is_tracing) 462 if (!is_tracing)
454 return; 463 return;
455 464
456 // It's only safe to access the work queues from the main thread. 465 // It's only safe to access the work queues from the main thread.
457 // TODO(alexclarke): We should find another way of tracing this 466 // TODO(alexclarke): We should find another way of tracing this
458 if (base::PlatformThread::CurrentId() != thread_id_) 467 if (base::PlatformThread::CurrentId() != thread_id_)
459 return; 468 return;
460 469
461 if (!is_locked) 470 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(), 471 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(),
466 any_thread().immediate_incoming_queue.size() + 472 immediate_incoming_queue().size() +
467 main_thread_only().immediate_work_queue->Size() + 473 main_thread_only().immediate_work_queue->Size() +
468 main_thread_only().delayed_work_queue->Size() + 474 main_thread_only().delayed_work_queue->Size() +
469 main_thread_only().delayed_incoming_queue.size()); 475 main_thread_only().delayed_incoming_queue.size());
470 if (!is_locked)
471 any_thread_lock_.Release();
472 } 476 }
473 477
474 const char* TaskQueueImpl::GetName() const { 478 const char* TaskQueueImpl::GetName() const {
475 return name_; 479 return name_;
476 } 480 }
477 481
478 TaskQueue::QueueType TaskQueueImpl::GetQueueType() const { 482 TaskQueue::QueueType TaskQueueImpl::GetQueueType() const {
479 return type_; 483 return type_;
480 } 484 }
481 485
482 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { 486 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
483 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority()) 487 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority())
484 return; 488 return;
485 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this, 489 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this,
486 priority); 490 priority);
487 } 491 }
488 492
489 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const { 493 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
490 size_t set_index = immediate_work_queue()->work_queue_set_index(); 494 size_t set_index = immediate_work_queue()->work_queue_set_index();
491 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index()); 495 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index());
492 return static_cast<TaskQueue::QueuePriority>(set_index); 496 return static_cast<TaskQueue::QueuePriority>(set_index);
493 } 497 }
494 498
495 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { 499 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
496 base::AutoLock lock(any_thread_lock_); 500 base::AutoLock lock(any_thread_lock_);
501 base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
497 state->BeginDictionary(); 502 state->BeginDictionary();
498 state->SetString("name", GetName()); 503 state->SetString("name", GetName());
499 state->SetString( 504 state->SetString(
500 "task_queue_id", 505 "task_queue_id",
501 base::StringPrintf("%" PRIx64, static_cast<uint64_t>( 506 base::StringPrintf("%" PRIx64, static_cast<uint64_t>(
502 reinterpret_cast<uintptr_t>(this)))); 507 reinterpret_cast<uintptr_t>(this))));
503 state->SetBoolean("enabled", IsQueueEnabled()); 508 state->SetBoolean("enabled", IsQueueEnabled());
504 state->SetString("time_domain_name", 509 state->SetString("time_domain_name",
505 main_thread_only().time_domain->GetName()); 510 main_thread_only().time_domain->GetName());
506 bool verbose_tracing_enabled = false; 511 bool verbose_tracing_enabled = false;
507 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 512 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
508 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); 513 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
509 state->SetInteger("immediate_incoming_queue_size", 514 state->SetInteger("immediate_incoming_queue_size",
510 any_thread().immediate_incoming_queue.size()); 515 immediate_incoming_queue().size());
511 state->SetInteger("delayed_incoming_queue_size", 516 state->SetInteger("delayed_incoming_queue_size",
512 main_thread_only().delayed_incoming_queue.size()); 517 main_thread_only().delayed_incoming_queue.size());
513 state->SetInteger("immediate_work_queue_size", 518 state->SetInteger("immediate_work_queue_size",
514 main_thread_only().immediate_work_queue->Size()); 519 main_thread_only().immediate_work_queue->Size());
515 state->SetInteger("delayed_work_queue_size", 520 state->SetInteger("delayed_work_queue_size",
516 main_thread_only().delayed_work_queue->Size()); 521 main_thread_only().delayed_work_queue->Size());
517 if (!main_thread_only().delayed_incoming_queue.empty()) { 522 if (!main_thread_only().delayed_incoming_queue.empty()) {
518 base::TimeDelta delay_to_next_task = 523 base::TimeDelta delay_to_next_task =
519 (main_thread_only().delayed_incoming_queue.top().delayed_run_time - 524 (main_thread_only().delayed_incoming_queue.top().delayed_run_time -
520 main_thread_only().time_domain->CreateLazyNow().Now()); 525 main_thread_only().time_domain->CreateLazyNow().Now());
521 state->SetDouble("delay_to_next_task_ms", 526 state->SetDouble("delay_to_next_task_ms",
522 delay_to_next_task.InMillisecondsF()); 527 delay_to_next_task.InMillisecondsF());
523 } 528 }
524 if (main_thread_only().current_fence) 529 if (main_thread_only().current_fence)
525 state->SetInteger("current_fence", main_thread_only().current_fence); 530 state->SetInteger("current_fence", main_thread_only().current_fence);
526 if (verbose_tracing_enabled) { 531 if (verbose_tracing_enabled) {
527 state->BeginArray("immediate_incoming_queue"); 532 state->BeginArray("immediate_incoming_queue");
528 QueueAsValueInto(any_thread().immediate_incoming_queue, state); 533 QueueAsValueInto(immediate_incoming_queue(), state);
529 state->EndArray(); 534 state->EndArray();
530 state->BeginArray("delayed_work_queue"); 535 state->BeginArray("delayed_work_queue");
531 main_thread_only().delayed_work_queue->AsValueInto(state); 536 main_thread_only().delayed_work_queue->AsValueInto(state);
532 state->EndArray(); 537 state->EndArray();
533 state->BeginArray("immediate_work_queue"); 538 state->BeginArray("immediate_work_queue");
534 main_thread_only().immediate_work_queue->AsValueInto(state); 539 main_thread_only().immediate_work_queue->AsValueInto(state);
535 state->EndArray(); 540 state->EndArray();
536 state->BeginArray("delayed_incoming_queue"); 541 state->BeginArray("delayed_incoming_queue");
537 QueueAsValueInto(main_thread_only().delayed_incoming_queue, state); 542 QueueAsValueInto(main_thread_only().delayed_incoming_queue, state);
538 state->EndArray(); 543 state->EndArray();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 630
626 // Tasks posted after this point will have a strictly higher enqueue order 631 // Tasks posted after this point will have a strictly higher enqueue order
627 // and will be blocked from running. 632 // and will be blocked from running.
628 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence( 633 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence(
629 main_thread_only().current_fence); 634 main_thread_only().current_fence);
630 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence( 635 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence(
631 main_thread_only().current_fence); 636 main_thread_only().current_fence);
632 637
633 if (!task_unblocked && previous_fence && 638 if (!task_unblocked && previous_fence &&
634 previous_fence < main_thread_only().current_fence) { 639 previous_fence < main_thread_only().current_fence) {
635 base::AutoLock lock(any_thread_lock_); 640 base::AutoLock lock(immediate_incoming_queue_lock_);
636 if (!any_thread().immediate_incoming_queue.empty() && 641 if (!immediate_incoming_queue().empty() &&
637 any_thread().immediate_incoming_queue.front().enqueue_order() > 642 immediate_incoming_queue().front().enqueue_order() > previous_fence &&
638 previous_fence && 643 immediate_incoming_queue().front().enqueue_order() <
639 any_thread().immediate_incoming_queue.front().enqueue_order() <
640 main_thread_only().current_fence) { 644 main_thread_only().current_fence) {
641 task_unblocked = true; 645 task_unblocked = true;
642 } 646 }
643 } 647 }
644 648
645 if (IsQueueEnabled() && task_unblocked) { 649 if (IsQueueEnabled() && task_unblocked) {
646 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( 650 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
647 FROM_HERE); 651 FROM_HERE);
648 } 652 }
649 } 653 }
650 654
651 void TaskQueueImpl::RemoveFence() { 655 void TaskQueueImpl::RemoveFence() {
652 if (!main_thread_only().task_queue_manager) 656 if (!main_thread_only().task_queue_manager)
653 return; 657 return;
654 658
655 EnqueueOrder previous_fence = main_thread_only().current_fence; 659 EnqueueOrder previous_fence = main_thread_only().current_fence;
656 main_thread_only().current_fence = 0; 660 main_thread_only().current_fence = 0;
657 661
658 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence(); 662 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence();
659 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); 663 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
660 664
661 if (!task_unblocked && previous_fence) { 665 if (!task_unblocked && previous_fence) {
662 base::AutoLock lock(any_thread_lock_); 666 base::AutoLock lock(immediate_incoming_queue_lock_);
663 if (!any_thread().immediate_incoming_queue.empty() && 667 if (!immediate_incoming_queue().empty() &&
664 any_thread().immediate_incoming_queue.front().enqueue_order() > 668 immediate_incoming_queue().front().enqueue_order() > previous_fence) {
665 previous_fence) {
666 task_unblocked = true; 669 task_unblocked = true;
667 } 670 }
668 } 671 }
669 672
670 if (IsQueueEnabled() && task_unblocked) { 673 if (IsQueueEnabled() && task_unblocked) {
671 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( 674 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
672 FROM_HERE); 675 FROM_HERE);
673 } 676 }
674 } 677 }
675 678
676 bool TaskQueueImpl::BlockedByFence() const { 679 bool TaskQueueImpl::BlockedByFence() const {
677 if (!main_thread_only().current_fence) 680 if (!main_thread_only().current_fence)
678 return false; 681 return false;
679 682
680 if (!main_thread_only().immediate_work_queue->BlockedByFence() || 683 if (!main_thread_only().immediate_work_queue->BlockedByFence() ||
681 !main_thread_only().delayed_work_queue->BlockedByFence()) { 684 !main_thread_only().delayed_work_queue->BlockedByFence()) {
682 return false; 685 return false;
683 } 686 }
684 687
685 base::AutoLock lock(any_thread_lock_); 688 base::AutoLock lock(immediate_incoming_queue_lock_);
686 if (any_thread().immediate_incoming_queue.empty()) 689 if (immediate_incoming_queue().empty())
687 return true; 690 return true;
688 691
689 return any_thread().immediate_incoming_queue.front().enqueue_order() > 692 return immediate_incoming_queue().front().enqueue_order() >
690 main_thread_only().current_fence; 693 main_thread_only().current_fence;
691 } 694 }
692 695
693 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const { 696 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const {
694 if (!IsQueueEnabled()) 697 if (!IsQueueEnabled())
695 return false; 698 return false;
696 699
697 if (!main_thread_only().current_fence) 700 if (!main_thread_only().current_fence)
698 return true; 701 return true;
699 702
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 811
809 void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) { 812 void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) {
810 if (!main_thread_only().task_queue_manager) 813 if (!main_thread_only().task_queue_manager)
811 return; 814 return;
812 815
813 if (enable) { 816 if (enable) {
814 // Check if there's any immediate work on either queue. 817 // Check if there's any immediate work on either queue.
815 bool immediate_queues_empty = 818 bool immediate_queues_empty =
816 main_thread_only().immediate_work_queue->Empty(); 819 main_thread_only().immediate_work_queue->Empty();
817 if (immediate_queues_empty) { 820 if (immediate_queues_empty) {
818 base::AutoLock lock(any_thread_lock_); 821 base::AutoLock lock(immediate_incoming_queue_lock_);
819 immediate_queues_empty = any_thread().immediate_incoming_queue.empty(); 822 immediate_queues_empty = immediate_incoming_queue().empty();
820 } 823 }
821 // Avoid holding the lock while we fire the notification. 824 // Avoid holding the lock while we fire the notification.
822 if (!immediate_queues_empty) 825 if (!immediate_queues_empty)
823 main_thread_only().time_domain->OnQueueHasImmediateWork(this); 826 main_thread_only().time_domain->OnQueueHasImmediateWork(this);
824 827
825 if (!main_thread_only().delayed_incoming_queue.empty()) { 828 if (!main_thread_only().delayed_incoming_queue.empty()) {
826 main_thread_only().time_domain->ScheduleDelayedWork( 829 main_thread_only().time_domain->ScheduleDelayedWork(
827 this, 830 this,
828 {main_thread_only().delayed_incoming_queue.top().delayed_run_time, 831 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
829 main_thread_only().delayed_incoming_queue.top().sequence_num}, 832 main_thread_only().delayed_incoming_queue.top().sequence_num},
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 this, 878 this,
876 {main_thread_only().delayed_incoming_queue.top().delayed_run_time, 879 {main_thread_only().delayed_incoming_queue.top().delayed_run_time,
877 main_thread_only().delayed_incoming_queue.top().sequence_num}, 880 main_thread_only().delayed_incoming_queue.top().sequence_num},
878 main_thread_only().time_domain->Now()); 881 main_thread_only().time_domain->Now());
879 } 882 }
880 } 883 }
881 } 884 }
882 885
883 void TaskQueueImpl::PushImmediateIncomingTaskForTest( 886 void TaskQueueImpl::PushImmediateIncomingTaskForTest(
884 TaskQueueImpl::Task&& task) { 887 TaskQueueImpl::Task&& task) {
885 base::AutoLock lock(any_thread_lock_); 888 base::AutoLock lock(immediate_incoming_queue_lock_);
886 any_thread().immediate_incoming_queue.push_back(std::move(task)); 889 immediate_incoming_queue().push_back(std::move(task));
887 } 890 }
888 891
889 } // namespace internal 892 } // namespace internal
890 } // namespace scheduler 893 } // namespace scheduler
891 } // namespace blink 894 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698