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
......
...@@ -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