summaryrefslogtreecommitdiff
path: root/lib/xray/xray_profiling.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xray/xray_profiling.cc')
-rw-r--r--lib/xray/xray_profiling.cc68
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,