Commit 4d7b7b48 authored by Alexander Timin's avatar Alexander Timin Committed by Commit Bot

[scheduler] Use UKM to sample tasks

Sample 0.01% of the tasks and record task metadata in the ukm.

R=haraken@chromium.org,rkaplow@chromium.org

Change-Id: I83d5d354726422d13f09fa0ab4fa80b2e3f61478
Reviewed-on: https://chromium-review.googlesource.com/1002178Reviewed-by: default avatarRobert Kaplow <rkaplow@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Alexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#549906}
parent ee45ea26
...@@ -820,6 +820,20 @@ void Page::SetPageFrozen(bool frozen) { ...@@ -820,6 +820,20 @@ void Page::SetPageFrozen(bool frozen) {
: PageLifecycleState::kHidden); : PageLifecycleState::kHidden);
} }
ukm::UkmRecorder* Page::GetUkmRecorder() {
Frame* frame = MainFrame();
if (!frame->IsLocalFrame())
return nullptr;
return ToLocalFrame(frame)->GetDocument()->UkmRecorder();
}
int64_t Page::GetUkmSourceId() {
Frame* frame = MainFrame();
if (!frame->IsLocalFrame())
return -1;
return ToLocalFrame(frame)->GetDocument()->UkmSourceID();
}
void Page::SetHasHighMediaEngagement(bool value) { void Page::SetHasHighMediaEngagement(bool value) {
has_high_media_engagement_ = value; has_high_media_engagement_ = value;
} }
......
...@@ -318,6 +318,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>, ...@@ -318,6 +318,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
void ReportIntervention(const String& message) override; void ReportIntervention(const String& message) override;
void RequestBeginMainFrameNotExpected(bool new_state) override; void RequestBeginMainFrameNotExpected(bool new_state) override;
void SetPageFrozen(bool frozen) override; void SetPageFrozen(bool frozen) override;
ukm::UkmRecorder* GetUkmRecorder() override;
int64_t GetUkmSourceId() override;
void SetHasHighMediaEngagement(bool value); void SetHasHighMediaEngagement(bool value);
......
...@@ -154,6 +154,7 @@ blink_platform_sources("scheduler") { ...@@ -154,6 +154,7 @@ blink_platform_sources("scheduler") {
"//base", "//base",
"//cc", "//cc",
"//device/base/synchronization", "//device/base/synchronization",
"//services/metrics/public/cpp:ukm_builders",
"//third_party/blink/renderer/platform:make_platform_generated", "//third_party/blink/renderer/platform:make_platform_generated",
"//third_party/blink/renderer/platform/wtf", "//third_party/blink/renderer/platform/wtf",
] ]
......
...@@ -30,6 +30,7 @@ include_rules = [ ...@@ -30,6 +30,7 @@ include_rules = [
"+base/threading/sequenced_task_runner_handle.h", "+base/threading/sequenced_task_runner_handle.h",
"+base/threading/thread.h", "+base/threading/thread.h",
"+base/threading/thread_checker.h", "+base/threading/thread_checker.h",
"+services/metrics",
] ]
specific_include_rules = { specific_include_rules = {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include <memory> #include <memory>
#include "base/bind.h" #include "base/bind.h"
#include "base/debug/stack_trace.h" #include "base/debug/stack_trace.h"
#include "base/feature_list.h" #include "base/feature_list.h"
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
#include "base/trace_event/trace_event_argument.h" #include "base/trace_event/trace_event_argument.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/public/common/page/launching_process_state.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/renderer_process_type.h" #include "third_party/blink/public/platform/scheduler/renderer_process_type.h"
...@@ -57,6 +59,7 @@ constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed = ...@@ -57,6 +59,7 @@ constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed =
base::TimeDelta::FromSeconds(5); base::TimeDelta::FromSeconds(5);
constexpr base::TimeDelta kQueueingTimeWindowDuration = constexpr base::TimeDelta kQueueingTimeWindowDuration =
base::TimeDelta::FromSeconds(1); base::TimeDelta::FromSeconds(1);
const double kSamplingRateForTaskUkm = 0.0001;
// Field trial name. // Field trial name.
const char kWakeUpThrottlingTrial[] = "RendererSchedulerWakeUpThrottling"; const char kWakeUpThrottlingTrial[] = "RendererSchedulerWakeUpThrottling";
...@@ -519,7 +522,8 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( ...@@ -519,7 +522,8 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
virtual_time_pause_count(0), virtual_time_pause_count(0),
max_virtual_time_task_starvation_count(0), max_virtual_time_task_starvation_count(0),
virtual_time_stopped(false), virtual_time_stopped(false),
nested_runloop(false) {} nested_runloop(false),
uniform_distribution(0.0f, 1.0f) {}
RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() = default; RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() = default;
...@@ -2492,6 +2496,65 @@ void RendererSchedulerImpl::OnTaskCompleted( ...@@ -2492,6 +2496,65 @@ void RendererSchedulerImpl::OnTaskCompleted(
main_thread_only().task_description_for_tracing = base::nullopt; main_thread_only().task_description_for_tracing = base::nullopt;
} }
void RendererSchedulerImpl::RecordTaskUkm(
MainThreadTaskQueue* queue,
const TaskQueue::Task& task,
base::TimeTicks start,
base::TimeTicks end,
base::Optional<base::TimeDelta> thread_time) {
if (!ShouldRecordTaskUkm())
return;
if (queue && queue->GetFrameScheduler()) {
RecordTaskUkmImpl(queue, task, start, end, thread_time,
static_cast<PageSchedulerImpl*>(
queue->GetFrameScheduler()->GetPageScheduler()),
1);
return;
}
for (PageSchedulerImpl* page_scheduler : main_thread_only().page_schedulers) {
RecordTaskUkmImpl(queue, task, start, end, thread_time, page_scheduler,
main_thread_only().page_schedulers.size());
}
}
void RendererSchedulerImpl::RecordTaskUkmImpl(
MainThreadTaskQueue* queue,
const TaskQueue::Task& task,
base::TimeTicks start,
base::TimeTicks end,
base::Optional<base::TimeDelta> thread_time,
PageSchedulerImpl* page_scheduler,
size_t page_schedulers_to_attribute) {
ukm::UkmRecorder* ukm_recorder = page_scheduler->GetUkmRecorder();
// OOPIFs are not supported.
if (!ukm_recorder)
return;
ukm::builders::RendererSchedulerTask builder(
page_scheduler->GetUkmSourceId());
builder.SetPageSchedulers(page_schedulers_to_attribute);
builder.SetRendererBackgrounded(main_thread_only().renderer_backgrounded);
builder.SetRendererHidden(main_thread_only().renderer_hidden);
builder.SetRendererAudible(main_thread_only().is_audio_playing);
builder.SetUseCase(
static_cast<int>(main_thread_only().current_use_case.get()));
builder.SetTaskType(task.task_type());
builder.SetQueueType(static_cast<int>(
queue ? queue->queue_type() : MainThreadTaskQueue::QueueType::kDetached));
builder.SetFrameStatus(static_cast<int>(
GetFrameStatus(queue ? queue->GetFrameScheduler() : nullptr)));
builder.SetTaskDuration((end - start).InMicroseconds());
if (thread_time) {
builder.SetTaskDuration(thread_time->InMicroseconds());
}
builder.Record(ukm_recorder);
}
void RendererSchedulerImpl::OnBeginNestedRunLoop() { void RendererSchedulerImpl::OnBeginNestedRunLoop() {
seqlock_queueing_time_estimator_.seqlock.WriteBegin(); seqlock_queueing_time_estimator_.seqlock.WriteBegin();
seqlock_queueing_time_estimator_.data.OnBeginNestedRunLoop(); seqlock_queueing_time_estimator_.data.OnBeginNestedRunLoop();
...@@ -2624,6 +2687,12 @@ base::WeakPtr<RendererSchedulerImpl> RendererSchedulerImpl::GetWeakPtr() { ...@@ -2624,6 +2687,12 @@ base::WeakPtr<RendererSchedulerImpl> RendererSchedulerImpl::GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
bool RendererSchedulerImpl::ShouldRecordTaskUkm() {
// This function returns true with probability of kSamplingRateForTaskUkm.
return main_thread_only().uniform_distribution(
main_thread_only().random_generator) < kSamplingRateForTaskUkm;
}
// static // static
const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) { const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) {
switch (use_case) { switch (use_case) {
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_SCHEDULER_IMPL_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_SCHEDULER_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_SCHEDULER_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_SCHEDULER_IMPL_H_
#include <random>
#include "base/atomicops.h" #include "base/atomicops.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
...@@ -580,6 +582,25 @@ class PLATFORM_EXPORT RendererSchedulerImpl ...@@ -580,6 +582,25 @@ class PLATFORM_EXPORT RendererSchedulerImpl
// TaskQueueThrottler. // TaskQueueThrottler.
void VirtualTimeResumed(); void VirtualTimeResumed();
bool ShouldRecordTaskUkm();
// Probabilistically record all task metadata for the current task.
// If task belongs to a per-frame queue, this task is attributed to
// a particular Page, otherwise it's attributed to all Pages in the process.
void RecordTaskUkm(MainThreadTaskQueue* queue,
const TaskQueue::Task& task,
base::TimeTicks start,
base::TimeTicks end,
base::Optional<base::TimeDelta> thread_time);
void RecordTaskUkmImpl(MainThreadTaskQueue* queue,
const TaskQueue::Task& task,
base::TimeTicks start,
base::TimeTicks end,
base::Optional<base::TimeDelta> thread_time,
PageSchedulerImpl* page_scheduler,
size_t page_schedulers_to_attribute);
// Indicates that scheduler has been shutdown. // Indicates that scheduler has been shutdown.
// It should be accessed only on the main thread, but couldn't be a member // It should be accessed only on the main thread, but couldn't be a member
// of MainThreadOnly struct because last might be destructed before we // of MainThreadOnly struct because last might be destructed before we
...@@ -722,6 +743,9 @@ class PLATFORM_EXPORT RendererSchedulerImpl ...@@ -722,6 +743,9 @@ class PLATFORM_EXPORT RendererSchedulerImpl
int max_virtual_time_task_starvation_count; int max_virtual_time_task_starvation_count;
bool virtual_time_stopped; bool virtual_time_stopped;
bool nested_runloop; bool nested_runloop;
std::mt19937_64 random_generator;
std::uniform_real_distribution<double> uniform_distribution;
}; };
struct AnyThread { struct AnyThread {
......
...@@ -383,5 +383,13 @@ void PageSchedulerImpl::SetMaxVirtualTimeTaskStarvationCount( ...@@ -383,5 +383,13 @@ void PageSchedulerImpl::SetMaxVirtualTimeTaskStarvationCount(
max_task_starvation_count); max_task_starvation_count);
} }
ukm::UkmRecorder* PageSchedulerImpl::GetUkmRecorder() {
return delegate_->GetUkmRecorder();
}
int64_t PageSchedulerImpl::GetUkmSourceId() {
return delegate_->GetUkmSourceId();
}
} // namespace scheduler } // namespace scheduler
} // namespace blink } // namespace blink
...@@ -91,6 +91,9 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { ...@@ -91,6 +91,9 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
void AsValueInto(base::trace_event::TracedValue* state) const; void AsValueInto(base::trace_event::TracedValue* state) const;
ukm::UkmRecorder* GetUkmRecorder();
int64_t GetUkmSourceId();
base::WeakPtr<PageSchedulerImpl> GetWeakPtr() { base::WeakPtr<PageSchedulerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace ukm {
class UkmRecorder;
}
namespace blink { namespace blink {
class PLATFORM_EXPORT PageScheduler { class PLATFORM_EXPORT PageScheduler {
...@@ -23,6 +27,8 @@ class PLATFORM_EXPORT PageScheduler { ...@@ -23,6 +27,8 @@ class PLATFORM_EXPORT PageScheduler {
virtual void ReportIntervention(const WTF::String& message) = 0; virtual void ReportIntervention(const WTF::String& message) = 0;
virtual void RequestBeginMainFrameNotExpected(bool new_state) = 0; virtual void RequestBeginMainFrameNotExpected(bool new_state) = 0;
virtual void SetPageFrozen(bool frozen) = 0; virtual void SetPageFrozen(bool frozen) = 0;
virtual ukm::UkmRecorder* GetUkmRecorder() = 0;
virtual int64_t GetUkmSourceId() = 0;
}; };
virtual ~PageScheduler() = default; virtual ~PageScheduler() = default;
......
...@@ -2450,6 +2450,73 @@ be describing additional metrics about the same event. ...@@ -2450,6 +2450,73 @@ be describing additional metrics about the same event.
</metric> </metric>
</event> </event>
<event name="RendererSchedulerTask">
<owner>altimin@chromium.org</owner>
<summary>
Sampled task from the renderer main thread. Sample rate is controlled
dynamically. See
blink::scheduler::MainThreadSchedulerImpl::ShouldRecordTaskUkm.
</summary>
<metric name="FrameStatus">
<summary>
Frame status of the frame associated with the context of this task. See
blink::scheduler::FrameStatus for the values of this enum.
</summary>
</metric>
<metric name="PageSchedulers">
<summary>
Number of pages this task should be attributed to. One if there is a hard
attribution, number of pages in the process otherwise.
</summary>
</metric>
<metric name="QueueType">
<summary>
Type of the task queue which this task was posted to. See
blink::scheduler::MainThreadTaskQueue::TaskType for the values of this
enum.
</summary>
</metric>
<metric name="RendererAudible">
<summary>
Whether renderer was playing audio when this task was run. Boolean,
encoded as an integer (0/1).
</summary>
</metric>
<metric name="RendererBackgrounded">
<summary>
Whether renderer was backgrounded when this task was run. Boolean, encoded
as an integer (0/1).
</summary>
</metric>
<metric name="RendererHidden">
<summary>
Whether renderer was hidden when this task was run. Boolean, encoded as an
integer (0/1).
</summary>
</metric>
<metric name="TaskCPUDuration">
<summary>
CPU duration of this task in microseconds.
</summary>
</metric>
<metric name="TaskDuration">
<summary>
Duration of this task in microseconds.
</summary>
</metric>
<metric name="TaskType">
<summary>
blink::TaskType for the current task.
</summary>
</metric>
<metric name="UseCase">
<summary>
MainThreadSchedulerImpl's UseCase when this task was run. See
blink::scheduler::UseCase for the values of this enum.
</summary>
</metric>
</event>
<event name="Pepper.Broker" singular="True"> <event name="Pepper.Broker" singular="True">
<owner>raymes@chromium.org</owner> <owner>raymes@chromium.org</owner>
<summary> <summary>
......
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