Commit 36155f5b authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

[Sampling profiler] Support per-profiler per-thread configuration

Implements the infrastructure to allow different platforms to
selectively enable the profiler on different threads. Retains the
enabling on all supported threads in the default configuration and
sets the state to disabled on all supported thread for Android,
pending launch on that platform.

Bug: 1129939
Change-Id: Iaec50b3aca4d3d7e2a75aa2015a09da53bfb80b0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2431456
Commit-Queue: Mike Wittman <wittman@chromium.org>
Reviewed-by: default avatarEtienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812392}
parent a2d219e6
...@@ -276,8 +276,10 @@ void ThreadProfiler::SetMainThreadTaskRunner( ...@@ -276,8 +276,10 @@ void ThreadProfiler::SetMainThreadTaskRunner(
void ThreadProfiler::SetAuxUnwinderFactory( void ThreadProfiler::SetAuxUnwinderFactory(
const base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>& factory) { const base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>& factory) {
if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) if (!ThreadProfilerConfiguration::Get()
->IsProfilerEnabledForCurrentProcessAndThread(thread_)) {
return; return;
}
aux_unwinder_factory_ = factory; aux_unwinder_factory_ = factory;
startup_profiler_->AddAuxUnwinder(aux_unwinder_factory_.Run()); startup_profiler_->AddAuxUnwinder(aux_unwinder_factory_.Run());
...@@ -293,8 +295,10 @@ void ThreadProfiler::StartOnChildThread(CallStackProfileParams::Thread thread) { ...@@ -293,8 +295,10 @@ void ThreadProfiler::StartOnChildThread(CallStackProfileParams::Thread thread) {
base::SequenceLocalStorageSlot<std::unique_ptr<ThreadProfiler>>> base::SequenceLocalStorageSlot<std::unique_ptr<ThreadProfiler>>>
child_thread_profiler_sequence_local_storage; child_thread_profiler_sequence_local_storage;
if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) if (!ThreadProfilerConfiguration::Get()
->IsProfilerEnabledForCurrentProcessAndThread(thread)) {
return; return;
}
child_thread_profiler_sequence_local_storage->emplace( child_thread_profiler_sequence_local_storage->emplace(
new ThreadProfiler(thread, base::ThreadTaskRunnerHandle::Get())); new ThreadProfiler(thread, base::ThreadTaskRunnerHandle::Get()));
...@@ -346,8 +350,10 @@ ThreadProfiler::ThreadProfiler( ...@@ -346,8 +350,10 @@ ThreadProfiler::ThreadProfiler(
owning_thread_task_runner_(owning_thread_task_runner), owning_thread_task_runner_(owning_thread_task_runner),
work_id_recorder_(std::make_unique<WorkIdRecorder>( work_id_recorder_(std::make_unique<WorkIdRecorder>(
base::WorkIdProvider::GetForCurrentThread())) { base::WorkIdProvider::GetForCurrentThread())) {
if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) if (!ThreadProfilerConfiguration::Get()
->IsProfilerEnabledForCurrentProcessAndThread(thread_)) {
return; return;
}
const base::StackSamplingProfiler::SamplingParams sampling_params = const base::StackSamplingProfiler::SamplingParams sampling_params =
ThreadProfilerConfiguration::Get()->GetSamplingParams(); ThreadProfilerConfiguration::Get()->GetSamplingParams();
...@@ -390,8 +396,10 @@ void ThreadProfiler::OnPeriodicCollectionCompleted( ...@@ -390,8 +396,10 @@ void ThreadProfiler::OnPeriodicCollectionCompleted(
void ThreadProfiler::SetMainThreadTaskRunnerImpl( void ThreadProfiler::SetMainThreadTaskRunnerImpl(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) { scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
if (!ThreadProfilerConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) if (!ThreadProfilerConfiguration::Get()
->IsProfilerEnabledForCurrentProcessAndThread(thread_)) {
return; return;
}
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
......
...@@ -73,6 +73,12 @@ bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const { ...@@ -73,6 +73,12 @@ bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcess() const {
switches::kStartStackProfiler); switches::kStartStackProfiler);
} }
bool ThreadProfilerConfiguration::IsProfilerEnabledForCurrentProcessAndThread(
metrics::CallStackProfileParams::Thread thread) const {
return IsProfilerEnabledForCurrentProcess() &&
platform_configuration_->IsEnabledForThread(current_process_, thread);
}
bool ThreadProfilerConfiguration::GetSyntheticFieldTrial( bool ThreadProfilerConfiguration::GetSyntheticFieldTrial(
std::string* trial_name, std::string* trial_name,
std::string* group_name) const { std::string* group_name) const {
......
...@@ -30,9 +30,13 @@ class ThreadProfilerConfiguration { ...@@ -30,9 +30,13 @@ class ThreadProfilerConfiguration {
// Get the stack sampling params to use. // Get the stack sampling params to use.
base::StackSamplingProfiler::SamplingParams GetSamplingParams() const; base::StackSamplingProfiler::SamplingParams GetSamplingParams() const;
// Returns true if the profiler should be started for the current process. // True if the profiler is enabled for any thread in the current process.
bool IsProfilerEnabledForCurrentProcess() const; bool IsProfilerEnabledForCurrentProcess() const;
// True if the profiler should be started for |thread| in the current process.
bool IsProfilerEnabledForCurrentProcessAndThread(
metrics::CallStackProfileParams::Thread thread) const;
// Get the synthetic field trial configuration. Returns true if a synthetic // Get the synthetic field trial configuration. Returns true if a synthetic
// field trial should be registered. This should only be called from the // field trial should be registered. This should only be called from the
// browser process. When run at startup, the profiler must use a synthetic // browser process. When run at startup, the profiler must use a synthetic
......
...@@ -34,6 +34,10 @@ class DefaultPlatformConfiguration ...@@ -34,6 +34,10 @@ class DefaultPlatformConfiguration
double GetChildProcessEnableFraction( double GetChildProcessEnableFraction(
metrics::CallStackProfileParams::Process process) const override; metrics::CallStackProfileParams::Process process) const override;
bool IsEnabledForThread(
metrics::CallStackProfileParams::Process process,
metrics::CallStackProfileParams::Thread thread) const override;
protected: protected:
bool IsSupportedForChannel(bool is_chrome_branded, bool IsSupportedForChannel(bool is_chrome_branded,
version_info::Channel channel) const override; version_info::Channel channel) const override;
...@@ -97,6 +101,13 @@ double DefaultPlatformConfiguration::GetChildProcessEnableFraction( ...@@ -97,6 +101,13 @@ double DefaultPlatformConfiguration::GetChildProcessEnableFraction(
} }
} }
bool DefaultPlatformConfiguration::IsEnabledForThread(
metrics::CallStackProfileParams::Process process,
metrics::CallStackProfileParams::Thread thread) const {
// Enable for all supported threads.
return true;
}
bool DefaultPlatformConfiguration::IsSupportedForChannel( bool DefaultPlatformConfiguration::IsSupportedForChannel(
bool is_chrome_branded, bool is_chrome_branded,
version_info::Channel channel) const { version_info::Channel channel) const {
...@@ -129,6 +140,10 @@ class AndroidPlatformConfiguration : public DefaultPlatformConfiguration { ...@@ -129,6 +140,10 @@ class AndroidPlatformConfiguration : public DefaultPlatformConfiguration {
double GetChildProcessEnableFraction( double GetChildProcessEnableFraction(
metrics::CallStackProfileParams::Process process) const override; metrics::CallStackProfileParams::Process process) const override;
bool IsEnabledForThread(
metrics::CallStackProfileParams::Process process,
metrics::CallStackProfileParams::Thread thread) const override;
protected: protected:
bool IsSupportedForChannel(bool is_chrome_branded, bool IsSupportedForChannel(bool is_chrome_branded,
version_info::Channel channel) const override; version_info::Channel channel) const override;
...@@ -190,6 +205,14 @@ double AndroidPlatformConfiguration::GetChildProcessEnableFraction( ...@@ -190,6 +205,14 @@ double AndroidPlatformConfiguration::GetChildProcessEnableFraction(
return 0.0; return 0.0;
} }
bool AndroidPlatformConfiguration::IsEnabledForThread(
metrics::CallStackProfileParams::Process process,
metrics::CallStackProfileParams::Thread thread) const {
// Disable for all supported threads pending launch. Enable only for browser
// tests.
return browser_test_mode_enabled();
}
bool AndroidPlatformConfiguration::IsSupportedForChannel( bool AndroidPlatformConfiguration::IsSupportedForChannel(
bool is_chrome_branded, bool is_chrome_branded,
version_info::Channel channel) const { version_info::Channel channel) const {
......
...@@ -81,6 +81,11 @@ class ThreadProfilerPlatformConfiguration { ...@@ -81,6 +81,11 @@ class ThreadProfilerPlatformConfiguration {
virtual double GetChildProcessEnableFraction( virtual double GetChildProcessEnableFraction(
metrics::CallStackProfileParams::Process process) const = 0; metrics::CallStackProfileParams::Process process) const = 0;
// Returns whether the profiler is enabled for |thread| in |process|.
virtual bool IsEnabledForThread(
metrics::CallStackProfileParams::Process process,
metrics::CallStackProfileParams::Thread thread) const = 0;
protected: protected:
// True if the profiler is to be run for the channel/chrome branding on the // True if the profiler is to be run for the channel/chrome branding on the
// platform. Does not need to check whether the StackSamplingProfiler is // platform. Does not need to check whether the StackSamplingProfiler is
......
...@@ -204,3 +204,55 @@ MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest, ...@@ -204,3 +204,55 @@ MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
metrics::CallStackProfileParams::UNKNOWN_PROCESS)); metrics::CallStackProfileParams::UNKNOWN_PROCESS));
#endif #endif
} }
MAYBE_PLATFORM_CONFIG_TEST_F(ThreadProfilerPlatformConfigurationTest,
IsEnabledForThread) {
#if defined(OS_ANDROID)
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::BROWSER_PROCESS,
metrics::CallStackProfileParams::MAIN_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::BROWSER_PROCESS,
metrics::CallStackProfileParams::IO_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::GPU_PROCESS,
metrics::CallStackProfileParams::MAIN_THREAD));
EXPECT_FALSE(
config()->IsEnabledForThread(metrics::CallStackProfileParams::GPU_PROCESS,
metrics::CallStackProfileParams::IO_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::GPU_PROCESS,
metrics::CallStackProfileParams::COMPOSITOR_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::RENDERER_PROCESS,
metrics::CallStackProfileParams::MAIN_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::RENDERER_PROCESS,
metrics::CallStackProfileParams::IO_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::RENDERER_PROCESS,
metrics::CallStackProfileParams::COMPOSITOR_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::RENDERER_PROCESS,
metrics::CallStackProfileParams::SERVICE_WORKER_THREAD));
EXPECT_FALSE(config()->IsEnabledForThread(
metrics::CallStackProfileParams::NETWORK_SERVICE_PROCESS,
metrics::CallStackProfileParams::IO_THREAD));
#else
// Profiling should be enabled without restriction across all threads. Not all
// these combinations actually make sense or are implemented in the code, but
// iterating over all combinations is the simplest way to test.
for (int i = 0; i <= metrics::CallStackProfileParams::MAX_PROCESS; ++i) {
const auto process =
static_cast<metrics::CallStackProfileParams::Process>(i);
for (int j = 0; j <= metrics::CallStackProfileParams::MAX_THREAD; ++j) {
const auto thread =
static_cast<metrics::CallStackProfileParams::Thread>(j);
EXPECT_TRUE(config()->IsEnabledForThread(process, thread));
}
}
#endif
}
...@@ -23,6 +23,8 @@ struct CallStackProfileParams { ...@@ -23,6 +23,8 @@ struct CallStackProfileParams {
PPAPI_PLUGIN_PROCESS, PPAPI_PLUGIN_PROCESS,
PPAPI_BROKER_PROCESS, PPAPI_BROKER_PROCESS,
NETWORK_SERVICE_PROCESS, NETWORK_SERVICE_PROCESS,
MAX_PROCESS = NETWORK_SERVICE_PROCESS,
}; };
// The thread from which the collection occurred. // The thread from which the collection occurred.
...@@ -39,6 +41,8 @@ struct CallStackProfileParams { ...@@ -39,6 +41,8 @@ struct CallStackProfileParams {
// Service worker thread. // Service worker thread.
SERVICE_WORKER_THREAD, SERVICE_WORKER_THREAD,
MAX_THREAD = SERVICE_WORKER_THREAD,
}; };
// The event that triggered the profile collection. // The event that triggered the profile collection.
......
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