diff options
Diffstat (limited to 'lib/xray/xray_profiling.cc')
-rw-r--r-- | lib/xray/xray_profiling.cc | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/lib/xray/xray_profiling.cc b/lib/xray/xray_profiling.cc index d4b4345d7..6615de1a3 100644 --- a/lib/xray/xray_profiling.cc +++ b/lib/xray/xray_profiling.cc @@ -19,7 +19,6 @@ #include "sanitizer_common/sanitizer_flags.h" #include "xray/xray_interface.h" #include "xray/xray_log_interface.h" - #include "xray_flags.h" #include "xray_profile_collector.h" #include "xray_profiling_flags.h" @@ -40,16 +39,30 @@ atomic_sint32_t ProfilerLogStatus = {XRayLogInitStatus::XRAY_LOG_UNINITIALIZED}; SpinMutex ProfilerOptionsMutex; struct alignas(64) ProfilingData { - FunctionCallTrie::Allocators *Allocators = nullptr; - FunctionCallTrie *FCT = nullptr; + FunctionCallTrie::Allocators *Allocators; + FunctionCallTrie *FCT; }; static pthread_key_t ProfilingKey; +thread_local std::aligned_storage<sizeof(FunctionCallTrie::Allocators)>::type + AllocatorsStorage; +thread_local std::aligned_storage<sizeof(FunctionCallTrie)>::type + FunctionCallTrieStorage; thread_local std::aligned_storage<sizeof(ProfilingData)>::type ThreadStorage{}; + static ProfilingData &getThreadLocalData() XRAY_NEVER_INSTRUMENT { thread_local auto ThreadOnce = [] { new (&ThreadStorage) ProfilingData{}; + auto *Allocators = + reinterpret_cast<FunctionCallTrie::Allocators *>(&AllocatorsStorage); + new (Allocators) FunctionCallTrie::Allocators(); + *Allocators = FunctionCallTrie::InitAllocators(); + auto *FCT = reinterpret_cast<FunctionCallTrie *>(&FunctionCallTrieStorage); + new (FCT) FunctionCallTrie(*Allocators); + auto &TLD = *reinterpret_cast<ProfilingData *>(&ThreadStorage); + TLD.Allocators = Allocators; + TLD.FCT = FCT; pthread_setspecific(ProfilingKey, &ThreadStorage); return false; }(); @@ -57,25 +70,18 @@ static ProfilingData &getThreadLocalData() XRAY_NEVER_INSTRUMENT { auto &TLD = *reinterpret_cast<ProfilingData *>(&ThreadStorage); - // We need to check whether the global flag to finalizing/finalized has been - // switched. If it is, then we ought to not actually initialise the data. - auto Status = atomic_load(&ProfilerLogStatus, memory_order_acquire); - if (Status == XRayLogInitStatus::XRAY_LOG_FINALIZING || - Status == XRayLogInitStatus::XRAY_LOG_FINALIZED) - return TLD; - - // If we're live, then we re-initialize TLD if the pointers are not null. - if (UNLIKELY(TLD.Allocators == nullptr && TLD.FCT == nullptr)) { - TLD.Allocators = reinterpret_cast<FunctionCallTrie::Allocators *>( - InternalAlloc(sizeof(FunctionCallTrie::Allocators))); - new (TLD.Allocators) FunctionCallTrie::Allocators(); - *TLD.Allocators = FunctionCallTrie::InitAllocators(); - TLD.FCT = reinterpret_cast<FunctionCallTrie *>( - InternalAlloc(sizeof(FunctionCallTrie))); - new (TLD.FCT) FunctionCallTrie(*TLD.Allocators); + if (UNLIKELY(TLD.Allocators == nullptr || TLD.FCT == nullptr)) { + auto *Allocators = + reinterpret_cast<FunctionCallTrie::Allocators *>(&AllocatorsStorage); + new (Allocators) FunctionCallTrie::Allocators(); + *Allocators = FunctionCallTrie::InitAllocators(); + auto *FCT = reinterpret_cast<FunctionCallTrie *>(&FunctionCallTrieStorage); + new (FCT) FunctionCallTrie(*Allocators); + TLD.Allocators = Allocators; + TLD.FCT = FCT; } - return TLD; + return *reinterpret_cast<ProfilingData *>(&ThreadStorage); } static void cleanupTLD() XRAY_NEVER_INSTRUMENT { @@ -83,8 +89,6 @@ static void cleanupTLD() XRAY_NEVER_INSTRUMENT { if (TLD.Allocators != nullptr && TLD.FCT != nullptr) { TLD.FCT->~FunctionCallTrie(); TLD.Allocators->~Allocators(); - InternalFree(TLD.FCT); - InternalFree(TLD.Allocators); TLD.FCT = nullptr; TLD.Allocators = nullptr; } @@ -162,11 +166,13 @@ namespace { thread_local atomic_uint8_t ReentranceGuard{0}; -static void postCurrentThreadFCT(ProfilingData &TLD) { +static void postCurrentThreadFCT(ProfilingData &TLD) XRAY_NEVER_INSTRUMENT { if (TLD.Allocators == nullptr || TLD.FCT == nullptr) return; - profileCollectorService::post(*TLD.FCT, GetTid()); + if (!TLD.FCT->getRoots().empty()) + profileCollectorService::post(*TLD.FCT, GetTid()); + cleanupTLD(); } @@ -181,13 +187,14 @@ void profilingHandleArg0(int32_t FuncId, return; auto Status = atomic_load(&ProfilerLogStatus, memory_order_acquire); - auto &TLD = getThreadLocalData(); if (UNLIKELY(Status == XRayLogInitStatus::XRAY_LOG_FINALIZED || Status == XRayLogInitStatus::XRAY_LOG_FINALIZING)) { + auto &TLD = getThreadLocalData(); postCurrentThreadFCT(TLD); return; } + auto &TLD = getThreadLocalData(); switch (Entry) { case XRayEntryType::ENTRY: case XRayEntryType::LOG_ARGS_ENTRY: @@ -235,15 +242,8 @@ XRayLogInitStatus profilingFinalize() XRAY_NEVER_INSTRUMENT { } XRayLogInitStatus -profilingLoggingInit(size_t BufferSize, size_t BufferMax, void *Options, - size_t OptionsSize) XRAY_NEVER_INSTRUMENT { - if (BufferSize != 0 || BufferMax != 0) { - if (Verbosity()) - Report("__xray_log_init() being used, and is unsupported. Use " - "__xray_log_init_mode(...) instead. Bailing out."); - return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; - } - +profilingLoggingInit(UNUSED size_t BufferSize, UNUSED size_t BufferMax, + void *Options, size_t OptionsSize) XRAY_NEVER_INSTRUMENT { s32 CurrentStatus = XRayLogInitStatus::XRAY_LOG_UNINITIALIZED; if (!atomic_compare_exchange_strong(&ProfilerLogStatus, &CurrentStatus, XRayLogInitStatus::XRAY_LOG_INITIALIZING, |