#include "chrome/common/profiler/thread_profiler_platform_configuration.h"
#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/notreached.h"
#include "base/profiler/process_type.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/rand_util.h"
#include "build/build_config.h"
#include "chrome/common/profiler/process_type.h"
namespace {
class DefaultPlatformConfiguration
: public ThreadProfilerPlatformConfiguration { … };
DefaultPlatformConfiguration::DefaultPlatformConfiguration(
bool browser_test_mode_enabled)
: … { … }
ThreadProfilerPlatformConfiguration::RelativePopulations
DefaultPlatformConfiguration::GetEnableRates(
std::optional<version_info::Channel> release_channel) const { … }
double DefaultPlatformConfiguration::GetChildProcessPerExecutionEnableFraction(
base::ProfilerProcessType process) const { … }
std::optional<base::ProfilerProcessType>
DefaultPlatformConfiguration::ChooseEnabledProcess() const { … }
bool DefaultPlatformConfiguration::IsEnabledForThread(
base::ProfilerProcessType process,
base::ProfilerThreadType thread,
std::optional<version_info::Channel> release_channel) const { … }
bool DefaultPlatformConfiguration::IsSupportedForChannel(
std::optional<version_info::Channel> release_channel) const { … }
#if BUILDFLAG(IS_ANDROID)
class AndroidPlatformConfiguration : public DefaultPlatformConfiguration {
public:
explicit AndroidPlatformConfiguration(
bool browser_test_mode_enabled,
base::RepeatingCallback<bool(double)> is_enabled_on_dev_callback);
RelativePopulations GetEnableRates(
std::optional<version_info::Channel> release_channel) const override;
double GetChildProcessPerExecutionEnableFraction(
base::ProfilerProcessType process) const override;
std::optional<base::ProfilerProcessType> ChooseEnabledProcess()
const override;
bool IsEnabledForThread(
base::ProfilerProcessType process,
base::ProfilerThreadType thread,
std::optional<version_info::Channel> release_channel) const override;
private:
const base::flat_map<base::ProfilerThreadType, bool> thread_enabled_on_dev_;
};
AndroidPlatformConfiguration::AndroidPlatformConfiguration(
bool browser_test_mode_enabled,
base::RepeatingCallback<bool(double)> is_enabled_on_dev_callback)
: DefaultPlatformConfiguration(browser_test_mode_enabled),
thread_enabled_on_dev_(base::MakeFlatMap<base::ProfilerThreadType, bool>(
[]() {
std::vector<base::ProfilerThreadType> threads;
for (int i = 0;
i <= static_cast<int>(base::ProfilerThreadType::kMax); i++) {
threads.push_back(static_cast<base::ProfilerThreadType>(i));
}
return threads;
}(),
{},
[&](base::ProfilerThreadType thread) {
return std::make_pair(thread, is_enabled_on_dev_callback.Run(0.25));
})) {}
ThreadProfilerPlatformConfiguration::RelativePopulations
AndroidPlatformConfiguration::GetEnableRates(
std::optional<version_info::Channel> release_channel) const {
if (!release_channel.has_value() || browser_test_mode_enabled()) {
return RelativePopulations{0, 100, 0};
}
CHECK(*release_channel == version_info::Channel::CANARY ||
*release_channel == version_info::Channel::DEV ||
*release_channel == version_info::Channel::BETA);
if (*release_channel == version_info::Channel::BETA) {
return RelativePopulations{25, 0, 75};
}
return RelativePopulations{0, 1, 99};
}
double AndroidPlatformConfiguration::GetChildProcessPerExecutionEnableFraction(
base::ProfilerProcessType process) const {
return 1.0;
}
std::optional<base::ProfilerProcessType>
AndroidPlatformConfiguration::ChooseEnabledProcess() const {
const struct {
base::ProfilerProcessType process;
int weight;
} process_enable_weights[] = {
{base::ProfilerProcessType::kBrowser, 50},
{base::ProfilerProcessType::kGpu, 40},
{base::ProfilerProcessType::kRenderer, 10},
};
int total_weight = 0;
for (const auto& process_enable_weight : process_enable_weights) {
total_weight += process_enable_weight.weight;
}
DCHECK_EQ(100, total_weight);
int chosen = base::RandInt(0, total_weight - 1);
int cumulative_weight = 0;
for (const auto& process_enable_weight : process_enable_weights) {
if (chosen >= cumulative_weight &&
chosen < cumulative_weight + process_enable_weight.weight) {
return process_enable_weight.process;
}
cumulative_weight += process_enable_weight.weight;
}
NOTREACHED_IN_MIGRATION();
return std::nullopt;
}
bool AndroidPlatformConfiguration::IsEnabledForThread(
base::ProfilerProcessType process,
base::ProfilerThreadType thread,
std::optional<version_info::Channel> release_channel) const {
#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARM64)
if (!(process == base::ProfilerProcessType::kBrowser &&
thread == base::ProfilerThreadType::kMain)) {
return false;
}
#endif
if (!release_channel.has_value() || browser_test_mode_enabled()) {
return true;
}
switch (*release_channel) {
case version_info::Channel::BETA:
case version_info::Channel::DEV: {
const auto entry = thread_enabled_on_dev_.find(thread);
CHECK(entry != thread_enabled_on_dev_.end());
return entry->second;
}
case version_info::Channel::CANARY:
return true;
default:
return false;
}
}
#endif
}
std::unique_ptr<ThreadProfilerPlatformConfiguration>
ThreadProfilerPlatformConfiguration::Create(
bool browser_test_mode_enabled,
base::RepeatingCallback<bool(double)> is_enabled_on_dev_callback) { … }
bool ThreadProfilerPlatformConfiguration::IsSupported(
std::optional<version_info::Channel> release_channel) const { … }
bool ThreadProfilerPlatformConfiguration::IsEnabled(
double enabled_probability) { … }