[compiler-rt] r336969 - [XRay][compiler-rt] Profiling Mode: Flush logs on exit
Dean Michael Berris via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 12 21:04:18 PDT 2018
Author: dberris
Date: Thu Jul 12 21:04:18 2018
New Revision: 336969
URL: http://llvm.org/viewvc/llvm-project?rev=336969&view=rev
Log:
[XRay][compiler-rt] Profiling Mode: Flush logs on exit
Summary:
This change adds support for writing out profiles at program exit.
Depends on D48653.
Reviewers: kpw, eizan
Reviewed By: kpw
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D48956
Modified:
compiler-rt/trunk/lib/xray/xray_profile_collector.cc
compiler-rt/trunk/lib/xray/xray_profiling.cc
compiler-rt/trunk/lib/xray/xray_profiling_flags.inc
compiler-rt/trunk/test/xray/TestCases/Posix/profiling-multi-threaded.cc
compiler-rt/trunk/test/xray/TestCases/Posix/profiling-single-threaded.cc
Modified: compiler-rt/trunk/lib/xray/xray_profile_collector.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_profile_collector.cc?rev=336969&r1=336968&r2=336969&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_profile_collector.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_profile_collector.cc Thu Jul 12 21:04:18 2018
@@ -30,13 +30,11 @@ struct ThreadTrie {
tid_t TId;
FunctionCallTrie *Trie;
};
-Vector<ThreadTrie> ThreadTries;
struct ProfileBuffer {
void *Data;
size_t Size;
};
-Vector<ProfileBuffer> ProfileBuffers;
struct BlockHeader {
u32 BlockSize;
@@ -44,6 +42,10 @@ struct BlockHeader {
u64 ThreadId;
};
+// These need to be pointers that point to heap/internal-allocator-allocated
+// objects because these are accessed even at program exit.
+Vector<ThreadTrie> *ThreadTries = nullptr;
+Vector<ProfileBuffer> *ProfileBuffers = nullptr;
FunctionCallTrie::Allocators *GlobalAllocators = nullptr;
} // namespace
@@ -57,8 +59,16 @@ void post(const FunctionCallTrie &T, tid
new (GlobalAllocators) FunctionCallTrie::Allocators();
*GlobalAllocators = FunctionCallTrie::InitAllocatorsCustom(
profilingFlags()->global_allocator_max);
+ ThreadTries = reinterpret_cast<Vector<ThreadTrie> *>(
+ InternalAlloc(sizeof(Vector<ThreadTrie>)));
+ new (ThreadTries) Vector<ThreadTrie>();
+ ProfileBuffers = reinterpret_cast<Vector<ProfileBuffer> *>(
+ InternalAlloc(sizeof(Vector<ProfileBuffer>)));
+ new (ProfileBuffers) Vector<ProfileBuffer>();
});
DCHECK_NE(GlobalAllocators, nullptr);
+ DCHECK_NE(ThreadTries, nullptr);
+ DCHECK_NE(ProfileBuffers, nullptr);
ThreadTrie *Item = nullptr;
{
@@ -66,7 +76,7 @@ void post(const FunctionCallTrie &T, tid
if (GlobalAllocators == nullptr)
return;
- Item = ThreadTries.PushBack();
+ Item = ThreadTries->PushBack();
Item->TId = TId;
// Here we're using the internal allocator instead of the managed allocator
@@ -188,15 +198,15 @@ void serialize() {
SpinMutexLock Lock(&GlobalMutex);
// Clear out the global ProfileBuffers.
- for (uptr I = 0; I < ProfileBuffers.Size(); ++I)
- InternalFree(ProfileBuffers[I].Data);
- ProfileBuffers.Reset();
+ for (uptr I = 0; I < ProfileBuffers->Size(); ++I)
+ InternalFree((*ProfileBuffers)[I].Data);
+ ProfileBuffers->Reset();
- if (ThreadTries.Size() == 0)
+ if (ThreadTries->Size() == 0)
return;
// Then repopulate the global ProfileBuffers.
- for (u32 I = 0; I < ThreadTries.Size(); ++I) {
+ for (u32 I = 0; I < ThreadTries->Size(); ++I) {
using ProfileRecordAllocator = typename ProfileRecordArray::AllocatorType;
ProfileRecordAllocator PRAlloc(profilingFlags()->global_allocator_max, 0);
ProfileRecord::PathAllocator PathAlloc(
@@ -207,7 +217,7 @@ void serialize() {
// use a local allocator and an __xray::Array<...> to store the intermediary
// data, then compute the size as we're going along. Then we'll allocate the
// contiguous space to contain the thread buffer data.
- const auto &Trie = *ThreadTries[I].Trie;
+ const auto &Trie = *(*ThreadTries)[I].Trie;
if (Trie.getRoots().empty())
continue;
populateRecords(ProfileRecords, PathAlloc, Trie);
@@ -227,8 +237,8 @@ void serialize() {
for (const auto &Record : ProfileRecords)
CumulativeSizes += 20 + (4 * Record.Path->size());
- BlockHeader Header{16 + CumulativeSizes, I, ThreadTries[I].TId};
- auto Buffer = ProfileBuffers.PushBack();
+ BlockHeader Header{16 + CumulativeSizes, I, (*ThreadTries)[I].TId};
+ auto Buffer = ProfileBuffers->PushBack();
Buffer->Size = sizeof(Header) + CumulativeSizes;
Buffer->Data = InternalAlloc(Buffer->Size, nullptr, 64);
DCHECK_NE(Buffer->Data, nullptr);
@@ -244,18 +254,26 @@ void serialize() {
void reset() {
SpinMutexLock Lock(&GlobalMutex);
- // Clear out the profile buffers that have been serialized.
- for (uptr I = 0; I < ProfileBuffers.Size(); ++I)
- InternalFree(ProfileBuffers[I].Data);
- ProfileBuffers.Reset();
-
- // Clear out the function call tries per thread.
- for (uptr I = 0; I < ThreadTries.Size(); ++I) {
- auto &T = ThreadTries[I];
- T.Trie->~FunctionCallTrie();
- InternalFree(T.Trie);
+ if (ProfileBuffers != nullptr) {
+ // Clear out the profile buffers that have been serialized.
+ for (uptr I = 0; I < ProfileBuffers->Size(); ++I)
+ InternalFree((*ProfileBuffers)[I].Data);
+ ProfileBuffers->Reset();
+ InternalFree(ProfileBuffers);
+ ProfileBuffers = nullptr;
+ }
+
+ if (ThreadTries != nullptr) {
+ // Clear out the function call tries per thread.
+ for (uptr I = 0; I < ThreadTries->Size(); ++I) {
+ auto &T = (*ThreadTries)[I];
+ T.Trie->~FunctionCallTrie();
+ InternalFree(T.Trie);
+ }
+ ThreadTries->Reset();
+ InternalFree(ThreadTries);
+ ThreadTries = nullptr;
}
- ThreadTries.Reset();
// Reset the global allocators.
if (GlobalAllocators != nullptr) {
@@ -267,18 +285,29 @@ void reset() {
InternalAlloc(sizeof(FunctionCallTrie::Allocators)));
new (GlobalAllocators) FunctionCallTrie::Allocators();
*GlobalAllocators = FunctionCallTrie::InitAllocators();
+ ThreadTries = reinterpret_cast<Vector<ThreadTrie> *>(
+ InternalAlloc(sizeof(Vector<ThreadTrie>)));
+ new (ThreadTries) Vector<ThreadTrie>();
+ ProfileBuffers = reinterpret_cast<Vector<ProfileBuffer> *>(
+ InternalAlloc(sizeof(Vector<ProfileBuffer>)));
+ new (ProfileBuffers) Vector<ProfileBuffer>();
}
XRayBuffer nextBuffer(XRayBuffer B) {
SpinMutexLock Lock(&GlobalMutex);
- if (B.Data == nullptr && ProfileBuffers.Size())
- return {ProfileBuffers[0].Data, ProfileBuffers[0].Size};
+
+ if (ProfileBuffers == nullptr || ProfileBuffers->Size() == 0)
+ return {nullptr, 0};
+
+ if (B.Data == nullptr)
+ return {(*ProfileBuffers)[0].Data, (*ProfileBuffers)[0].Size};
BlockHeader Header;
internal_memcpy(&Header, B.Data, sizeof(BlockHeader));
auto NextBlock = Header.BlockNum + 1;
- if (NextBlock < ProfileBuffers.Size())
- return {ProfileBuffers[NextBlock].Data, ProfileBuffers[NextBlock].Size};
+ if (NextBlock < ProfileBuffers->Size())
+ return {(*ProfileBuffers)[NextBlock].Data,
+ (*ProfileBuffers)[NextBlock].Size};
return {nullptr, 0};
}
Modified: compiler-rt/trunk/lib/xray/xray_profiling.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_profiling.cc?rev=336969&r1=336968&r2=336969&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_profiling.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_profiling.cc Thu Jul 12 21:04:18 2018
@@ -277,7 +277,7 @@ profilingLoggingInit(size_t BufferSize,
// We need to reset the profile data collection implementation now.
profileCollectorService::reset();
- // We need to set up the at-thread-exit handler.
+ // We need to set up the exit handlers.
static pthread_once_t Once = PTHREAD_ONCE_INIT;
pthread_once(&Once, +[] {
pthread_key_create(&ProfilingKey, +[](void *P) {
@@ -288,6 +288,19 @@ profilingLoggingInit(size_t BufferSize,
postCurrentThreadFCT(TLD);
});
+
+ // We also need to set up an exit handler, so that we can get the profile
+ // information at exit time. We use the C API to do this, to not rely on C++
+ // ABI functions for registering exit handlers.
+ Atexit(+[] {
+ // Finalize and flush.
+ if (profilingFinalize() != XRAY_LOG_FINALIZED)
+ return;
+ if (profilingFlush() != XRAY_LOG_FLUSHED)
+ return;
+ if (Verbosity())
+ Report("XRay Profile flushed at exit.");
+ });
});
__xray_log_set_buffer_iterator(profileCollectorService::nextBuffer);
@@ -321,13 +334,16 @@ bool profilingDynamicInitializer() XRAY_
profilingFlush,
};
auto RegistrationResult = __xray_log_register_mode("xray-profiling", Impl);
- if (RegistrationResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK &&
- Verbosity())
- Report("Cannot register XRay Profiling mode to 'xray-profiling'; error = "
- "%d\n",
- RegistrationResult);
+ if (RegistrationResult != XRayLogRegisterStatus::XRAY_REGISTRATION_OK) {
+ if (Verbosity())
+ Report("Cannot register XRay Profiling mode to 'xray-profiling'; error = "
+ "%d\n",
+ RegistrationResult);
+ return false;
+ }
+
if (!internal_strcmp(flags()->xray_mode, "xray-profiling"))
- __xray_set_log_impl(Impl);
+ __xray_log_select_mode("xray_profiling");
return true;
}
Modified: compiler-rt/trunk/lib/xray/xray_profiling_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_profiling_flags.inc?rev=336969&r1=336968&r2=336969&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_profiling_flags.inc (original)
+++ compiler-rt/trunk/lib/xray/xray_profiling_flags.inc Thu Jul 12 21:04:18 2018
@@ -20,7 +20,7 @@ XRAY_FLAG(uptr, global_allocator_max, 2
"Maximum size of the global allocator for profile storage.")
XRAY_FLAG(uptr, stack_allocator_max, 2 << 24,
"Maximum size of the traversal stack allocator.")
-XRAY_FLAG(int, grace_period_ms, 100,
+XRAY_FLAG(int, grace_period_ms, 1,
"Profile collection will wait this much time in milliseconds before "
"resetting the global state. This gives a chance to threads to "
"notice that the profiler has been finalized and clean up.")
Modified: compiler-rt/trunk/test/xray/TestCases/Posix/profiling-multi-threaded.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Posix/profiling-multi-threaded.cc?rev=336969&r1=336968&r2=336969&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Posix/profiling-multi-threaded.cc (original)
+++ compiler-rt/trunk/test/xray/TestCases/Posix/profiling-multi-threaded.cc Thu Jul 12 21:04:18 2018
@@ -8,7 +8,7 @@
// RUN: XRAY_PROFILING_OPTIONS=no_flush=1 %run %t
// RUN: XRAY_OPTIONS=verbosity=1 %run %t
// RUN: PROFILES=`ls xray-log.profiling-multi-* | wc -l`
-// RUN: [ $PROFILES -eq 1 ]
+// RUN: [ $PROFILES -ge 1 ]
// RUN: rm -f xray-log.profiling-multi-*
//
// REQUIRES: x86_64-target-arch
Modified: compiler-rt/trunk/test/xray/TestCases/Posix/profiling-single-threaded.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Posix/profiling-single-threaded.cc?rev=336969&r1=336968&r2=336969&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Posix/profiling-single-threaded.cc (original)
+++ compiler-rt/trunk/test/xray/TestCases/Posix/profiling-single-threaded.cc Thu Jul 12 21:04:18 2018
@@ -8,7 +8,7 @@
// RUN: XRAY_PROFILING_OPTIONS=no_flush=true %run %t
// RUN: XRAY_OPTIONS=verbosity=1 %run %t
// RUN: PROFILES=`ls xray-log.profiling-single-* | wc -l`
-// RUN: [ $PROFILES -eq 2 ]
+// RUN: [ $PROFILES -ge 2 ]
// RUN: rm -f xray-log.profiling-single-*
//
// REQUIRES: x86_64-target-arch
More information about the llvm-commits
mailing list