Commit 017e49f3 authored by Siddhartha's avatar Siddhartha Committed by Commit Bot

Enable tracing sampler profiler for IO thread

Stores the profiler in TLS and registers trace log observer for the
thread. If tracing is enabled then IO thread will be profiled.
We observe a lot of janks on IO thread and stack traces will be useful
to debug these traces.

Change-Id: I84f5c5f9c15d957ac2ee807289ddfab24731ef6d
Reviewed-on: https://chromium-review.googlesource.com/c/1330748
Commit-Queue: ssid <ssid@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#608549}
parent d31eecb7
......@@ -562,8 +562,8 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) {
base::Bind(&IsTraceEventArgsWhitelisted));
// Setup tracing sampler profiler as early as possible at startup if needed.
tracing_sampler_profiler_ = std::make_unique<tracing::TracingSamplerProfiler>(
base::PlatformThread::CurrentId());
tracing_sampler_profiler_ =
tracing::TracingSamplerProfiler::CreateOnMainThread();
#if defined(OS_WIN) && !defined(CHROME_MULTIPLE_DLL_BROWSER)
v8_crashpad_support::SetUp();
......
......@@ -151,6 +151,7 @@
#include "components/rappor/rappor_service_impl.h"
#include "components/signin/core/browser/account_consistency_method.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include "components/tracing/common/tracing_sampler_profiler.h"
#include "components/tracing/common/tracing_switches.h"
#include "components/translate/core/browser/translate_download_manager.h"
#include "components/variations/field_trial_config/field_trial_util.h"
......@@ -1201,6 +1202,13 @@ void ChromeBrowserMainParts::PostCreateThreads() {
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ThreadProfiler::StartOnChildThread,
metrics::CallStackProfileParams::IO_THREAD));
// Sampling multiple threads might cause overhead on Android and we don't want
// to enable it unless the data is needed.
#if !defined(OS_ANDROID)
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&tracing::TracingSamplerProfiler::CreateOnChildThread));
#endif
}
void ChromeBrowserMainParts::ServiceManagerConnectionStarted(
......
......@@ -7,9 +7,11 @@
#include <cinttypes>
#include "base/format_macros.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
......@@ -118,6 +120,26 @@ class TracingProfileBuilder
} // namespace
// static
std::unique_ptr<TracingSamplerProfiler>
TracingSamplerProfiler::CreateOnMainThread() {
return base::WrapUnique(
new TracingSamplerProfiler(base::PlatformThread::CurrentId()));
}
// static
void TracingSamplerProfiler::CreateOnChildThread() {
using ProfilerSlot =
base::SequenceLocalStorageSlot<std::unique_ptr<TracingSamplerProfiler>>;
static base::NoDestructor<ProfilerSlot> slot;
if (!slot.get()->Get()) {
slot.get()->Set(base::WrapUnique(
new TracingSamplerProfiler(base::PlatformThread::CurrentId())));
}
TracingSamplerProfiler* profiler = slot.get()->Get().get();
profiler->OnMessageLoopStarted();
}
TracingSamplerProfiler::TracingSamplerProfiler(
base::PlatformThreadId sampled_thread_id)
: sampled_thread_id_(sampled_thread_id), weak_ptr_factory_(this) {
......@@ -136,6 +158,12 @@ TracingSamplerProfiler::~TracingSamplerProfiler() {
this);
}
void TracingSamplerProfiler::OnMessageLoopStarted() {
base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
weak_ptr_factory_.GetWeakPtr());
OnTraceLogEnabled();
}
void TracingSamplerProfiler::OnTraceLogEnabled() {
// Ensure there was not an instance of the profiler already running.
if (profiler_.get())
......@@ -178,10 +206,4 @@ void TracingSamplerProfiler::OnTraceLogDisabled() {
profiler_.reset();
}
void TracingSamplerProfiler::OnMessageLoopStarted() {
base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
weak_ptr_factory_.GetWeakPtr());
OnTraceLogEnabled();
}
} // namespace tracing
......@@ -24,16 +24,29 @@ namespace tracing {
class TRACING_EXPORT TracingSamplerProfiler
: public base::trace_event::TraceLog::AsyncEnabledStateObserver {
public:
TracingSamplerProfiler(base::PlatformThreadId sampled_thread_id);
// Creates sampling profiler on main thread. Since the message loop might not
// be setup when creating this profiler, the client must call
// OnMessageLoopStarted() when setup.
static std::unique_ptr<TracingSamplerProfiler> CreateOnMainThread();
// Sets up tracing sampling profiler on a child thread. The profiler will be
// stored in SequencedLocalStorageSlot and will be destroyed with the thread
// task runner.
static void CreateOnChildThread();
~TracingSamplerProfiler() override;
// Notify the profiler that the message loop for current thread is started.
// Only required for main thread.
void OnMessageLoopStarted();
// trace_event::TraceLog::EnabledStateObserver implementation:
void OnTraceLogEnabled() override;
void OnTraceLogDisabled() override;
void OnMessageLoopStarted();
private:
explicit TracingSamplerProfiler(base::PlatformThreadId sampled_thread_id);
const base::PlatformThreadId sampled_thread_id_;
std::unique_ptr<base::StackSamplingProfiler> profiler_;
......
......@@ -10,6 +10,7 @@
#include "base/profiler/stack_sampling_profiler.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/trace_event/trace_buffer.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
......@@ -128,8 +129,8 @@ class TracingSampleProfilerTest : public testing::Test {
} // namespace
TEST_F(TracingSampleProfilerTest, OnSampleCompleted) {
TracingSamplerProfiler profiler(base::PlatformThread::CurrentId());
profiler.OnMessageLoopStarted();
auto profiler = TracingSamplerProfiler::CreateOnMainThread();
profiler->OnMessageLoopStarted();
BeginTrace();
base::RunLoop().RunUntilIdle();
WaitForEvents();
......@@ -143,8 +144,8 @@ TEST_F(TracingSampleProfilerTest, OnSampleCompleted) {
TEST_F(TracingSampleProfilerTest, JoinRunningTracing) {
BeginTrace();
TracingSamplerProfiler profiler(base::PlatformThread::CurrentId());
profiler.OnMessageLoopStarted();
auto profiler = TracingSamplerProfiler::CreateOnMainThread();
profiler->OnMessageLoopStarted();
base::RunLoop().RunUntilIdle();
WaitForEvents();
EndTracing();
......@@ -155,4 +156,19 @@ TEST_F(TracingSampleProfilerTest, JoinRunningTracing) {
EXPECT_EQ(events_received_count(), 0U);
}
TEST_F(TracingSampleProfilerTest, SamplingChildThread) {
base::Thread sampled_thread("sampling_profiler_test");
sampled_thread.Start();
sampled_thread.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&TracingSamplerProfiler::CreateOnChildThread));
BeginTrace();
base::RunLoop().RunUntilIdle();
WaitForEvents();
EndTracing();
if (IsStackUnwindingSupported())
EXPECT_GT(events_received_count(), 0U);
else
EXPECT_EQ(events_received_count(), 0U);
}
} // namespace tracing
......@@ -338,9 +338,8 @@ int GpuMain(const MainFunctionParams& parameters) {
gpu_process.set_main_thread(child_thread);
// Setup tracing sampler profiler as early as possible.
auto tracing_sampler_profiler =
std::make_unique<tracing::TracingSamplerProfiler>(
base::PlatformThread::CurrentId());
std::unique_ptr<tracing::TracingSamplerProfiler> tracing_sampler_profiler =
tracing::TracingSamplerProfiler::CreateOnMainThread();
tracing_sampler_profiler->OnMessageLoopStarted();
#if defined(OS_ANDROID)
......
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