#include "base/profiler/stack_sampling_profiler.h"
#include <algorithm>
#include <cmath>
#include <map>
#include <optional>
#include <utility>
#include "base/atomic_sequence_num.h"
#include "base/atomicops.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/singleton.h"
#include "base/profiler/profiler_buildflags.h"
#include "base/profiler/stack_buffer.h"
#include "base/profiler/stack_sampler.h"
#include "base/profiler/stack_unwind_data.h"
#include "base/profiler/unwinder.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/thread_annotations.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/trace_event/base_tracing.h"
#include "build/build_config.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/static_constants.h"
#endif
#if BUILDFLAG(IS_APPLE)
#include "base/mac/mac_util.h"
#endif
namespace base {
class ScopedAllowThreadRecallForStackSamplingProfiler
: public ScopedAllowBaseSyncPrimitivesOutsideBlockingScope { … };
namespace {
constexpr WaitableEvent::ResetPolicy kResetPolicy = …;
const int kNullProfilerId = …;
TimeTicks GetNextSampleTimeImpl(TimeTicks scheduled_current_sample_time,
TimeDelta sampling_interval,
TimeTicks now) { … }
}
class StackSamplingProfiler::SamplingThread : public Thread { … };
void StackSamplingProfiler::SamplingThread::TestPeer::Reset() { … }
void StackSamplingProfiler::SamplingThread::TestPeer::DisableIdleShutdown() { … }
void StackSamplingProfiler::SamplingThread::TestPeer::ShutdownAssumingIdle(
bool simulate_intervening_add) { … }
void StackSamplingProfiler::SamplingThread::TestPeer::
ShutdownTaskAndSignalEvent(SamplingThread* sampler,
int add_events,
WaitableEvent* event) { … }
AtomicSequenceNumber StackSamplingProfiler::SamplingThread::CollectionContext::
next_collection_id;
StackSamplingProfiler::SamplingThread::SamplingThread()
: … { … }
StackSamplingProfiler::SamplingThread::~SamplingThread() = default;
StackSamplingProfiler::SamplingThread*
StackSamplingProfiler::SamplingThread::GetInstance() { … }
int StackSamplingProfiler::SamplingThread::Add(
std::unique_ptr<CollectionContext> collection) { … }
void StackSamplingProfiler::SamplingThread::AddAuxUnwinder(
int collection_id,
std::unique_ptr<Unwinder> unwinder) { … }
void StackSamplingProfiler::SamplingThread::ApplyMetadataToPastSamples(
base::TimeTicks period_start,
base::TimeTicks period_end,
uint64_t name_hash,
std::optional<int64_t> key,
int64_t value,
std::optional<PlatformThreadId> thread_id) { … }
void StackSamplingProfiler::SamplingThread::AddProfileMetadata(
uint64_t name_hash,
std::optional<int64_t> key,
int64_t value,
std::optional<PlatformThreadId> thread_id) { … }
void StackSamplingProfiler::SamplingThread::Remove(int collection_id) { … }
scoped_refptr<SingleThreadTaskRunner>
StackSamplingProfiler::SamplingThread::GetOrCreateTaskRunnerForAdd() { … }
scoped_refptr<SingleThreadTaskRunner>
StackSamplingProfiler::SamplingThread::GetTaskRunner(
ThreadExecutionState* out_state) { … }
scoped_refptr<SingleThreadTaskRunner>
StackSamplingProfiler::SamplingThread::GetTaskRunnerOnSamplingThread() { … }
void StackSamplingProfiler::SamplingThread::FinishCollection(
std::unique_ptr<CollectionContext> collection) { … }
void StackSamplingProfiler::SamplingThread::ScheduleShutdownIfIdle() { … }
void StackSamplingProfiler::SamplingThread::AddAuxUnwinderTask(
int collection_id,
std::unique_ptr<Unwinder> unwinder) { … }
void StackSamplingProfiler::SamplingThread::ApplyMetadataToPastSamplesTask(
base::TimeTicks period_start,
base::TimeTicks period_end,
uint64_t name_hash,
std::optional<int64_t> key,
int64_t value,
std::optional<PlatformThreadId> thread_id) { … }
void StackSamplingProfiler::SamplingThread::AddProfileMetadataTask(
uint64_t name_hash,
std::optional<int64_t> key,
int64_t value,
std::optional<PlatformThreadId> thread_id) { … }
void StackSamplingProfiler::SamplingThread::AddCollectionTask(
std::unique_ptr<CollectionContext> collection) { … }
void StackSamplingProfiler::SamplingThread::RemoveCollectionTask(
int collection_id) { … }
void StackSamplingProfiler::SamplingThread::ScheduleCollectionStop(
int collection_id) { … }
void StackSamplingProfiler::SamplingThread::RecordSampleTask(
int collection_id) { … }
void StackSamplingProfiler::SamplingThread::ShutdownTask(int add_events) { … }
void StackSamplingProfiler::SamplingThread::CleanUp() { … }
void StackSamplingProfiler::TestPeer::Reset() { … }
bool StackSamplingProfiler::TestPeer::IsSamplingThreadRunning() { … }
void StackSamplingProfiler::TestPeer::DisableIdleShutdown() { … }
void StackSamplingProfiler::TestPeer::PerformSamplingThreadIdleShutdown(
bool simulate_intervening_start) { … }
TimeTicks StackSamplingProfiler::TestPeer::GetNextSampleTime(
TimeTicks scheduled_current_sample_time,
TimeDelta sampling_interval,
TimeTicks now) { … }
bool StackSamplingProfiler::IsSupportedForCurrentPlatform() { … }
StackSamplingProfiler::StackSamplingProfiler(
SamplingProfilerThreadToken thread_token,
const SamplingParams& params,
std::unique_ptr<ProfileBuilder> profile_builder,
UnwindersFactory core_unwinders_factory,
RepeatingClosure record_sample_callback,
StackSamplerTestDelegate* test_delegate)
: … { … }
StackSamplingProfiler::~StackSamplingProfiler() { … }
void StackSamplingProfiler::Start() { … }
void StackSamplingProfiler::Stop() { … }
void StackSamplingProfiler::AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder) { … }
void StackSamplingProfiler::ApplyMetadataToPastSamples(
base::TimeTicks period_start,
base::TimeTicks period_end,
uint64_t name_hash,
std::optional<int64_t> key,
int64_t value,
std::optional<PlatformThreadId> thread_id) { … }
void StackSamplingProfiler::AddProfileMetadata(
uint64_t name_hash,
int64_t key,
int64_t value,
std::optional<PlatformThreadId> thread_id) { … }
}