Commit eb9eb9b1 authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

[Sampling profiler] Introduce ThreadToken representation

The stack sampling implementations for Linux and Android platforms require
the pthread_t type to obtain the stack base address, in addition to the
PlatformThreadId. This change introduces a minimal ThreadToken abstraction
that encapsulates the necessary thread state across platforms.

TBR=gab@chromium.org

Bug: 988579
Change-Id: Ie5d70709ddae362ca414dc5a635e456c8bd9f8ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1860151Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Reviewed-by: default avatarssid <ssid@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Reviewed-by: default avatarCharlie Andrews <charliea@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709061}
parent 42f3f2e6
...@@ -616,6 +616,8 @@ jumbo_component("base") { ...@@ -616,6 +616,8 @@ jumbo_component("base") {
"profiler/register_context.h", "profiler/register_context.h",
"profiler/sample_metadata.cc", "profiler/sample_metadata.cc",
"profiler/sample_metadata.h", "profiler/sample_metadata.h",
"profiler/sampling_profiler_thread_token.cc",
"profiler/sampling_profiler_thread_token.h",
"profiler/stack_buffer.cc", "profiler/stack_buffer.cc",
"profiler/stack_buffer.h", "profiler/stack_buffer.h",
"profiler/stack_copier.cc", "profiler/stack_copier.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/profiler/sampling_profiler_thread_token.h"
namespace base {
SamplingProfilerThreadToken GetSamplingProfilerCurrentThreadToken() {
#if defined(OS_ANDROID) || defined(OS_LINUX)
return {PlatformThread::CurrentId(), pthread_self()};
#else
return {PlatformThread::CurrentId()};
#endif
}
} // namespace base
// Copyright 2019 The Chromium 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 BASE_PROFILER_SAMPLING_PROFILER_THREAD_TOKEN_H_
#define BASE_PROFILER_SAMPLING_PROFILER_THREAD_TOKEN_H_
#include "base/base_export.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#if defined(OS_ANDROID) || defined(OS_LINUX)
#include <pthread.h>
#endif
namespace base {
// SamplingProfilerThreadToken represents the thread identifier(s) required by
// sampling profiler to operate on a thread. PlatformThreadId is needed for all
// platforms, while non-Mac POSIX also requires a pthread_t to pass to pthread
// functions used to obtain the stack base address.
struct SamplingProfilerThreadToken {
PlatformThreadId id;
#if defined(OS_ANDROID) || defined(OS_LINUX)
pthread_t pthread_id;
#endif
};
BASE_EXPORT SamplingProfilerThreadToken GetSamplingProfilerCurrentThreadToken();
} // namespace base
#endif // BASE_PROFILER_SAMPLING_PROFILER_THREAD_TOKEN_H_
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/base_export.h" #include "base/base_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
namespace base { namespace base {
...@@ -26,10 +27,11 @@ class BASE_EXPORT StackSampler { ...@@ -26,10 +27,11 @@ class BASE_EXPORT StackSampler {
public: public:
virtual ~StackSampler(); virtual ~StackSampler();
// Creates a stack sampler that records samples for thread with |thread_id|. // Creates a stack sampler that records samples for thread with
// Returns null if this platform does not support stack sampling. // |thread_token|. Returns null if this platform does not support stack
// sampling.
static std::unique_ptr<StackSampler> Create( static std::unique_ptr<StackSampler> Create(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate); StackSamplerTestDelegate* test_delegate);
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
namespace base { namespace base {
std::unique_ptr<StackSampler> StackSampler::Create( std::unique_ptr<StackSampler> StackSampler::Create(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate) { StackSamplerTestDelegate* test_delegate) {
return std::make_unique<StackSamplerImpl>( return std::make_unique<StackSamplerImpl>(
std::make_unique<StackCopierSignal>( std::make_unique<StackCopierSignal>(
std::make_unique<ThreadDelegatePosix>(thread_id)), std::make_unique<ThreadDelegatePosix>(thread_token)),
std::make_unique<NativeUnwinderAndroid>(), module_cache, test_delegate); std::make_unique<NativeUnwinderAndroid>(), module_cache, test_delegate);
} }
......
...@@ -11,7 +11,7 @@ namespace base { ...@@ -11,7 +11,7 @@ namespace base {
// static // static
std::unique_ptr<StackSampler> StackSampler::Create( std::unique_ptr<StackSampler> StackSampler::Create(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate) { StackSamplerTestDelegate* test_delegate) {
return nullptr; return nullptr;
......
...@@ -13,12 +13,12 @@ namespace base { ...@@ -13,12 +13,12 @@ namespace base {
// static // static
std::unique_ptr<StackSampler> StackSampler::Create( std::unique_ptr<StackSampler> StackSampler::Create(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate) { StackSamplerTestDelegate* test_delegate) {
return std::make_unique<StackSamplerImpl>( return std::make_unique<StackSamplerImpl>(
std::make_unique<StackCopierSuspend>( std::make_unique<StackCopierSuspend>(
std::make_unique<SuspendableThreadDelegateMac>(thread_id)), std::make_unique<SuspendableThreadDelegateMac>(thread_token)),
std::make_unique<NativeUnwinderMac>(module_cache), module_cache, std::make_unique<NativeUnwinderMac>(module_cache), module_cache,
test_delegate); test_delegate);
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
namespace base { namespace base {
std::unique_ptr<StackSampler> StackSampler::Create( std::unique_ptr<StackSampler> StackSampler::Create(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate) { StackSamplerTestDelegate* test_delegate) {
return nullptr; return nullptr;
......
...@@ -14,13 +14,13 @@ namespace base { ...@@ -14,13 +14,13 @@ namespace base {
// static // static
std::unique_ptr<StackSampler> StackSampler::Create( std::unique_ptr<StackSampler> StackSampler::Create(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* test_delegate) { StackSamplerTestDelegate* test_delegate) {
#if defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM64) #if defined(ARCH_CPU_X86_64) || defined(ARCH_CPU_ARM64)
return std::make_unique<StackSamplerImpl>( return std::make_unique<StackSamplerImpl>(
std::make_unique<StackCopierSuspend>( std::make_unique<StackCopierSuspend>(
std::make_unique<SuspendableThreadDelegateWin>(thread_id)), std::make_unique<SuspendableThreadDelegateWin>(thread_token)),
std::make_unique<NativeUnwinderWin>(), module_cache, test_delegate); std::make_unique<NativeUnwinderWin>(), module_cache, test_delegate);
#else #else
return nullptr; return nullptr;
......
...@@ -79,13 +79,11 @@ class StackSamplingProfiler::SamplingThread : public Thread { ...@@ -79,13 +79,11 @@ class StackSamplingProfiler::SamplingThread : public Thread {
}; };
struct CollectionContext { struct CollectionContext {
CollectionContext(PlatformThreadId target, CollectionContext(const SamplingParams& params,
const SamplingParams& params,
WaitableEvent* finished, WaitableEvent* finished,
std::unique_ptr<StackSampler> sampler, std::unique_ptr<StackSampler> sampler,
std::unique_ptr<ProfileBuilder> profile_builder) std::unique_ptr<ProfileBuilder> profile_builder)
: collection_id(next_collection_id.GetNext()), : collection_id(next_collection_id.GetNext()),
target(target),
params(params), params(params),
finished(finished), finished(finished),
sampler(std::move(sampler)), sampler(std::move(sampler)),
...@@ -96,7 +94,6 @@ class StackSamplingProfiler::SamplingThread : public Thread { ...@@ -96,7 +94,6 @@ class StackSamplingProfiler::SamplingThread : public Thread {
// collection to outside interests. // collection to outside interests.
const int collection_id; const int collection_id;
const PlatformThreadId target; // ID of The thread being sampled.
const SamplingParams params; // Information about how to sample. const SamplingParams params; // Information about how to sample.
WaitableEvent* const finished; // Signaled when all sampling complete. WaitableEvent* const finished; // Signaled when all sampling complete.
...@@ -649,23 +646,23 @@ void StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown( ...@@ -649,23 +646,23 @@ void StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(
} }
StackSamplingProfiler::StackSamplingProfiler( StackSamplingProfiler::StackSamplingProfiler(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
const SamplingParams& params, const SamplingParams& params,
std::unique_ptr<ProfileBuilder> profile_builder, std::unique_ptr<ProfileBuilder> profile_builder,
StackSamplerTestDelegate* test_delegate) StackSamplerTestDelegate* test_delegate)
: StackSamplingProfiler(thread_id, : StackSamplingProfiler(thread_token,
params, params,
std::move(profile_builder), std::move(profile_builder),
nullptr, nullptr,
test_delegate) {} test_delegate) {}
StackSamplingProfiler::StackSamplingProfiler( StackSamplingProfiler::StackSamplingProfiler(
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
const SamplingParams& params, const SamplingParams& params,
std::unique_ptr<ProfileBuilder> profile_builder, std::unique_ptr<ProfileBuilder> profile_builder,
std::unique_ptr<StackSampler> sampler, std::unique_ptr<StackSampler> sampler,
StackSamplerTestDelegate* test_delegate) StackSamplerTestDelegate* test_delegate)
: thread_id_(thread_id), : thread_token_(thread_token),
params_(params), params_(params),
profile_builder_(std::move(profile_builder)), profile_builder_(std::move(profile_builder)),
sampler_(std::move(sampler)), sampler_(std::move(sampler)),
...@@ -712,7 +709,7 @@ void StackSamplingProfiler::Start() { ...@@ -712,7 +709,7 @@ void StackSamplingProfiler::Start() {
if (!sampler_) if (!sampler_)
sampler_ = StackSampler::Create( sampler_ = StackSampler::Create(
thread_id_, profile_builder_->GetModuleCache(), test_delegate_); thread_token_, profile_builder_->GetModuleCache(), test_delegate_);
if (!sampler_) if (!sampler_)
return; return;
...@@ -735,7 +732,7 @@ void StackSamplingProfiler::Start() { ...@@ -735,7 +732,7 @@ void StackSamplingProfiler::Start() {
DCHECK_EQ(kNullProfilerId, profiler_id_); DCHECK_EQ(kNullProfilerId, profiler_id_);
profiler_id_ = SamplingThread::GetInstance()->Add( profiler_id_ = SamplingThread::GetInstance()->Add(
std::make_unique<SamplingThread::CollectionContext>( std::make_unique<SamplingThread::CollectionContext>(
thread_id_, params_, &profiling_inactive_, std::move(sampler_), params_, &profiling_inactive_, std::move(sampler_),
std::move(profile_builder_))); std::move(profile_builder_)));
DCHECK_NE(kNullProfilerId, profiler_id_); DCHECK_NE(kNullProfilerId, profiler_id_);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/base_export.h" #include "base/base_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/profiler/profile_builder.h" #include "base/profiler/profile_builder.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -86,14 +87,14 @@ class BASE_EXPORT StackSamplingProfiler { ...@@ -86,14 +87,14 @@ class BASE_EXPORT StackSamplingProfiler {
// //
// The caller must ensure that this object gets destroyed before the thread // The caller must ensure that this object gets destroyed before the thread
// exits. // exits.
StackSamplingProfiler(PlatformThreadId thread_id, StackSamplingProfiler(SamplingProfilerThreadToken thread_token,
const SamplingParams& params, const SamplingParams& params,
std::unique_ptr<ProfileBuilder> profile_builder, std::unique_ptr<ProfileBuilder> profile_builder,
StackSamplerTestDelegate* test_delegate = nullptr); StackSamplerTestDelegate* test_delegate = nullptr);
// Same as above function, with custom |sampler| implementation. The sampler // Same as above function, with custom |sampler| implementation. The sampler
// on Android is not implemented in base. // on Android is not implemented in base.
StackSamplingProfiler(PlatformThreadId thread_id, StackSamplingProfiler(SamplingProfilerThreadToken thread_token,
const SamplingParams& params, const SamplingParams& params,
std::unique_ptr<ProfileBuilder> profile_builder, std::unique_ptr<ProfileBuilder> profile_builder,
std::unique_ptr<StackSampler> sampler, std::unique_ptr<StackSampler> sampler,
...@@ -157,7 +158,7 @@ class BASE_EXPORT StackSamplingProfiler { ...@@ -157,7 +158,7 @@ class BASE_EXPORT StackSamplingProfiler {
class SamplingThread; class SamplingThread;
// The thread whose stack will be sampled. // The thread whose stack will be sampled.
PlatformThreadId thread_id_; SamplingProfilerThreadToken thread_token_;
const SamplingParams params_; const SamplingParams params_;
......
...@@ -61,7 +61,7 @@ TargetThread::TargetThread(OnceClosure to_run) : to_run_(std::move(to_run)) {} ...@@ -61,7 +61,7 @@ TargetThread::TargetThread(OnceClosure to_run) : to_run_(std::move(to_run)) {}
TargetThread::~TargetThread() = default; TargetThread::~TargetThread() = default;
void TargetThread::ThreadMain() { void TargetThread::ThreadMain() {
id_ = PlatformThread::CurrentId(); thread_token_ = GetSamplingProfilerCurrentThreadToken();
std::move(to_run_).Run(); std::move(to_run_).Run();
} }
...@@ -144,7 +144,7 @@ void WithTargetThread(UnwindScenario* scenario, ...@@ -144,7 +144,7 @@ void WithTargetThread(UnwindScenario* scenario,
events.ready_for_sample.Wait(); events.ready_for_sample.Wait();
std::move(profile_callback).Run(target_thread.id()); std::move(profile_callback).Run(target_thread.thread_token());
events.sample_finished.Signal(); events.sample_finished.Signal();
...@@ -160,12 +160,14 @@ std::vector<Frame> SampleScenario(UnwindScenario* scenario, ...@@ -160,12 +160,14 @@ std::vector<Frame> SampleScenario(UnwindScenario* scenario,
std::vector<Frame> sample; std::vector<Frame> sample;
WithTargetThread( WithTargetThread(
scenario, BindLambdaForTesting([&](PlatformThreadId target_thread_id) { scenario,
BindLambdaForTesting(
[&](SamplingProfilerThreadToken target_thread_token) {
WaitableEvent sampling_thread_completed( WaitableEvent sampling_thread_completed(
WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler( StackSamplingProfiler profiler(
target_thread_id, params, target_thread_token, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache, module_cache,
BindLambdaForTesting([&sample, &sampling_thread_completed]( BindLambdaForTesting([&sample, &sampling_thread_completed](
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/profiler/frame.h" #include "base/profiler/frame.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -26,10 +27,10 @@ class TargetThread : public PlatformThread::Delegate { ...@@ -26,10 +27,10 @@ class TargetThread : public PlatformThread::Delegate {
// PlatformThread::Delegate: // PlatformThread::Delegate:
void ThreadMain() override; void ThreadMain() override;
PlatformThreadId id() const { return id_; } SamplingProfilerThreadToken thread_token() const { return thread_token_; }
private: private:
PlatformThreadId id_ = 0; SamplingProfilerThreadToken thread_token_ = {0};
OnceClosure to_run_; OnceClosure to_run_;
DISALLOW_COPY_AND_ASSIGN(TargetThread); DISALLOW_COPY_AND_ASSIGN(TargetThread);
...@@ -91,7 +92,7 @@ class UnwindScenario { ...@@ -91,7 +92,7 @@ class UnwindScenario {
FunctionAddressRange CallWithPlainFunction(OnceClosure wait_for_sample); FunctionAddressRange CallWithPlainFunction(OnceClosure wait_for_sample);
// The callback to perform profiling on the provided thread. // The callback to perform profiling on the provided thread.
using ProfileCallback = OnceCallback<void(PlatformThreadId)>; using ProfileCallback = OnceCallback<void(SamplingProfilerThreadToken)>;
// Executes |profile_callback| while running |scenario| on the target // Executes |profile_callback| while running |scenario| on the target
// thread. Performs all necessary target thread startup and shutdown work before // thread. Performs all necessary target thread startup and shutdown work before
......
...@@ -270,13 +270,13 @@ void WithTargetThread(ProfileCallback profile_callback) { ...@@ -270,13 +270,13 @@ void WithTargetThread(ProfileCallback profile_callback) {
} }
struct TestProfilerInfo { struct TestProfilerInfo {
TestProfilerInfo(PlatformThreadId thread_id, TestProfilerInfo(SamplingProfilerThreadToken thread_token,
const SamplingParams& params, const SamplingParams& params,
ModuleCache* module_cache, ModuleCache* module_cache,
StackSamplerTestDelegate* delegate = nullptr) StackSamplerTestDelegate* delegate = nullptr)
: completed(WaitableEvent::ResetPolicy::MANUAL, : completed(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED), WaitableEvent::InitialState::NOT_SIGNALED),
profiler(thread_id, profiler(thread_token,
params, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache, module_cache,
...@@ -298,15 +298,15 @@ struct TestProfilerInfo { ...@@ -298,15 +298,15 @@ struct TestProfilerInfo {
// Creates multiple profilers based on a vector of parameters. // Creates multiple profilers based on a vector of parameters.
std::vector<std::unique_ptr<TestProfilerInfo>> CreateProfilers( std::vector<std::unique_ptr<TestProfilerInfo>> CreateProfilers(
PlatformThreadId target_thread_id, SamplingProfilerThreadToken target_thread_token,
const std::vector<SamplingParams>& params, const std::vector<SamplingParams>& params,
ModuleCache* module_cache) { ModuleCache* module_cache) {
DCHECK(!params.empty()); DCHECK(!params.empty());
std::vector<std::unique_ptr<TestProfilerInfo>> profilers; std::vector<std::unique_ptr<TestProfilerInfo>> profilers;
for (const auto& i : params) { for (const auto& i : params) {
profilers.push_back( profilers.push_back(std::make_unique<TestProfilerInfo>(target_thread_token,
std::make_unique<TestProfilerInfo>(target_thread_id, i, module_cache)); i, module_cache));
} }
return profilers; return profilers;
...@@ -318,8 +318,9 @@ std::vector<std::vector<Frame>> CaptureSamples(const SamplingParams& params, ...@@ -318,8 +318,9 @@ std::vector<std::vector<Frame>> CaptureSamples(const SamplingParams& params,
TimeDelta profiler_wait_time, TimeDelta profiler_wait_time,
ModuleCache* module_cache) { ModuleCache* module_cache) {
std::vector<std::vector<Frame>> samples; std::vector<std::vector<Frame>> samples;
WithTargetThread(BindLambdaForTesting([&](PlatformThreadId target_thread_id) { WithTargetThread(BindLambdaForTesting(
TestProfilerInfo info(target_thread_id, params, module_cache); [&](SamplingProfilerThreadToken target_thread_token) {
TestProfilerInfo info(target_thread_token, params, module_cache);
info.profiler.Start(); info.profiler.Start();
info.completed.TimedWait(profiler_wait_time); info.completed.TimedWait(profiler_wait_time);
info.profiler.Stop(); info.profiler.Stop();
...@@ -408,7 +409,7 @@ void TestLibraryUnload(bool wait_until_unloaded, ModuleCache* module_cache) { ...@@ -408,7 +409,7 @@ void TestLibraryUnload(bool wait_until_unloaded, ModuleCache* module_cache) {
StackCopiedSignaler test_delegate(&stack_copied, &start_stack_walk, StackCopiedSignaler test_delegate(&stack_copied, &start_stack_walk,
wait_until_unloaded); wait_until_unloaded);
StackSamplingProfiler profiler( StackSamplingProfiler profiler(
target_thread.id(), params, target_thread.thread_token(), params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache, module_cache,
BindLambdaForTesting( BindLambdaForTesting(
...@@ -618,18 +619,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { ...@@ -618,18 +619,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
// Checks that a profiler can stop/destruct without ever having started. // Checks that a profiler can stop/destruct without ever having started.
PROFILER_TEST_F(StackSamplingProfilerTest, StopWithoutStarting) { PROFILER_TEST_F(StackSamplingProfilerTest, StopWithoutStarting) {
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
SamplingParams params; SamplingParams params;
params.sampling_interval = TimeDelta::FromMilliseconds(0); params.sampling_interval = TimeDelta::FromMilliseconds(0);
params.samples_per_profile = 1; params.samples_per_profile = 1;
Profile profile; Profile profile;
WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent sampling_completed(
WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler( StackSamplingProfiler profiler(
target_thread_id, params, target_thread_token, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting( BindLambdaForTesting(
...@@ -666,8 +668,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) { ...@@ -666,8 +668,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) {
size_t count_ = 0; size_t count_ = 0;
}; };
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
SamplingParams params[2]; SamplingParams params[2];
// Providing an initial delay makes it more likely that both will be // Providing an initial delay makes it more likely that both will be
...@@ -684,37 +686,38 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) { ...@@ -684,37 +686,38 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) {
SampleRecordedCounter samples_recorded[size(params)]; SampleRecordedCounter samples_recorded[size(params)];
TestProfilerInfo profiler_info0(target_thread_id, params[0], module_cache(), TestProfilerInfo profiler_info0(target_thread_token, params[0],
&samples_recorded[0]); module_cache(), &samples_recorded[0]);
TestProfilerInfo profiler_info1(target_thread_id, params[1], module_cache(), TestProfilerInfo profiler_info1(target_thread_token, params[1],
&samples_recorded[1]); module_cache(), &samples_recorded[1]);
profiler_info0.profiler.Start(); profiler_info0.profiler.Start();
profiler_info1.profiler.Start(); profiler_info1.profiler.Start();
// Wait for both to start accumulating samples. Using a WaitableEvent is // Wait for both to start accumulating samples. Using a WaitableEvent is
// possible but gets complicated later on because there's no way of knowing // possible but gets complicated later on because there's no way of
// if 0 or 1 additional sample will be taken after Stop() and thus no way // knowing if 0 or 1 additional sample will be taken after Stop() and
// of knowing how many Wait() calls to make on it. // thus no way of knowing how many Wait() calls to make on it.
while (samples_recorded[0].Get() == 0 || samples_recorded[1].Get() == 0) while (samples_recorded[0].Get() == 0 || samples_recorded[1].Get() == 0)
PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
// Ensure that the first sampler can be safely stopped while the second // Ensure that the first sampler can be safely stopped while the second
// continues to run. The stopped first profiler will still have a // continues to run. The stopped first profiler will still have a
// RecordSampleTask pending that will do nothing when executed because the // RecordSampleTask pending that will do nothing when executed because
// collection will have been removed by Stop(). // the collection will have been removed by Stop().
profiler_info0.profiler.Stop(); profiler_info0.profiler.Stop();
profiler_info0.completed.Wait(); profiler_info0.completed.Wait();
size_t count0 = samples_recorded[0].Get(); size_t count0 = samples_recorded[0].Get();
size_t count1 = samples_recorded[1].Get(); size_t count1 = samples_recorded[1].Get();
// Waiting for the second sampler to collect a couple samples ensures that // Waiting for the second sampler to collect a couple samples ensures
// the pending RecordSampleTask for the first has executed because tasks are // that the pending RecordSampleTask for the first has executed because
// always ordered by their next scheduled time. // tasks are always ordered by their next scheduled time.
while (samples_recorded[1].Get() < count1 + 2) while (samples_recorded[1].Get() < count1 + 2)
PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
// Ensure that the first profiler didn't do anything since it was stopped. // Ensure that the first profiler didn't do anything since it was
// stopped.
EXPECT_EQ(count0, samples_recorded[0].Get()); EXPECT_EQ(count0, samples_recorded[0].Get());
})); }));
} }
...@@ -749,16 +752,16 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) { ...@@ -749,16 +752,16 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) {
WaitableEvent sample_recorded_; WaitableEvent sample_recorded_;
}; };
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
SamplingParams params; SamplingParams params;
params.sampling_interval = AVeryLongTimeDelta(); params.sampling_interval = AVeryLongTimeDelta();
params.samples_per_profile = 2; params.samples_per_profile = 2;
SampleRecordedEvent samples_recorded; SampleRecordedEvent samples_recorded;
TestProfilerInfo profiler_info(target_thread_id, params, module_cache(), TestProfilerInfo profiler_info(target_thread_token, params,
&samples_recorded); module_cache(), &samples_recorded);
profiler_info.profiler.Start(); profiler_info.profiler.Start();
...@@ -779,15 +782,15 @@ PROFILER_TEST_F(StackSamplingProfilerTest, DestroyProfilerWhileProfiling) { ...@@ -779,15 +782,15 @@ PROFILER_TEST_F(StackSamplingProfilerTest, DestroyProfilerWhileProfiling) {
params.sampling_interval = TimeDelta::FromMilliseconds(10); params.sampling_interval = TimeDelta::FromMilliseconds(10);
Profile profile; Profile profile;
WithTargetThread(BindLambdaForTesting([&, this]( WithTargetThread(BindLambdaForTesting([&, this](SamplingProfilerThreadToken
PlatformThreadId target_thread_id) { target_thread_token) {
std::unique_ptr<StackSamplingProfiler> profiler; std::unique_ptr<StackSamplingProfiler> profiler;
auto profile_builder = std::make_unique<TestProfileBuilder>( auto profile_builder = std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting([&profile](Profile result_profile) { BindLambdaForTesting([&profile](Profile result_profile) {
profile = std::move(result_profile); profile = std::move(result_profile);
})); }));
profiler.reset(new StackSamplingProfiler(target_thread_id, params, profiler.reset(new StackSamplingProfiler(target_thread_token, params,
std::move(profile_builder))); std::move(profile_builder)));
profiler->Start(); profiler->Start();
profiler.reset(); profiler.reset();
...@@ -814,8 +817,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { ...@@ -814,8 +817,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) {
// Checks that a sampler can be started while another is running. // Checks that a sampler can be started while another is running.
PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) { PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) {
WithTargetThread( WithTargetThread(BindLambdaForTesting(
BindLambdaForTesting([this](PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
std::vector<SamplingParams> params(2); std::vector<SamplingParams> params(2);
params[0].initial_delay = AVeryLongTimeDelta(); params[0].initial_delay = AVeryLongTimeDelta();
...@@ -825,7 +828,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) { ...@@ -825,7 +828,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) {
params[1].samples_per_profile = 1; params[1].samples_per_profile = 1;
std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
CreateProfilers(target_thread_id, params, module_cache()); CreateProfilers(target_thread_token, params, module_cache());
profiler_infos[0]->profiler.Start(); profiler_infos[0]->profiler.Start();
profiler_infos[1]->profiler.Start(); profiler_infos[1]->profiler.Start();
...@@ -838,19 +841,21 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) { ...@@ -838,19 +841,21 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) {
// correctly. Also checks that RecordMetadata() is invoked each time a sample // correctly. Also checks that RecordMetadata() is invoked each time a sample
// is recorded. // is recorded.
PROFILER_TEST_F(StackSamplingProfilerTest, ProfileGeneralInfo) { PROFILER_TEST_F(StackSamplingProfilerTest, ProfileGeneralInfo) {
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
SamplingParams params; SamplingParams params;
params.sampling_interval = TimeDelta::FromMilliseconds(1); params.sampling_interval = TimeDelta::FromMilliseconds(1);
params.samples_per_profile = 3; params.samples_per_profile = 3;
TestProfilerInfo profiler_info(target_thread_id, params, module_cache()); TestProfilerInfo profiler_info(target_thread_token, params,
module_cache());
profiler_info.profiler.Start(); profiler_info.profiler.Start();
profiler_info.completed.Wait(); profiler_info.completed.Wait();
EXPECT_EQ(3u, profiler_info.profile.samples.size()); EXPECT_EQ(3u, profiler_info.profile.samples.size());
// The profile duration should be greater than the total sampling intervals. // The profile duration should be greater than the total sampling
// intervals.
EXPECT_GT(profiler_info.profile.profile_duration, EXPECT_GT(profiler_info.profile.profile_duration,
profiler_info.profile.sampling_period * 3); profiler_info.profile.sampling_period * 3);
...@@ -915,14 +920,15 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ...@@ -915,14 +920,15 @@ PROFILER_TEST_F(StackSamplingProfilerTest,
// Checks that it's safe to stop a task after it's completed and the sampling // Checks that it's safe to stop a task after it's completed and the sampling
// thread has shut-down for being idle. // thread has shut-down for being idle.
PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) { PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) {
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
SamplingParams params; SamplingParams params;
params.sampling_interval = TimeDelta::FromMilliseconds(1); params.sampling_interval = TimeDelta::FromMilliseconds(1);
params.samples_per_profile = 1; params.samples_per_profile = 1;
TestProfilerInfo profiler_info(target_thread_id, params, module_cache()); TestProfilerInfo profiler_info(target_thread_token, params,
module_cache());
profiler_info.profiler.Start(); profiler_info.profiler.Start();
profiler_info.completed.Wait(); profiler_info.completed.Wait();
...@@ -931,10 +937,11 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) { ...@@ -931,10 +937,11 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) {
ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning()); ASSERT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
// Perform an idle shutdown. // Perform an idle shutdown.
StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(false); StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(
false);
// Stop should be safe though its impossible to know at this moment if the // Stop should be safe though its impossible to know at this moment if
// sampling thread has completely exited or will just "stop soon". // the sampling thread has completely exited or will just "stop soon".
profiler_info.profiler.Stop(); profiler_info.profiler.Stop();
})); }));
} }
...@@ -943,8 +950,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) { ...@@ -943,8 +950,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) {
// started. // started.
PROFILER_TEST_F(StackSamplingProfilerTest, PROFILER_TEST_F(StackSamplingProfilerTest,
ProfileBeforeAndAfterSamplingThreadRunning) { ProfileBeforeAndAfterSamplingThreadRunning) {
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
std::vector<SamplingParams> params(2); std::vector<SamplingParams> params(2);
params[0].initial_delay = AVeryLongTimeDelta(); params[0].initial_delay = AVeryLongTimeDelta();
...@@ -956,10 +963,12 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ...@@ -956,10 +963,12 @@ PROFILER_TEST_F(StackSamplingProfilerTest,
params[1].samples_per_profile = 1; params[1].samples_per_profile = 1;
std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
CreateProfilers(target_thread_id, params, module_cache()); CreateProfilers(target_thread_token, params, module_cache());
// First profiler is started when there has never been a sampling thread. // First profiler is started when there has never been a sampling
EXPECT_FALSE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning()); // thread.
EXPECT_FALSE(
StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
profiler_infos[0]->profiler.Start(); profiler_infos[0]->profiler.Start();
// Second profiler is started when sampling thread is already running. // Second profiler is started when sampling thread is already running.
EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning()); EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
...@@ -974,14 +983,15 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ...@@ -974,14 +983,15 @@ PROFILER_TEST_F(StackSamplingProfilerTest,
// Checks that an idle-shutdown task will abort if a new profiler starts // Checks that an idle-shutdown task will abort if a new profiler starts
// between when it was posted and when it runs. // between when it was posted and when it runs.
PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) { PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) {
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
SamplingParams params; SamplingParams params;
params.sampling_interval = TimeDelta::FromMilliseconds(1); params.sampling_interval = TimeDelta::FromMilliseconds(1);
params.samples_per_profile = 1; params.samples_per_profile = 1;
TestProfilerInfo profiler_info(target_thread_id, params, module_cache()); TestProfilerInfo profiler_info(target_thread_token, params,
module_cache());
profiler_info.profiler.Start(); profiler_info.profiler.Start();
profiler_info.completed.Wait(); profiler_info.completed.Wait();
...@@ -989,18 +999,21 @@ PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) { ...@@ -989,18 +999,21 @@ PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) {
// Perform an idle shutdown but simulate that a new capture is started // Perform an idle shutdown but simulate that a new capture is started
// before it can actually run. // before it can actually run.
StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(true); StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(
true);
// Though the shutdown-task has been executed, any actual exit of the // Though the shutdown-task has been executed, any actual exit of the
// thread is asynchronous so there is no way to detect that *didn't* exit // thread is asynchronous so there is no way to detect that *didn't*
// except to wait a reasonable amount of time and then check. Since the // exit except to wait a reasonable amount of time and then check. Since
// thread was just running ("perform" blocked until it was), it should // the thread was just running ("perform" blocked until it was), it
// finish almost immediately and without any waiting for tasks or events. // should finish almost immediately and without any waiting for tasks or
// events.
PlatformThread::Sleep(TimeDelta::FromMilliseconds(200)); PlatformThread::Sleep(TimeDelta::FromMilliseconds(200));
EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning()); EXPECT_TRUE(StackSamplingProfiler::TestPeer::IsSamplingThreadRunning());
// Ensure that it's still possible to run another sampler. // Ensure that it's still possible to run another sampler.
TestProfilerInfo another_info(target_thread_id, params, module_cache()); TestProfilerInfo another_info(target_thread_token, params,
module_cache());
another_info.profiler.Start(); another_info.profiler.Start();
another_info.completed.Wait(); another_info.completed.Wait();
EXPECT_EQ(1u, another_info.profile.samples.size()); EXPECT_EQ(1u, another_info.profile.samples.size());
...@@ -1009,8 +1022,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) { ...@@ -1009,8 +1022,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) {
// Checks that synchronized multiple sampling requests execute in parallel. // Checks that synchronized multiple sampling requests execute in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) { PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) {
WithTargetThread( WithTargetThread(BindLambdaForTesting(
BindLambdaForTesting([this](PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
std::vector<SamplingParams> params(2); std::vector<SamplingParams> params(2);
// Providing an initial delay makes it more likely that both will be // Providing an initial delay makes it more likely that both will be
...@@ -1028,7 +1041,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) { ...@@ -1028,7 +1041,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) {
params[1].samples_per_profile = 8; params[1].samples_per_profile = 8;
std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
CreateProfilers(target_thread_id, params, module_cache()); CreateProfilers(target_thread_token, params, module_cache());
profiler_infos[0]->profiler.Start(); profiler_infos[0]->profiler.Start();
profiler_infos[1]->profiler.Start(); profiler_infos[1]->profiler.Start();
...@@ -1048,8 +1061,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) { ...@@ -1048,8 +1061,8 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) {
// Checks that several mixed sampling requests execute in parallel. // Checks that several mixed sampling requests execute in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) { PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) {
WithTargetThread(BindLambdaForTesting([this]( WithTargetThread(BindLambdaForTesting(
PlatformThreadId target_thread_id) { [this](SamplingProfilerThreadToken target_thread_token) {
std::vector<SamplingParams> params(3); std::vector<SamplingParams> params(3);
params[0].initial_delay = TimeDelta::FromMilliseconds(8); params[0].initial_delay = TimeDelta::FromMilliseconds(8);
...@@ -1065,15 +1078,17 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) { ...@@ -1065,15 +1078,17 @@ PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) {
params[2].samples_per_profile = 10; params[2].samples_per_profile = 10;
std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos = std::vector<std::unique_ptr<TestProfilerInfo>> profiler_infos =
CreateProfilers(target_thread_id, params, module_cache()); CreateProfilers(target_thread_token, params, module_cache());
for (auto& i : profiler_infos) for (auto& i : profiler_infos)
i->profiler.Start(); i->profiler.Start();
// Wait for one profiler to finish. // Wait for one profiler to finish.
size_t completed_profiler = WaitForSamplingComplete(profiler_infos); size_t completed_profiler = WaitForSamplingComplete(profiler_infos);
EXPECT_EQ(10u, profiler_infos[completed_profiler]->profile.samples.size()); EXPECT_EQ(10u,
// Stop and destroy all profilers, always in the same order. Don't crash. profiler_infos[completed_profiler]->profile.samples.size());
// Stop and destroy all profilers, always in the same order. Don't
// crash.
for (auto& i : profiler_infos) for (auto& i : profiler_infos)
i->profiler.Stop(); i->profiler.Stop();
for (auto& i : profiler_infos) for (auto& i : profiler_infos)
...@@ -1120,7 +1135,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) { ...@@ -1120,7 +1135,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) {
WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler1( StackSamplingProfiler profiler1(
target_thread1.id(), params1, target_thread1.thread_token(), params1,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting( BindLambdaForTesting(
...@@ -1133,7 +1148,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) { ...@@ -1133,7 +1148,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) {
WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler2( StackSamplingProfiler profiler2(
target_thread2.id(), params2, target_thread2.thread_token(), params2,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting( BindLambdaForTesting(
...@@ -1160,7 +1175,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) { ...@@ -1160,7 +1175,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) {
class ProfilerThread : public SimpleThread { class ProfilerThread : public SimpleThread {
public: public:
ProfilerThread(const std::string& name, ProfilerThread(const std::string& name,
PlatformThreadId thread_id, SamplingProfilerThreadToken thread_token,
const SamplingParams& params, const SamplingParams& params,
ModuleCache* module_cache) ModuleCache* module_cache)
: SimpleThread(name, Options()), : SimpleThread(name, Options()),
...@@ -1168,7 +1183,7 @@ class ProfilerThread : public SimpleThread { ...@@ -1168,7 +1183,7 @@ class ProfilerThread : public SimpleThread {
WaitableEvent::InitialState::NOT_SIGNALED), WaitableEvent::InitialState::NOT_SIGNALED),
completed_(WaitableEvent::ResetPolicy::MANUAL, completed_(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED), WaitableEvent::InitialState::NOT_SIGNALED),
profiler_(thread_id, profiler_(thread_token,
params, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache, module_cache,
...@@ -1198,7 +1213,8 @@ class ProfilerThread : public SimpleThread { ...@@ -1198,7 +1213,8 @@ class ProfilerThread : public SimpleThread {
// Checks that different threads can run samplers in parallel. // Checks that different threads can run samplers in parallel.
PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) { PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) {
WithTargetThread(BindLambdaForTesting([](PlatformThreadId target_thread_id) { WithTargetThread(
BindLambdaForTesting([](SamplingProfilerThreadToken target_thread_token) {
// Providing an initial delay makes it more likely that both will be // Providing an initial delay makes it more likely that both will be
// scheduled before either starts to run. Once started, samples will // scheduled before either starts to run. Once started, samples will
// run ordered by their scheduled, interleaved times regardless of // run ordered by their scheduled, interleaved times regardless of
...@@ -1213,11 +1229,11 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) { ...@@ -1213,11 +1229,11 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) {
// Start the profiler threads and give them a moment to get going. // Start the profiler threads and give them a moment to get going.
ModuleCache module_cache1; ModuleCache module_cache1;
ProfilerThread profiler_thread1("profiler1", target_thread_id, params1, ProfilerThread profiler_thread1("profiler1", target_thread_token,
&module_cache1); params1, &module_cache1);
ModuleCache module_cache2; ModuleCache module_cache2;
ProfilerThread profiler_thread2("profiler2", target_thread_id, params2, ProfilerThread profiler_thread2("profiler2", target_thread_token,
&module_cache2); params2, &module_cache2);
profiler_thread1.Start(); profiler_thread1.Start();
profiler_thread2.Start(); profiler_thread2.Start();
PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); PlatformThread::Sleep(TimeDelta::FromMilliseconds(10));
...@@ -1245,17 +1261,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_BeforeStart) { ...@@ -1245,17 +1261,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_BeforeStart) {
UnwindScenario scenario(BindRepeating(&CallWithPlainFunction)); UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
Profile profile; Profile profile;
WithTargetThread(&scenario, BindLambdaForTesting([&](PlatformThreadId WithTargetThread(
target_thread_id) { &scenario,
BindLambdaForTesting(
[&](SamplingProfilerThreadToken target_thread_token) {
WaitableEvent sampling_thread_completed( WaitableEvent sampling_thread_completed(
WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler( StackSamplingProfiler profiler(
target_thread_id, params, target_thread_token, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting( BindLambdaForTesting([&profile, &sampling_thread_completed](
[&profile, &sampling_thread_completed](Profile result_profile) { Profile result_profile) {
profile = std::move(result_profile); profile = std::move(result_profile);
sampling_thread_completed.Signal(); sampling_thread_completed.Signal();
}))); })));
...@@ -1283,17 +1301,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_AfterStart) { ...@@ -1283,17 +1301,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_AfterStart) {
UnwindScenario scenario(BindRepeating(&CallWithPlainFunction)); UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
Profile profile; Profile profile;
WithTargetThread(&scenario, BindLambdaForTesting([&](PlatformThreadId WithTargetThread(
target_thread_id) { &scenario,
BindLambdaForTesting(
[&](SamplingProfilerThreadToken target_thread_token) {
WaitableEvent sampling_thread_completed( WaitableEvent sampling_thread_completed(
WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler( StackSamplingProfiler profiler(
target_thread_id, params, target_thread_token, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting( BindLambdaForTesting([&profile, &sampling_thread_completed](
[&profile, &sampling_thread_completed](Profile result_profile) { Profile result_profile) {
profile = std::move(result_profile); profile = std::move(result_profile);
sampling_thread_completed.Signal(); sampling_thread_completed.Signal();
}))); })));
...@@ -1321,17 +1341,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_AfterStop) { ...@@ -1321,17 +1341,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, AddAuxUnwinder_AfterStop) {
UnwindScenario scenario(BindRepeating(&CallWithPlainFunction)); UnwindScenario scenario(BindRepeating(&CallWithPlainFunction));
Profile profile; Profile profile;
WithTargetThread(&scenario, BindLambdaForTesting([&](PlatformThreadId WithTargetThread(
target_thread_id) { &scenario,
BindLambdaForTesting(
[&](SamplingProfilerThreadToken target_thread_token) {
WaitableEvent sampling_thread_completed( WaitableEvent sampling_thread_completed(
WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED); WaitableEvent::InitialState::NOT_SIGNALED);
StackSamplingProfiler profiler( StackSamplingProfiler profiler(
target_thread_id, params, target_thread_token, params,
std::make_unique<TestProfileBuilder>( std::make_unique<TestProfileBuilder>(
module_cache(), module_cache(),
BindLambdaForTesting( BindLambdaForTesting([&profile, &sampling_thread_completed](
[&profile, &sampling_thread_completed](Profile result_profile) { Profile result_profile) {
profile = std::move(result_profile); profile = std::move(result_profile);
sampling_thread_completed.Signal(); sampling_thread_completed.Signal();
}))); })));
......
...@@ -59,10 +59,11 @@ bool SuspendableThreadDelegateMac::ScopedSuspendThread::WasSuccessful() const { ...@@ -59,10 +59,11 @@ bool SuspendableThreadDelegateMac::ScopedSuspendThread::WasSuccessful() const {
// SuspendableThreadDelegateMac ----------------------------------------------- // SuspendableThreadDelegateMac -----------------------------------------------
SuspendableThreadDelegateMac::SuspendableThreadDelegateMac( SuspendableThreadDelegateMac::SuspendableThreadDelegateMac(
mach_port_t thread_port) SamplingProfilerThreadToken thread_token)
: thread_port_(thread_port), : thread_port_(thread_token.id),
thread_stack_base_address_(reinterpret_cast<uintptr_t>( thread_stack_base_address_(
pthread_get_stackaddr_np(pthread_from_mach_thread_np(thread_port)))) { reinterpret_cast<uintptr_t>(pthread_get_stackaddr_np(
pthread_from_mach_thread_np(thread_token.id)))) {
// This class suspends threads, and those threads might be suspended in dyld. // This class suspends threads, and those threads might be suspended in dyld.
// Therefore, for all the system functions that might be linked in dynamically // Therefore, for all the system functions that might be linked in dynamically
// that are used while threads are suspended, make calls to them to make sure // that are used while threads are suspended, make calls to them to make sure
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/base_export.h" #include "base/base_export.h"
#include "base/profiler/native_unwinder_mac.h" #include "base/profiler/native_unwinder_mac.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/suspendable_thread_delegate.h" #include "base/profiler/suspendable_thread_delegate.h"
#include "base/sampling_heap_profiler/module_cache.h" #include "base/sampling_heap_profiler/module_cache.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -35,7 +36,7 @@ class BASE_EXPORT SuspendableThreadDelegateMac ...@@ -35,7 +36,7 @@ class BASE_EXPORT SuspendableThreadDelegateMac
mach_port_t thread_port_; mach_port_t thread_port_;
}; };
SuspendableThreadDelegateMac(mach_port_t thread_port); SuspendableThreadDelegateMac(SamplingProfilerThreadToken thread_token);
~SuspendableThreadDelegateMac() override; ~SuspendableThreadDelegateMac() override;
SuspendableThreadDelegateMac(const SuspendableThreadDelegateMac&) = delete; SuspendableThreadDelegateMac(const SuspendableThreadDelegateMac&) = delete;
......
...@@ -172,9 +172,9 @@ bool SuspendableThreadDelegateWin::ScopedSuspendThread::WasSuccessful() const { ...@@ -172,9 +172,9 @@ bool SuspendableThreadDelegateWin::ScopedSuspendThread::WasSuccessful() const {
// ---------------------------------------------------------- // ----------------------------------------------------------
SuspendableThreadDelegateWin::SuspendableThreadDelegateWin( SuspendableThreadDelegateWin::SuspendableThreadDelegateWin(
PlatformThreadId thread_id) SamplingProfilerThreadToken thread_token)
: thread_id_(thread_id), : thread_id_(thread_token.id),
thread_handle_(GetThreadHandle(thread_id)), thread_handle_(GetThreadHandle(thread_token.id)),
thread_stack_base_address_(reinterpret_cast<uintptr_t>( thread_stack_base_address_(reinterpret_cast<uintptr_t>(
GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase)) {} GetThreadEnvironmentBlock(thread_handle_.Get())->Tib.StackBase)) {}
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <windows.h> #include <windows.h>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/suspendable_thread_delegate.h" #include "base/profiler/suspendable_thread_delegate.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
...@@ -34,7 +35,8 @@ class BASE_EXPORT SuspendableThreadDelegateWin ...@@ -34,7 +35,8 @@ class BASE_EXPORT SuspendableThreadDelegateWin
DISALLOW_COPY_AND_ASSIGN(ScopedSuspendThread); DISALLOW_COPY_AND_ASSIGN(ScopedSuspendThread);
}; };
explicit SuspendableThreadDelegateWin(PlatformThreadId thread_id); explicit SuspendableThreadDelegateWin(
SamplingProfilerThreadToken thread_token);
~SuspendableThreadDelegateWin() override; ~SuspendableThreadDelegateWin() override;
SuspendableThreadDelegateWin(const SuspendableThreadDelegateWin&) = delete; SuspendableThreadDelegateWin(const SuspendableThreadDelegateWin&) = delete;
......
...@@ -12,9 +12,9 @@ namespace base { ...@@ -12,9 +12,9 @@ namespace base {
namespace { namespace {
uintptr_t GetThreadStackBaseAddress(PlatformThreadId thread_id) { uintptr_t GetThreadStackBaseAddress(pthread_t pthread_id) {
pthread_attr_t attr; pthread_attr_t attr;
pthread_getattr_np(thread_id, &attr); pthread_getattr_np(pthread_id, &attr);
void* base_address; void* base_address;
size_t size; size_t size;
pthread_attr_getstack(&attr, &base_address, &size); pthread_attr_getstack(&attr, &base_address, &size);
...@@ -23,9 +23,11 @@ uintptr_t GetThreadStackBaseAddress(PlatformThreadId thread_id) { ...@@ -23,9 +23,11 @@ uintptr_t GetThreadStackBaseAddress(PlatformThreadId thread_id) {
} // namespace } // namespace
ThreadDelegatePosix::ThreadDelegatePosix(PlatformThreadId thread_id) ThreadDelegatePosix::ThreadDelegatePosix(
: thread_id_(thread_id), SamplingProfilerThreadToken thread_token)
thread_stack_base_address_(GetThreadStackBaseAddress(thread_id)) {} : thread_id_(thread_token.id),
thread_stack_base_address_(
GetThreadStackBaseAddress(thread_token.pthread_id)) {}
PlatformThreadId ThreadDelegatePosix::GetThreadId() const { PlatformThreadId ThreadDelegatePosix::GetThreadId() const {
return thread_id_; return thread_id_;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define BASE_PROFILER_THREAD_DELEGATE_POSIX_H_ #define BASE_PROFILER_THREAD_DELEGATE_POSIX_H_
#include "base/base_export.h" #include "base/base_export.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/thread_delegate.h" #include "base/profiler/thread_delegate.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -15,7 +16,7 @@ namespace base { ...@@ -15,7 +16,7 @@ namespace base {
// POSIX. // POSIX.
class BASE_EXPORT ThreadDelegatePosix : public ThreadDelegate { class BASE_EXPORT ThreadDelegatePosix : public ThreadDelegate {
public: public:
ThreadDelegatePosix(PlatformThreadId thread_id); ThreadDelegatePosix(SamplingProfilerThreadToken thread_token);
ThreadDelegatePosix(const ThreadDelegatePosix&) = delete; ThreadDelegatePosix(const ThreadDelegatePosix&) = delete;
ThreadDelegatePosix& operator=(const ThreadDelegatePosix&) = delete; ThreadDelegatePosix& operator=(const ThreadDelegatePosix&) = delete;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/message_loop/work_id_provider.h" #include "base/message_loop/work_id_provider.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/profiler/sample_metadata.h" #include "base/profiler/sample_metadata.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/threading/sequence_local_storage_slot.h" #include "base/threading/sequence_local_storage_slot.h"
...@@ -237,7 +238,7 @@ ThreadProfiler::ThreadProfiler( ...@@ -237,7 +238,7 @@ ThreadProfiler::ThreadProfiler(
return; return;
startup_profiler_ = std::make_unique<StackSamplingProfiler>( startup_profiler_ = std::make_unique<StackSamplingProfiler>(
base::PlatformThread::CurrentId(), kSamplingParams, base::GetSamplingProfilerCurrentThreadToken(), kSamplingParams,
std::make_unique<CallStackProfileBuilder>( std::make_unique<CallStackProfileBuilder>(
CallStackProfileParams(GetProcess(), thread, CallStackProfileParams(GetProcess(), thread,
CallStackProfileParams::PROCESS_STARTUP), CallStackProfileParams::PROCESS_STARTUP),
...@@ -297,7 +298,7 @@ void ThreadProfiler::StartPeriodicSamplingCollection() { ...@@ -297,7 +298,7 @@ void ThreadProfiler::StartPeriodicSamplingCollection() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// NB: Destroys the previous profiler as side effect. // NB: Destroys the previous profiler as side effect.
periodic_profiler_ = std::make_unique<StackSamplingProfiler>( periodic_profiler_ = std::make_unique<StackSamplingProfiler>(
base::PlatformThread::CurrentId(), kSamplingParams, base::GetSamplingProfilerCurrentThreadToken(), kSamplingParams,
std::make_unique<CallStackProfileBuilder>( std::make_unique<CallStackProfileBuilder>(
CallStackProfileParams(GetProcess(), thread_, CallStackProfileParams(GetProcess(), thread_,
CallStackProfileParams::PERIODIC_COLLECTION), CallStackProfileParams::PERIODIC_COLLECTION),
......
...@@ -13,9 +13,10 @@ namespace { ...@@ -13,9 +13,10 @@ namespace {
constexpr size_t kMaxFrameDepth = 48; constexpr size_t kMaxFrameDepth = 48;
} // namespace } // namespace
StackSamplerAndroid::StackSamplerAndroid(base::PlatformThreadId tid, StackSamplerAndroid::StackSamplerAndroid(
base::SamplingProfilerThreadToken thread_token,
base::ModuleCache* module_cache) base::ModuleCache* module_cache)
: tid_(tid), module_cache_(module_cache) {} : thread_token_(thread_token), module_cache_(module_cache) {}
StackSamplerAndroid::~StackSamplerAndroid() = default; StackSamplerAndroid::~StackSamplerAndroid() = default;
...@@ -35,7 +36,8 @@ void StackSamplerAndroid::RecordStackFrames( ...@@ -35,7 +36,8 @@ void StackSamplerAndroid::RecordStackFrames(
unwinder_.Initialize(); unwinder_.Initialize();
} }
const void* pcs[kMaxFrameDepth]; const void* pcs[kMaxFrameDepth];
size_t depth = unwinder_.TraceStack(tid_, stack_buffer, pcs, kMaxFrameDepth); size_t depth =
unwinder_.TraceStack(thread_token_.id, stack_buffer, pcs, kMaxFrameDepth);
std::vector<base::Frame> frames; std::vector<base::Frame> frames;
frames.reserve(depth); frames.reserve(depth);
for (size_t i = 0; i < depth; ++i) { for (size_t i = 0; i < depth; ++i) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef SERVICES_TRACING_PUBLIC_CPP_STACK_SAMPLING_STACK_SAMPLER_ANDROID_H_ #ifndef SERVICES_TRACING_PUBLIC_CPP_STACK_SAMPLING_STACK_SAMPLER_ANDROID_H_
#define SERVICES_TRACING_PUBLIC_CPP_STACK_SAMPLING_STACK_SAMPLER_ANDROID_H_ #define SERVICES_TRACING_PUBLIC_CPP_STACK_SAMPLING_STACK_SAMPLER_ANDROID_H_
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/stack_sampler.h" #include "base/profiler/stack_sampler.h"
#include "base/sampling_heap_profiler/module_cache.h" #include "base/sampling_heap_profiler/module_cache.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -19,7 +20,7 @@ class StackSamplerAndroid : public base::StackSampler { ...@@ -19,7 +20,7 @@ class StackSamplerAndroid : public base::StackSampler {
// StackUnwinderAndroid only supports sampling one thread at a time. So, the // StackUnwinderAndroid only supports sampling one thread at a time. So, the
// clients of this class must ensure synchronization between multiple // clients of this class must ensure synchronization between multiple
// instances of the sampler. // instances of the sampler.
explicit StackSamplerAndroid(base::PlatformThreadId thread_id, explicit StackSamplerAndroid(base::SamplingProfilerThreadToken thread_token,
base::ModuleCache*); base::ModuleCache*);
~StackSamplerAndroid() override; ~StackSamplerAndroid() override;
...@@ -32,7 +33,7 @@ class StackSamplerAndroid : public base::StackSampler { ...@@ -32,7 +33,7 @@ class StackSamplerAndroid : public base::StackSampler {
base::ProfileBuilder* profile_builder) override; base::ProfileBuilder* profile_builder) override;
private: private:
base::PlatformThreadId tid_; base::SamplingProfilerThreadToken thread_token_;
base::ModuleCache* module_cache_; base::ModuleCache* module_cache_;
StackUnwinderAndroid unwinder_; StackUnwinderAndroid unwinder_;
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/process/process.h" #include "base/process/process.h"
#include "base/process/process_handle.h" #include "base/process/process_handle.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/stack_sampling_profiler.h" #include "base/profiler/stack_sampling_profiler.h"
#include "base/strings/strcat.h" #include "base/strings/strcat.h"
#include "base/task/thread_pool/thread_pool_instance.h" #include "base/task/thread_pool/thread_pool_instance.h"
...@@ -461,7 +462,7 @@ TracingSamplerProfiler::TracingProfileBuilder::GetCallstackIDAndMaybeEmit( ...@@ -461,7 +462,7 @@ TracingSamplerProfiler::TracingProfileBuilder::GetCallstackIDAndMaybeEmit(
std::unique_ptr<TracingSamplerProfiler> std::unique_ptr<TracingSamplerProfiler>
TracingSamplerProfiler::CreateOnMainThread() { TracingSamplerProfiler::CreateOnMainThread() {
return std::make_unique<TracingSamplerProfiler>( return std::make_unique<TracingSamplerProfiler>(
(base::PlatformThread::CurrentId())); base::GetSamplingProfilerCurrentThreadToken());
} }
// static // static
...@@ -471,7 +472,7 @@ void TracingSamplerProfiler::CreateOnChildThread() { ...@@ -471,7 +472,7 @@ void TracingSamplerProfiler::CreateOnChildThread() {
return; return;
auto* profiler = auto* profiler =
new TracingSamplerProfiler(base::PlatformThread::CurrentId()); new TracingSamplerProfiler(base::GetSamplingProfilerCurrentThreadToken());
slot->Set(profiler); slot->Set(profiler);
} }
...@@ -508,9 +509,9 @@ void TracingSamplerProfiler::StopTracingForTesting() { ...@@ -508,9 +509,9 @@ void TracingSamplerProfiler::StopTracingForTesting() {
} }
TracingSamplerProfiler::TracingSamplerProfiler( TracingSamplerProfiler::TracingSamplerProfiler(
base::PlatformThreadId sampled_thread_id) base::SamplingProfilerThreadToken sampled_thread_token)
: sampled_thread_id_(sampled_thread_id) { : sampled_thread_token_(sampled_thread_token) {
DCHECK_NE(sampled_thread_id_, base::kInvalidThreadId); DCHECK_NE(sampled_thread_token_.id, base::kInvalidThreadId);
TracingSamplerProfilerDataSource::Get()->RegisterProfiler(this); TracingSamplerProfilerDataSource::Get()->RegisterProfiler(this);
} }
...@@ -545,20 +546,22 @@ void TracingSamplerProfiler::StartTracing( ...@@ -545,20 +546,22 @@ void TracingSamplerProfiler::StartTracing(
params.keep_consistent_sampling_interval = false; params.keep_consistent_sampling_interval = false;
auto profile_builder = std::make_unique<TracingProfileBuilder>( auto profile_builder = std::make_unique<TracingProfileBuilder>(
sampled_thread_id_, std::move(trace_writer), should_enable_filtering); sampled_thread_token_.id, std::move(trace_writer),
should_enable_filtering);
profile_builder_ = profile_builder.get(); profile_builder_ = profile_builder.get();
// Create and start the stack sampling profiler. // Create and start the stack sampling profiler.
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#if BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && defined(OFFICIAL_BUILD) #if BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && defined(OFFICIAL_BUILD)
auto* module_cache = profile_builder->GetModuleCache(); auto* module_cache = profile_builder->GetModuleCache();
profiler_ = std::make_unique<base::StackSamplingProfiler>( profiler_ = std::make_unique<base::StackSamplingProfiler>(
sampled_thread_id_, params, std::move(profile_builder), sampled_thread_token_, params, std::move(profile_builder),
std::make_unique<StackSamplerAndroid>(sampled_thread_id_, module_cache)); std::make_unique<StackSamplerAndroid>(sampled_thread_token_,
module_cache));
profiler_->Start(); profiler_->Start();
#endif // BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && defined(OFFICIAL_BUILD) #endif // BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && defined(OFFICIAL_BUILD)
#else // defined(OS_ANDROID) #else // defined(OS_ANDROID)
profiler_ = std::make_unique<base::StackSamplingProfiler>( profiler_ = std::make_unique<base::StackSamplingProfiler>(
sampled_thread_id_, params, std::move(profile_builder)); sampled_thread_token_, params, std::move(profile_builder));
profiler_->Start(); profiler_->Start();
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/component_export.h" #include "base/component_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/stack_sampling_profiler.h" #include "base/profiler/stack_sampling_profiler.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
...@@ -116,7 +117,8 @@ class COMPONENT_EXPORT(TRACING_CPP) TracingSamplerProfiler { ...@@ -116,7 +117,8 @@ class COMPONENT_EXPORT(TRACING_CPP) TracingSamplerProfiler {
static void StartTracingForTesting(tracing::PerfettoProducer* producer); static void StartTracingForTesting(tracing::PerfettoProducer* producer);
static void StopTracingForTesting(); static void StopTracingForTesting();
explicit TracingSamplerProfiler(base::PlatformThreadId sampled_thread_id); explicit TracingSamplerProfiler(
base::SamplingProfilerThreadToken sampled_thread_token);
virtual ~TracingSamplerProfiler(); virtual ~TracingSamplerProfiler();
void StartTracing(std::unique_ptr<perfetto::TraceWriter> trace_writer, void StartTracing(std::unique_ptr<perfetto::TraceWriter> trace_writer,
...@@ -124,7 +126,7 @@ class COMPONENT_EXPORT(TRACING_CPP) TracingSamplerProfiler { ...@@ -124,7 +126,7 @@ class COMPONENT_EXPORT(TRACING_CPP) TracingSamplerProfiler {
void StopTracing(); void StopTracing();
private: private:
const base::PlatformThreadId sampled_thread_id_; const base::SamplingProfilerThreadToken sampled_thread_token_;
base::Lock lock_; base::Lock lock_;
std::unique_ptr<base::StackSamplingProfiler> profiler_; // under |lock_| std::unique_ptr<base::StackSamplingProfiler> profiler_; // under |lock_|
......
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