Flutter Engine
sampling_profiler.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/shell/profiling/sampling_profiler.h"
6 
7 namespace flutter {
8 
10  const char* thread_label,
11  fml::RefPtr<fml::TaskRunner> profiler_task_runner,
12  Sampler sampler,
13  int num_samples_per_sec)
14  : thread_label_(thread_label),
15  profiler_task_runner_(profiler_task_runner),
16  sampler_(std::move(sampler)),
17  num_samples_per_sec_(num_samples_per_sec) {}
18 
20  if (!profiler_task_runner_) {
21  return;
22  }
23  FML_CHECK(num_samples_per_sec_ > 0)
24  << "number of samples must be a positive integer, got: "
25  << num_samples_per_sec_;
26  double delay_between_samples = 1.0 / num_samples_per_sec_;
27  auto task_delay = fml::TimeDelta::FromSecondsF(delay_between_samples);
28  UpdateObservatoryThreadName();
29  SampleRepeatedly(task_delay);
30 }
31 
32 void SamplingProfiler::SampleRepeatedly(fml::TimeDelta task_delay) const {
33  profiler_task_runner_->PostDelayedTask(
34  [profiler = this, task_delay = task_delay, sampler = sampler_]() {
35  // TODO(kaushikiska): consider buffering these every n seconds to
36  // avoid spamming the trace buffer.
37  const ProfileSample usage = sampler();
38  if (usage.cpu_usage) {
39  const auto& cpu_usage = usage.cpu_usage;
40  std::string total_cpu_usage =
41  std::to_string(cpu_usage->total_cpu_usage);
42  std::string num_threads = std::to_string(cpu_usage->num_threads);
43  TRACE_EVENT_INSTANT2("flutter::profiling", "CpuUsage",
44  "total_cpu_usage", total_cpu_usage.c_str(),
45  "num_threads", num_threads.c_str());
46  }
47  if (usage.memory_usage) {
48  std::string dirty_memory_usage =
49  std::to_string(usage.memory_usage->dirty_memory_usage);
50  std::string owned_shared_memory_usage =
51  std::to_string(usage.memory_usage->owned_shared_memory_usage);
52  TRACE_EVENT_INSTANT2("flutter::profiling", "MemoryUsage",
53  "dirty_memory_usage", dirty_memory_usage.c_str(),
54  "owned_shared_memory_usage",
55  owned_shared_memory_usage.c_str());
56  }
57  if (usage.gpu_usage) {
58  std::string gpu_usage =
59  std::to_string(usage.gpu_usage->percent_usage);
60  TRACE_EVENT_INSTANT1("flutter::profiling", "GpuUsage", "gpu_usage",
61  gpu_usage.c_str());
62  }
63  profiler->SampleRepeatedly(task_delay);
64  },
65  task_delay);
66 }
67 
68 void SamplingProfiler::UpdateObservatoryThreadName() const {
69  FML_CHECK(profiler_task_runner_);
70 
71  profiler_task_runner_->PostTask(
72  [label = thread_label_ + std::string{".profiler"}]() {
73  Dart_SetThreadName(label.c_str());
74  });
75 }
76 
77 } // namespace flutter
SamplingProfiler(const char *thread_label, fml::RefPtr< fml::TaskRunner > profiler_task_runner, Sampler sampler, int num_samples_per_sec)
Construct a new Sampling Profiler object.
static constexpr TimeDelta FromSecondsF(double seconds)
Definition: time_delta.h:53
#define TRACE_EVENT_INSTANT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
Definition: trace_event.h:110
Definition: ref_ptr.h:252
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
void Start() const
Starts the SamplingProfiler by triggering SampleRepeatedly.
Container for the metrics we collect during each run of Sampler. This currently holds CpuUsageInfo an...
#define TRACE_EVENT_INSTANT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:107
std::optional< CpuUsageInfo > cpu_usage
#define FML_CHECK(condition)
Definition: logging.h:68
std::optional< MemoryUsageInfo > memory_usage
virtual void PostDelayedTask(const fml::closure &task, fml::TimeDelta delay)
Definition: task_runner.cc:33
std::function< ProfileSample(void)> Sampler
Sampler is run during SamplingProfiler::SampleRepeatedly. Each platform should implement its version ...
std::optional< GpuUsageInfo > gpu_usage