Commit cc3c410d authored by Alex Clarke's avatar Alex Clarke Committed by Commit Bot

SequenceManager: Only record task time if we need to

We don't need task timing on the UI thread, so this patch arranges for
time only to be sampled if we have an observer that needs it.

Bug: 897751
Change-Id: I5915efdb903813a574ca05cee316cb30fa75b39c
Reviewed-on: https://chromium-review.googlesource.com/c/1297425
Commit-Queue: Alex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603059}
parent ca86bf34
...@@ -474,18 +474,24 @@ void SequenceManagerImpl::WillQueueTask(Task* pending_task) { ...@@ -474,18 +474,24 @@ void SequenceManagerImpl::WillQueueTask(Task* pending_task) {
TaskQueue::TaskTiming SequenceManagerImpl::InitializeTaskTiming( TaskQueue::TaskTiming SequenceManagerImpl::InitializeTaskTiming(
internal::TaskQueueImpl* task_queue) { internal::TaskQueueImpl* task_queue) {
bool records_wall_time = bool records_wall_time = ShouldRecordTaskTiming(task_queue);
(task_queue->GetShouldNotifyObservers() &&
main_thread_only().task_time_observers.might_have_observers()) ||
task_queue->RequiresTaskTiming();
bool records_thread_time = records_wall_time && ShouldRecordCPUTimeForTask(); bool records_thread_time = records_wall_time && ShouldRecordCPUTimeForTask();
return TaskQueue::TaskTiming(records_wall_time, records_thread_time); return TaskQueue::TaskTiming(records_wall_time, records_thread_time);
} }
bool SequenceManagerImpl::ShouldRecordTaskTiming(
const internal::TaskQueueImpl* task_queue) {
if (task_queue->RequiresTaskTiming())
return true;
return main_thread_only().nesting_depth == 0 &&
main_thread_only().task_time_observers.might_have_observers();
}
void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task,
LazyNow* time_before_task) { LazyNow* time_before_task) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"),
"SequenceManagerImpl::NotifyWillProcessTaskObservers"); "SequenceManagerImpl::NotifyWillProcessTaskObservers");
if (executing_task->task_queue->GetQuiescenceMonitored()) if (executing_task->task_queue->GetQuiescenceMonitored())
main_thread_only().task_was_run_on_quiescence_monitored_queue = true; main_thread_only().task_was_run_on_quiescence_monitored_queue = true;
...@@ -498,7 +504,9 @@ void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, ...@@ -498,7 +504,9 @@ void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task,
executing_task->pending_task.posted_from.function_name()); executing_task->pending_task.posted_from.function_name());
#endif // OS_NACL #endif // OS_NACL
executing_task->task_timing.RecordTaskStart(time_before_task); bool record_task_timing = ShouldRecordTaskTiming(executing_task->task_queue);
if (record_task_timing)
executing_task->task_timing.RecordTaskStart(time_before_task);
if (!executing_task->task_queue->GetShouldNotifyObservers()) if (!executing_task->task_queue->GetShouldNotifyObservers())
return; return;
...@@ -517,11 +525,7 @@ void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, ...@@ -517,11 +525,7 @@ void SequenceManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task,
executing_task->pending_task); executing_task->pending_task);
} }
bool notify_time_observers = if (!record_task_timing)
main_thread_only().task_time_observers.might_have_observers() ||
executing_task->task_queue->RequiresTaskTiming();
if (!notify_time_observers)
return; return;
if (main_thread_only().nesting_depth == 0) { if (main_thread_only().nesting_depth == 0) {
...@@ -543,13 +547,16 @@ void SequenceManagerImpl::NotifyDidProcessTask(ExecutingTask* executing_task, ...@@ -543,13 +547,16 @@ void SequenceManagerImpl::NotifyDidProcessTask(ExecutingTask* executing_task,
LazyNow* time_after_task) { LazyNow* time_after_task) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"),
"SequenceManagerImpl::NotifyDidProcessTaskObservers"); "SequenceManagerImpl::NotifyDidProcessTaskObservers");
if (!executing_task->task_queue->GetShouldNotifyObservers())
return;
executing_task->task_timing.RecordTaskEnd(time_after_task); bool record_task_timing = ShouldRecordTaskTiming(executing_task->task_queue);
const TaskQueue::TaskTiming& task_timing = executing_task->task_timing; // Record end time ASAP to avoid bias due to the overhead of observers.
if (record_task_timing)
executing_task->task_timing.RecordTaskEnd(time_after_task);
if (!executing_task->task_queue->GetShouldNotifyObservers()) const TaskQueue::TaskTiming& task_timing = executing_task->task_timing;
return;
if (task_timing.has_wall_time() && main_thread_only().nesting_depth == 0) { if (task_timing.has_wall_time() && main_thread_only().nesting_depth == 0) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"),
......
...@@ -313,6 +313,7 @@ class BASE_EXPORT SequenceManagerImpl ...@@ -313,6 +313,7 @@ class BASE_EXPORT SequenceManagerImpl
// Deletes queues marked for deletion and empty queues marked for shutdown. // Deletes queues marked for deletion and empty queues marked for shutdown.
void CleanUpQueues(); void CleanUpQueues();
bool ShouldRecordTaskTiming(const internal::TaskQueueImpl* task_queue);
bool ShouldRecordCPUTimeForTask(); bool ShouldRecordCPUTimeForTask();
// Helper to terminate all scoped trace events to allow starting new ones // Helper to terminate all scoped trace events to allow starting new ones
......
...@@ -104,7 +104,6 @@ class SequenceManagerPerfTest : public testing::TestWithParam<PerfTestType> { ...@@ -104,7 +104,6 @@ class SequenceManagerPerfTest : public testing::TestWithParam<PerfTestType> {
if (manager_) { if (manager_) {
time_domain_ = std::make_unique<PerfTestTimeDomain>(); time_domain_ = std::make_unique<PerfTestTimeDomain>();
manager_->RegisterTimeDomain(time_domain_.get()); manager_->RegisterTimeDomain(time_domain_.get());
manager_->AddTaskTimeObserver(&test_task_time_observer_);
} }
} }
...@@ -336,9 +335,6 @@ class SequenceManagerPerfTest : public testing::TestWithParam<PerfTestType> { ...@@ -336,9 +335,6 @@ class SequenceManagerPerfTest : public testing::TestWithParam<PerfTestType> {
RepeatingClosure delayed_task_closure_; RepeatingClosure delayed_task_closure_;
RepeatingClosure immediate_task_closure_; RepeatingClosure immediate_task_closure_;
// TODO(alexclarke): parameterize so we can measure with and without a
// TaskTimeObserver.
TestTaskTimeObserver test_task_time_observer_;
}; };
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
......
...@@ -961,6 +961,7 @@ bool TaskQueueImpl::HasPendingImmediateWork() { ...@@ -961,6 +961,7 @@ bool TaskQueueImpl::HasPendingImmediateWork() {
void TaskQueueImpl::SetOnTaskStartedHandler( void TaskQueueImpl::SetOnTaskStartedHandler(
TaskQueueImpl::OnTaskStartedHandler handler) { TaskQueueImpl::OnTaskStartedHandler handler) {
DCHECK(should_notify_observers_ || handler.is_null());
main_thread_only().on_task_started_handler = std::move(handler); main_thread_only().on_task_started_handler = std::move(handler);
} }
...@@ -972,6 +973,7 @@ void TaskQueueImpl::OnTaskStarted(const Task& task, ...@@ -972,6 +973,7 @@ void TaskQueueImpl::OnTaskStarted(const Task& task,
void TaskQueueImpl::SetOnTaskCompletedHandler( void TaskQueueImpl::SetOnTaskCompletedHandler(
TaskQueueImpl::OnTaskCompletedHandler handler) { TaskQueueImpl::OnTaskCompletedHandler handler) {
DCHECK(should_notify_observers_ || handler.is_null());
main_thread_only().on_task_completed_handler = std::move(handler); main_thread_only().on_task_completed_handler = std::move(handler);
} }
......
...@@ -115,7 +115,7 @@ MainThreadTaskQueue::MainThreadTaskQueue( ...@@ -115,7 +115,7 @@ MainThreadTaskQueue::MainThreadTaskQueue(
freeze_when_keep_active_(params.freeze_when_keep_active), freeze_when_keep_active_(params.freeze_when_keep_active),
main_thread_scheduler_(main_thread_scheduler), main_thread_scheduler_(main_thread_scheduler),
frame_scheduler_(params.frame_scheduler) { frame_scheduler_(params.frame_scheduler) {
if (GetTaskQueueImpl()) { if (GetTaskQueueImpl() && spec.should_notify_observers) {
// TaskQueueImpl may be null for tests. // TaskQueueImpl may be null for tests.
// TODO(scheduler-dev): Consider mapping directly to // TODO(scheduler-dev): Consider mapping directly to
// MainThreadSchedulerImpl::OnTaskStarted/Completed. At the moment this // MainThreadSchedulerImpl::OnTaskStarted/Completed. At the moment this
......
...@@ -17,7 +17,7 @@ NonMainThreadTaskQueue::NonMainThreadTaskQueue( ...@@ -17,7 +17,7 @@ NonMainThreadTaskQueue::NonMainThreadTaskQueue(
NonMainThreadSchedulerImpl* non_main_thread_scheduler) NonMainThreadSchedulerImpl* non_main_thread_scheduler)
: TaskQueue(std::move(impl), spec), : TaskQueue(std::move(impl), spec),
non_main_thread_scheduler_(non_main_thread_scheduler) { non_main_thread_scheduler_(non_main_thread_scheduler) {
if (GetTaskQueueImpl()) { if (GetTaskQueueImpl() && spec.should_notify_observers) {
// TaskQueueImpl may be null for tests. // TaskQueueImpl may be null for tests.
GetTaskQueueImpl()->SetOnTaskCompletedHandler(base::BindRepeating( GetTaskQueueImpl()->SetOnTaskCompletedHandler(base::BindRepeating(
&NonMainThreadTaskQueue::OnTaskCompleted, base::Unretained(this))); &NonMainThreadTaskQueue::OnTaskCompleted, base::Unretained(this)));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment