[compiler-rt] r309792 - [XRay][compiler-rt] Remove use of std::mutex and std::shared_ptr from global scope.

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 1 21:51:41 PDT 2017


Author: dberris
Date: Tue Aug  1 21:51:40 2017
New Revision: 309792

URL: http://llvm.org/viewvc/llvm-project?rev=309792&view=rev
Log:
[XRay][compiler-rt] Remove use of std::mutex and std::shared_ptr from global scope.

Summary:
This change attempts to remove all the dependencies we have on
std::mutex and any std::shared_ptr construction in global variables. We
instead use raw pointers to these objects, and construct them on the
heap. In cases where it's possible, we lazily initialize these pointers.

While we do not have a replacement for std::shared_ptr yet in
compiler-rt, we use this work-around to avoid having to statically
initialize the objects as globals. Subsequent changes should allow us to
completely remove our dependency on std::shared_ptr and instead have our
own implementation of the std::shared_ptr and std::weak_ptr semantics
(or completely rewrite the implementaton to not need these
standard-library provided abstractions).

Reviewers: dblaikie, kpw, pelikan

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D36078

Modified:
    compiler-rt/trunk/include/xray/xray_records.h
    compiler-rt/trunk/lib/xray/xray_fdr_logging.cc
    compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h
    compiler-rt/trunk/lib/xray/xray_inmemory_log.cc

Modified: compiler-rt/trunk/include/xray/xray_records.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/xray/xray_records.h?rev=309792&r1=309791&r2=309792&view=diff
==============================================================================
--- compiler-rt/trunk/include/xray/xray_records.h (original)
+++ compiler-rt/trunk/include/xray/xray_records.h Tue Aug  1 21:51:40 2017
@@ -17,6 +17,8 @@
 #ifndef XRAY_XRAY_RECORDS_H
 #define XRAY_XRAY_RECORDS_H
 
+#include <cstdint>
+
 namespace __xray {
 
 enum FileTypes {

Modified: compiler-rt/trunk/lib/xray/xray_fdr_logging.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_fdr_logging.cc?rev=309792&r1=309791&r2=309792&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_fdr_logging.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_fdr_logging.cc Tue Aug  1 21:51:40 2017
@@ -39,7 +39,10 @@
 namespace __xray {
 
 // Global BufferQueue.
-std::shared_ptr<BufferQueue> BQ;
+// NOTE: This is a pointer to avoid having to do atomic operations at
+// initialization time. This is OK to leak as there will only be one bufferqueue
+// for the runtime, initialized once through the fdrInit(...) sequence.
+std::shared_ptr<BufferQueue>* BQ = nullptr;
 
 __sanitizer::atomic_sint32_t LogFlushStatus = {
     XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING};
@@ -64,7 +67,7 @@ XRayLogFlushStatus fdrLoggingFlush() XRA
   // Make a copy of the BufferQueue pointer to prevent other threads that may be
   // resetting it from blowing away the queue prematurely while we're dealing
   // with it.
-  auto LocalBQ = BQ;
+  auto LocalBQ = *BQ;
 
   // We write out the file in the following format:
   //
@@ -129,7 +132,7 @@ XRayLogInitStatus fdrLoggingFinalize() X
 
   // Do special things to make the log finalize itself, and not allow any more
   // operations to be performed until re-initialized.
-  BQ->finalize();
+  (*BQ)->finalize();
 
   __sanitizer::atomic_store(&LoggingStatus,
                             XRayLogInitStatus::XRAY_LOG_FINALIZED,
@@ -146,7 +149,7 @@ XRayLogInitStatus fdrLoggingReset() XRAY
     return static_cast<XRayLogInitStatus>(CurrentStatus);
 
   // Release the in-memory buffer queue.
-  BQ.reset();
+  BQ->reset();
 
   // Spin until the flushing status is flushed.
   s32 CurrentFlushingStatus = XRayLogFlushStatus::XRAY_LOG_FLUSHED;
@@ -195,7 +198,7 @@ void fdrLoggingHandleArg0(int32_t FuncId
   auto TSC_CPU = getTimestamp();
   __xray_fdr_internal::processFunctionHook(FuncId, Entry, std::get<0>(TSC_CPU),
                                            std::get<1>(TSC_CPU), clock_gettime,
-                                           LoggingStatus, BQ);
+                                           LoggingStatus, *BQ);
 }
 
 void fdrLoggingHandleCustomEvent(void *Event,
@@ -220,7 +223,7 @@ void fdrLoggingHandleCustomEvent(void *E
     (void)Once;
   }
   int32_t ReducedEventSize = static_cast<int32_t>(EventSize);
-  if (!isLogInitializedAndReady(LocalBQ, TSC, CPU, clock_gettime))
+  if (!isLogInitializedAndReady(*LocalBQ, TSC, CPU, clock_gettime))
     return;
 
   // Here we need to prepare the log to handle:
@@ -268,7 +271,10 @@ XRayLogInitStatus fdrLoggingInit(std::si
   }
 
   bool Success = false;
-  BQ = std::make_shared<BufferQueue>(BufferSize, BufferMax, Success);
+  if (BQ == nullptr)
+    BQ = new std::shared_ptr<BufferQueue>();
+
+  *BQ = std::make_shared<BufferQueue>(BufferSize, BufferMax, Success);
   if (!Success) {
     Report("BufferQueue init failed.\n");
     return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

Modified: compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h?rev=309792&r1=309791&r2=309792&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h (original)
+++ compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h Tue Aug  1 21:51:40 2017
@@ -169,8 +169,9 @@ public:
 // Make sure a thread that's ever called handleArg0 has a thread-local
 // live reference to the buffer queue for this particular instance of
 // FDRLogging, and that we're going to clean it up when the thread exits.
-thread_local std::shared_ptr<BufferQueue> LocalBQ = nullptr;
-thread_local ThreadExitBufferCleanup Cleanup(LocalBQ, Buffer);
+thread_local std::shared_ptr<BufferQueue>* LocalBQ =
+    new std::shared_ptr<BufferQueue>();
+thread_local ThreadExitBufferCleanup Cleanup(*LocalBQ, Buffer);
 
 class RecursionGuard {
   bool &Running;
@@ -451,8 +452,8 @@ static void rewindRecentCall(uint64_t TS
   }
 }
 
-inline bool releaseThreadLocalBuffer(BufferQueue *BQ) {
-  auto EC = BQ->releaseBuffer(Buffer);
+inline bool releaseThreadLocalBuffer(BufferQueue &BQArg) {
+  auto EC = BQArg.releaseBuffer(Buffer);
   if (EC != BufferQueue::ErrorCode::Ok) {
     Report("Failed to release buffer at %p; error=%s\n", Buffer.Buffer,
            BufferQueue::getErrorString(EC));
@@ -467,9 +468,9 @@ inline bool prepareBuffer(int (*wall_clo
   char *BufferStart = static_cast<char *>(Buffer.Buffer);
   if ((RecordPtr + MaxSize) > (BufferStart + Buffer.Size - MetadataRecSize)) {
     writeEOBMetadata();
-    if (!releaseThreadLocalBuffer(LocalBQ.get()))
+    if (!releaseThreadLocalBuffer(**LocalBQ))
       return false;
-    auto EC = LocalBQ->getBuffer(Buffer);
+    auto EC = (*LocalBQ)->getBuffer(Buffer);
     if (EC != BufferQueue::ErrorCode::Ok) {
       Report("Failed to acquire a buffer; error=%s\n",
              BufferQueue::getErrorString(EC));
@@ -481,7 +482,7 @@ inline bool prepareBuffer(int (*wall_clo
 }
 
 inline bool isLogInitializedAndReady(
-    std::shared_ptr<BufferQueue> &LocalBQ, uint64_t TSC, unsigned char CPU,
+    std::shared_ptr<BufferQueue> &LBQ, uint64_t TSC, unsigned char CPU,
     int (*wall_clock_reader)(clockid_t,
                              struct timespec *)) XRAY_NEVER_INSTRUMENT {
   // Bail out right away if logging is not initialized yet.
@@ -493,24 +494,24 @@ inline bool isLogInitializedAndReady(
         (Status == XRayLogInitStatus::XRAY_LOG_FINALIZING ||
          Status == XRayLogInitStatus::XRAY_LOG_FINALIZED)) {
       writeEOBMetadata();
-      if (!releaseThreadLocalBuffer(LocalBQ.get()))
+      if (!releaseThreadLocalBuffer(*LBQ))
         return false;
       RecordPtr = nullptr;
-      LocalBQ = nullptr;
+      LBQ = nullptr;
       return false;
     }
     return false;
   }
 
-  if (!loggingInitialized(LoggingStatus) || LocalBQ->finalizing()) {
+  if (!loggingInitialized(LoggingStatus) || LBQ->finalizing()) {
     writeEOBMetadata();
-    if (!releaseThreadLocalBuffer(LocalBQ.get()))
+    if (!releaseThreadLocalBuffer(*LBQ))
       return false;
     RecordPtr = nullptr;
   }
 
   if (Buffer.Buffer == nullptr) {
-    auto EC = LocalBQ->getBuffer(Buffer);
+    auto EC = LBQ->getBuffer(Buffer);
     if (EC != BufferQueue::ErrorCode::Ok) {
       auto LS = __sanitizer::atomic_load(&LoggingStatus,
                                          __sanitizer::memory_order_acquire);
@@ -538,7 +539,7 @@ inline void endBufferIfFull() XRAY_NEVER
   auto BufferStart = static_cast<char *>(Buffer.Buffer);
   if ((RecordPtr + MetadataRecSize) - BufferStart == MetadataRecSize) {
     writeEOBMetadata();
-    if (!releaseThreadLocalBuffer(LocalBQ.get()))
+    if (!releaseThreadLocalBuffer(**LocalBQ))
       return;
     RecordPtr = nullptr;
   }
@@ -563,10 +564,10 @@ inline void processFunctionHook(
 
   // In case the reference has been cleaned up before, we make sure we
   // initialize it to the provided BufferQueue.
-  if (LocalBQ == nullptr)
-    LocalBQ = BQ;
+  if ((*LocalBQ) == nullptr)
+    *LocalBQ = BQ;
 
-  if (!isLogInitializedAndReady(LocalBQ, TSC, CPU, wall_clock_reader))
+  if (!isLogInitializedAndReady(*LocalBQ, TSC, CPU, wall_clock_reader))
     return;
 
   // Before we go setting up writing new function entries, we need to be really
@@ -606,7 +607,7 @@ inline void processFunctionHook(
   // Buffer, set it up properly before doing any further writing.
   //
   if (!prepareBuffer(wall_clock_reader, FunctionRecSize + MetadataRecSize)) {
-    LocalBQ = nullptr;
+    *LocalBQ = nullptr;
     return;
   }
 

Modified: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_inmemory_log.cc?rev=309792&r1=309791&r2=309792&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc Tue Aug  1 21:51:40 2017
@@ -16,12 +16,12 @@
 //===----------------------------------------------------------------------===//
 
 #include <cassert>
+#include <errno.h>
 #include <fcntl.h>
-#include <mutex>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
-#include <thread>
+#include <time.h>
 #include <unistd.h>
 
 #include "sanitizer_common/sanitizer_libc.h"
@@ -43,7 +43,7 @@ void __xray_InMemoryRawLog(int32_t FuncI
 
 namespace __xray {
 
-std::mutex LogMutex;
+__sanitizer::SpinMutex LogMutex;
 
 class ThreadExitFlusher {
   int Fd;
@@ -58,7 +58,7 @@ public:
         Offset(Offset) {}
 
   ~ThreadExitFlusher() XRAY_NEVER_INSTRUMENT {
-    std::lock_guard<std::mutex> L(LogMutex);
+    __sanitizer::SpinMutexLock L(&LogMutex);
     if (Fd > 0 && Start != nullptr) {
       retryingWriteAll(Fd, reinterpret_cast<char *>(Start),
                        reinterpret_cast<char *>(Start + Offset));
@@ -127,7 +127,7 @@ void __xray_InMemoryRawLog(int32_t FuncI
   R.FuncId = FuncId;
   ++Offset;
   if (Offset == BuffLen) {
-    std::lock_guard<std::mutex> L(LogMutex);
+    __sanitizer::SpinMutexLock L(&LogMutex);
     auto RecordBuffer = reinterpret_cast<__xray::XRayRecord *>(InMemoryBuffer);
     retryingWriteAll(Fd, reinterpret_cast<char *>(RecordBuffer),
                      reinterpret_cast<char *>(RecordBuffer + Offset));




More information about the llvm-commits mailing list