summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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));