summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2017-08-02 04:51:40 +0000
committerDean Michael Berris <dberris@google.com>2017-08-02 04:51:40 +0000
commitcd6d69c22ec4b19475b51fa7a677954b9da1ddb3 (patch)
tree97b704d1660bc0277509cbce7dcbd17f8af2203d
parent73ea55e16c3724f1ea0caa30a34aad7427dd36f7 (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@309792 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/xray/xray_records.h2
-rw-r--r--lib/xray/xray_fdr_logging.cc20
-rw-r--r--lib/xray/xray_fdr_logging_impl.h35
-rw-r--r--lib/xray/xray_inmemory_log.cc10
4 files changed, 38 insertions, 29 deletions
diff --git a/include/xray/xray_records.h b/include/xray/xray_records.h
index feb8d228b..506755dbd 100644
--- a/include/xray/xray_records.h
+++ b/include/xray/xray_records.h
@@ -17,6 +17,8 @@
#ifndef XRAY_XRAY_RECORDS_H
#define XRAY_XRAY_RECORDS_H
+#include <cstdint>
+
namespace __xray {
enum FileTypes {
diff --git a/lib/xray/xray_fdr_logging.cc b/lib/xray/xray_fdr_logging.cc
index a7e1382c3..21a09bf12 100644
--- a/lib/xray/xray_fdr_logging.cc
+++ b/lib/xray/xray_fdr_logging.cc
@@ -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() XRAY_NEVER_INSTRUMENT {
// 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() XRAY_NEVER_INSTRUMENT {
// 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_NEVER_INSTRUMENT {
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 *Event,
(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::size_t BufferSize, std::size_t BufferMax,
}
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;
diff --git a/lib/xray/xray_fdr_logging_impl.h b/lib/xray/xray_fdr_logging_impl.h
index 4a1d80fd0..ce4f6cd53 100644
--- a/lib/xray/xray_fdr_logging_impl.h
+++ b/lib/xray/xray_fdr_logging_impl.h
@@ -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 TSC, uint64_t &LastTSC,
}
}
-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_clock_reader)(clockid_t,
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_clock_reader)(clockid_t,
}
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_INSTRUMENT {
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;
}
diff --git a/lib/xray/xray_inmemory_log.cc b/lib/xray/xray_inmemory_log.cc
index 83aecfaf7..2f407e2a3 100644
--- a/lib/xray/xray_inmemory_log.cc
+++ b/lib/xray/xray_inmemory_log.cc
@@ -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 FuncId,
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 FuncId, XRayEntryType Type,
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));