blob: 76917abe4aedfa1b8a663e4a34db6b6eb682472b [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PROFILING_SAMPLING_PROFILER_H_
#define FLUTTER_SHELL_PROFILING_SAMPLING_PROFILER_H_
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include "flutter/fml/task_runner.h"
#include "flutter/fml/trace_event.h"
namespace flutter {
/**
* @brief CPU usage stats. `num_threads` is the number of threads owned by the
* process. It is to be noted that this is not per shell, there can be multiple
* shells within the process. `total_cpu_usage` is the percentage (between [0,
* 100]) cpu usage of the application. This is across all the cores, for example
* an application using 100% of all the core will report `total_cpu_usage` as
* `100`, if it has 100% across 2 cores and 0% across the other cores, embedder
* must report `total_cpu_usage` as `50`.
*/
struct CpuUsageInfo {
uint32_t num_threads;
double total_cpu_usage;
};
/**
* @brief Container for the metrics we collect during each run of `Sampler`.
* This currently holds `CpuUsageInfo` but the intent is to expand it to other
* metrics.
*
* @see flutter::Sampler
*/
struct ProfileSample {
std::optional<CpuUsageInfo> cpu_usage;
};
/**
* @brief Sampler is run during `SamplingProfiler::SampleRepeatedly`. Each
* platform should implement its version of a `Sampler` if they decide to
* participate in gathering profiling metrics.
*
* @see flutter::SamplingProfiler::SampleRepeatedly
*/
using Sampler = std::function<ProfileSample(void)>;
/**
* @brief a Sampling Profiler that runs peridically and calls the `Sampler`
* which servers as a value function to gather various profiling metrics as
* represented by `ProfileSample`. These profiling metrics are then posted to
* the observatory timeline.
*
*/
class SamplingProfiler {
public:
/**
* @brief Construct a new Sampling Profiler object
*
* @param thread_label observatory prefix to be set for the profiling task
* runner.
* @param profiler_task_runner the task runner to service sampling requests.
* @param sampler the value function to collect the profiling metrics.
* @param num_samples_per_sec number of times you wish to run the sampler per
* second.
*
* @see fml::TaskRunner
*/
SamplingProfiler(const char* thread_label,
fml::RefPtr<fml::TaskRunner> profiler_task_runner,
Sampler sampler,
int num_samples_per_sec);
/**
* @brief Starts the SamplingProfiler by triggering `SampleRepeatedly`.
*
*/
void Start() const;
private:
const std::string thread_label_;
const fml::RefPtr<fml::TaskRunner> profiler_task_runner_;
const Sampler sampler_;
const uint32_t num_samples_per_sec_;
void SampleRepeatedly(fml::TimeDelta task_delay) const;
/**
* @brief This doesn't update the underlying OS thread name for the thread
* backing `profiler_task_runner_`. Instead, this is just additional metadata
* for the Observatory to show the thread name of the isolate.
*
*/
void UpdateObservatoryThreadName() const;
FML_DISALLOW_COPY_AND_ASSIGN(SamplingProfiler);
};
} // namespace flutter
#endif // FLUTTER_SHELL_PROFILING_SAMPLING_PROFILER_H_