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

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

Issue 2781323003: [scheduler] Split lock in TaskQueueImpl. (Closed)
Patch Set: Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
index b534f5179759da5509ce80c1d50b6c27dd8e7759..9263754c83218e43fe8d0d563c44e7f91e2cfedb 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -169,6 +169,7 @@ TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
void TaskQueueImpl::UnregisterTaskQueue() {
base::AutoLock lock(any_thread_lock_);
+ base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
if (main_thread_only().time_domain)
main_thread_only().time_domain->UnregisterQueue(this);
if (!any_thread().task_queue_manager)
@@ -180,7 +181,7 @@ void TaskQueueImpl::UnregisterTaskQueue() {
any_thread().task_queue_manager = nullptr;
main_thread_only().task_queue_manager = nullptr;
main_thread_only().delayed_incoming_queue = std::priority_queue<Task>();
- any_thread().immediate_incoming_queue.clear();
+ immediate_incoming_queue().clear();
main_thread_only().immediate_work_queue.reset();
main_thread_only().delayed_work_queue.reset();
}
@@ -286,7 +287,7 @@ void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread(
this, {delayed_run_time, pending_task.sequence_num}, now);
}
- TraceQueueSize(false);
+ TraceQueueSize();
}
void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
@@ -321,7 +322,7 @@ void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) {
PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task),
time_domain_now);
}
- TraceQueueSize(false);
+ TraceQueueSize();
}
void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
@@ -332,7 +333,12 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
bool nestable) {
// If the |immediate_incoming_queue| is empty we need a DoWork posted to make
// it run.
- if (any_thread().immediate_incoming_queue.empty()) {
+ bool is_immediate_incoming_queue_empty;
+ {
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ is_immediate_incoming_queue_empty = immediate_incoming_queue().empty();
+ }
+ if (is_immediate_incoming_queue_empty) {
// However there's no point posting a DoWork for a blocked queue. NB we can
// only tell if it's disabled from the main thread.
bool queue_is_blocked =
@@ -342,12 +348,17 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
this, sequence_number, queue_is_blocked);
any_thread().time_domain->OnQueueHasImmediateWork(this);
}
- any_thread().immediate_incoming_queue.emplace_back(
- posted_from, task, desired_run_time, sequence_number, nestable,
- sequence_number);
- any_thread().task_queue_manager->DidQueueTask(
- any_thread().immediate_incoming_queue.back());
- TraceQueueSize(true);
+
+ Task* queued_task;
+ {
+ base::AutoLock lock(immediate_incoming_queue_lock_);
alex clarke (OOO till 29th) 2017/03/30 13:23:46 Can we avoid locking this twice?
altimin 2017/03/30 14:04:36 Done.
+ immediate_incoming_queue().emplace_back(posted_from, task, desired_run_time,
+ sequence_number, nestable,
+ sequence_number);
+ queued_task = &immediate_incoming_queue().back();
+ }
+ any_thread().task_queue_manager->DidQueueTask(*queued_task);
+ TraceQueueSize();
}
void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
@@ -359,8 +370,9 @@ void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() {
base::AutoLock lock(any_thread_lock_);
+ base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
WTF::Deque<TaskQueueImpl::Task> queue;
- queue.swap(any_thread().immediate_incoming_queue);
+ queue.swap(immediate_incoming_queue());
return queue;
}
@@ -371,8 +383,8 @@ bool TaskQueueImpl::IsEmpty() const {
return false;
}
- base::AutoLock lock(any_thread_lock_);
- return any_thread().immediate_incoming_queue.empty();
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ return immediate_incoming_queue().empty();
}
size_t TaskQueueImpl::GetNumberOfPendingTasks() const {
@@ -381,8 +393,8 @@ size_t TaskQueueImpl::GetNumberOfPendingTasks() const {
task_count += main_thread_only().delayed_incoming_queue.size();
task_count += main_thread_only().immediate_work_queue->Size();
- base::AutoLock lock(any_thread_lock_);
- task_count += any_thread().immediate_incoming_queue.size();
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ task_count += immediate_incoming_queue().size();
return task_count;
}
@@ -402,8 +414,8 @@ bool TaskQueueImpl::HasPendingImmediateWork() const {
}
// Finally tasks on |immediate_incoming_queue| count as immediate work.
- base::AutoLock lock(any_thread_lock_);
- return !any_thread().immediate_incoming_queue.empty();
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ return !immediate_incoming_queue().empty();
}
base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() {
@@ -443,7 +455,7 @@ TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) {
return base::nullopt;
}
-void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
+void TaskQueueImpl::TraceQueueSize() const {
bool is_tracing;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
&is_tracing);
@@ -455,17 +467,12 @@ void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
if (base::PlatformThread::CurrentId() != thread_id_)
return;
- if (!is_locked)
- any_thread_lock_.Acquire();
- else
- any_thread_lock_.AssertAcquired();
+ base::AutoLock lock(immediate_incoming_queue_lock_);
TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(),
- any_thread().immediate_incoming_queue.size() +
+ immediate_incoming_queue().size() +
main_thread_only().immediate_work_queue->Size() +
main_thread_only().delayed_work_queue->Size() +
main_thread_only().delayed_incoming_queue.size());
- if (!is_locked)
- any_thread_lock_.Release();
}
const char* TaskQueueImpl::GetName() const {
@@ -491,6 +498,7 @@ TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
base::AutoLock lock(any_thread_lock_);
+ base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_);
state->BeginDictionary();
state->SetString("name", GetName());
state->SetString(
@@ -504,7 +512,7 @@ void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
state->SetInteger("immediate_incoming_queue_size",
- any_thread().immediate_incoming_queue.size());
+ immediate_incoming_queue().size());
state->SetInteger("delayed_incoming_queue_size",
main_thread_only().delayed_incoming_queue.size());
state->SetInteger("immediate_work_queue_size",
@@ -522,7 +530,7 @@ void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetInteger("current_fence", main_thread_only().current_fence);
if (verbose_tracing_enabled) {
state->BeginArray("immediate_incoming_queue");
- QueueAsValueInto(any_thread().immediate_incoming_queue, state);
+ QueueAsValueInto(immediate_incoming_queue(), state);
state->EndArray();
state->BeginArray("delayed_work_queue");
main_thread_only().delayed_work_queue->AsValueInto(state);
@@ -629,11 +637,10 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) {
if (!task_unblocked && previous_fence &&
previous_fence < main_thread_only().current_fence) {
- base::AutoLock lock(any_thread_lock_);
- if (!any_thread().immediate_incoming_queue.empty() &&
- any_thread().immediate_incoming_queue.front().enqueue_order() >
- previous_fence &&
- any_thread().immediate_incoming_queue.front().enqueue_order() <
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ if (!immediate_incoming_queue().empty() &&
+ immediate_incoming_queue().front().enqueue_order() > previous_fence &&
+ immediate_incoming_queue().front().enqueue_order() <
main_thread_only().current_fence) {
task_unblocked = true;
}
@@ -656,10 +663,9 @@ void TaskQueueImpl::RemoveFence() {
task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
if (!task_unblocked && previous_fence) {
- base::AutoLock lock(any_thread_lock_);
- if (!any_thread().immediate_incoming_queue.empty() &&
- any_thread().immediate_incoming_queue.front().enqueue_order() >
- previous_fence) {
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ if (!immediate_incoming_queue().empty() &&
+ immediate_incoming_queue().front().enqueue_order() > previous_fence) {
task_unblocked = true;
}
}
@@ -679,11 +685,11 @@ bool TaskQueueImpl::BlockedByFence() const {
return false;
}
- base::AutoLock lock(any_thread_lock_);
- if (any_thread().immediate_incoming_queue.empty())
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ if (immediate_incoming_queue().empty())
return true;
- return any_thread().immediate_incoming_queue.front().enqueue_order() >
+ return immediate_incoming_queue().front().enqueue_order() >
main_thread_only().current_fence;
}
@@ -812,8 +818,8 @@ void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) {
bool immediate_queues_empty =
main_thread_only().immediate_work_queue->Empty();
if (immediate_queues_empty) {
- base::AutoLock lock(any_thread_lock_);
- immediate_queues_empty = any_thread().immediate_incoming_queue.empty();
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ immediate_queues_empty = immediate_incoming_queue().empty();
}
// Avoid holding the lock while we fire the notification.
if (!immediate_queues_empty)
@@ -879,8 +885,8 @@ void TaskQueueImpl::SweepCanceledDelayedTasks(base::TimeTicks now) {
void TaskQueueImpl::PushImmediateIncomingTaskForTest(
TaskQueueImpl::Task&& task) {
- base::AutoLock lock(any_thread_lock_);
- any_thread().immediate_incoming_queue.push_back(std::move(task));
+ base::AutoLock lock(immediate_incoming_queue_lock_);
+ immediate_incoming_queue().push_back(std::move(task));
}
} // namespace internal

Powered by Google App Engine
This is Rietveld 408576698