[compiler-rt] r344578 - [XRay] Encapsulate all FD log related logic into a class

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 15 18:24:47 PDT 2018


Author: phosek
Date: Mon Oct 15 18:24:46 2018
New Revision: 344578

URL: http://llvm.org/viewvc/llvm-project?rev=344578&view=rev
Log:
[XRay] Encapsulate all FD log related logic into a class

This abstracts away the file descriptor related logic which makes it
easier to port XRay to platform that don't use file descriptors or
file system for writing the log data, such as Fuchsia.

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

Modified:
    compiler-rt/trunk/lib/xray/xray_basic_logging.cc
    compiler-rt/trunk/lib/xray/xray_fdr_logging.cc
    compiler-rt/trunk/lib/xray/xray_profiling.cc
    compiler-rt/trunk/lib/xray/xray_utils.cc
    compiler-rt/trunk/lib/xray/xray_utils.h

Modified: compiler-rt/trunk/lib/xray/xray_basic_logging.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_basic_logging.cc?rev=344578&r1=344577&r2=344578&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_basic_logging.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_basic_logging.cc Mon Oct 15 18:24:46 2018
@@ -60,7 +60,7 @@ struct alignas(64) ThreadLocalData {
   void *ShadowStack = nullptr;
   size_t StackSize = 0;
   size_t StackEntries = 0;
-  int Fd = -1;
+  LogWriter *LogWriter = nullptr;
 };
 
 struct BasicLoggingOptions {
@@ -83,10 +83,10 @@ static atomic_uint64_t ThresholdTicks{0}
 static atomic_uint64_t TicksPerSec{0};
 static atomic_uint64_t CycleFrequency{NanosecondsPerSecond};
 
-static int openLogFile() XRAY_NEVER_INSTRUMENT {
-  int F = getLogFD();
-  if (F == -1)
-    return -1;
+static LogWriter *getLog() XRAY_NEVER_INSTRUMENT {
+  LogWriter* LW = LogWriter::Open();
+  if (LW == nullptr)
+    return LW;
 
   static pthread_once_t DetectOnce = PTHREAD_ONCE_INIT;
   pthread_once(&DetectOnce, +[] {
@@ -108,16 +108,16 @@ static int openLogFile() XRAY_NEVER_INST
   // before setting the values in the header.
   Header.ConstantTSC = 1;
   Header.NonstopTSC = 1;
-  retryingWriteAll(F, reinterpret_cast<char *>(&Header),
-                   reinterpret_cast<char *>(&Header) + sizeof(Header));
-  return F;
+  LW->WriteAll(reinterpret_cast<char *>(&Header),
+               reinterpret_cast<char *>(&Header) + sizeof(Header));
+  return LW;
 }
 
-static int getGlobalFd() XRAY_NEVER_INSTRUMENT {
+static LogWriter *getGlobalLog() XRAY_NEVER_INSTRUMENT {
   static pthread_once_t OnceInit = PTHREAD_ONCE_INIT;
-  static int Fd = 0;
-  pthread_once(&OnceInit, +[] { Fd = openLogFile(); });
-  return Fd;
+  static LogWriter *LW = nullptr;
+  pthread_once(&OnceInit, +[] { LW = getLog(); });
+  return LW;
 }
 
 static ThreadLocalData &getThreadLocalData() XRAY_NEVER_INSTRUMENT {
@@ -129,7 +129,7 @@ static ThreadLocalData &getThreadLocalDa
       return false;
     }
     pthread_setspecific(PThreadKey, &TLD);
-    TLD.Fd = getGlobalFd();
+    TLD.LogWriter = getGlobalLog();
     TLD.InMemoryBuffer = reinterpret_cast<XRayRecord *>(
         InternalAlloc(sizeof(XRayRecord) * GlobalOptions.ThreadBufferSize,
                       nullptr, alignof(XRayRecord)));
@@ -157,8 +157,8 @@ template <class RDTSC>
 void InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
                     RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
   auto &TLD = getThreadLocalData();
-  int Fd = getGlobalFd();
-  if (Fd == -1)
+  LogWriter *LW = getGlobalLog();
+  if (LW == nullptr)
     return;
 
   // Use a simple recursion guard, to handle cases where we're already logging
@@ -242,9 +242,9 @@ void InMemoryRawLog(int32_t FuncId, XRay
   auto FirstEntry = reinterpret_cast<XRayRecord *>(TLD.InMemoryBuffer);
   internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
   if (++TLD.BufferOffset == TLD.BufferSize) {
-    SpinMutexLock L(&LogMutex);
-    retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
-                     reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+    SpinMutexLock Lock(&LogMutex);
+    LW->WriteAll(reinterpret_cast<char *>(FirstEntry),
+                 reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
     TLD.BufferOffset = 0;
     TLD.StackEntries = 0;
   }
@@ -257,17 +257,17 @@ void InMemoryRawLogWithArg(int32_t FuncI
   auto FirstEntry =
       reinterpret_cast<XRayArgPayload *>(TLD.InMemoryBuffer);
   const auto &BuffLen = TLD.BufferSize;
-  int Fd = getGlobalFd();
-  if (Fd == -1)
+  LogWriter *LW = getGlobalLog();
+  if (LW == nullptr)
     return;
 
   // First we check whether there's enough space to write the data consecutively
   // in the thread-local buffer. If not, we first flush the buffer before
   // attempting to write the two records that must be consecutive.
   if (TLD.BufferOffset + 2 > BuffLen) {
-    SpinMutexLock L(&LogMutex);
-    retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
-                     reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+    SpinMutexLock Lock(&LogMutex);
+    LW->WriteAll(reinterpret_cast<char *>(FirstEntry),
+                 reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
     TLD.BufferOffset = 0;
     TLD.StackEntries = 0;
   }
@@ -288,9 +288,9 @@ void InMemoryRawLogWithArg(int32_t FuncI
   R.Arg = Arg1;
   internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
   if (++TLD.BufferOffset == BuffLen) {
-    SpinMutexLock L(&LogMutex);
-    retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
-                     reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+    SpinMutexLock Lock(&LogMutex);
+    LW->WriteAll(reinterpret_cast<char *>(FirstEntry),
+                 reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
     TLD.BufferOffset = 0;
     TLD.StackEntries = 0;
   }
@@ -347,25 +347,25 @@ static void TLDDestructor(void *P) XRAY_
       Report("Cleaned up log for TID: %d\n", GetTid());
   });
 
-  if (TLD.Fd == -1 || TLD.BufferOffset == 0) {
+  if (TLD.LogWriter == nullptr || TLD.BufferOffset == 0) {
     if (Verbosity())
-      Report("Skipping buffer for TID: %d; Fd = %d; Offset = %llu\n", GetTid(),
-             TLD.Fd, TLD.BufferOffset);
+      Report("Skipping buffer for TID: %d; Offset = %llu\n", GetTid(),
+             TLD.BufferOffset);
     return;
   }
 
   {
     SpinMutexLock L(&LogMutex);
-    retryingWriteAll(TLD.Fd, reinterpret_cast<char *>(TLD.InMemoryBuffer),
-                     reinterpret_cast<char *>(TLD.InMemoryBuffer) +
-                         (sizeof(XRayRecord) * TLD.BufferOffset));
+    TLD.LogWriter->WriteAll(reinterpret_cast<char *>(TLD.InMemoryBuffer),
+                            reinterpret_cast<char *>(TLD.InMemoryBuffer) +
+                            (sizeof(XRayRecord) * TLD.BufferOffset));
   }
 
   // Because this thread's exit could be the last one trying to write to
   // the file and that we're not able to close out the file properly, we
   // sync instead and hope that the pending writes are flushed as the
   // thread exits.
-  fsync(TLD.Fd);
+  TLD.LogWriter->Flush();
 }
 
 XRayLogInitStatus basicLoggingInit(UNUSED size_t BufferSize,

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=344578&r1=344577&r2=344578&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_fdr_logging.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_fdr_logging.cc Mon Oct 15 18:24:46 2018
@@ -838,8 +838,8 @@ XRayLogFlushStatus fdrLoggingFlush() XRA
   //      (fixed-sized) and let the tools reading the buffers deal with the data
   //      afterwards.
   //
-  int Fd = getLogFD();
-  if (Fd == -1) {
+  LogWriter* LW = LogWriter::Open();
+  if (LW == nullptr) {
     auto Result = XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
     atomic_store(&LogFlushStatus, Result, memory_order_release);
     return Result;
@@ -847,8 +847,8 @@ XRayLogFlushStatus fdrLoggingFlush() XRA
 
   XRayFileHeader Header = fdrCommonHeaderInfo();
   Header.FdrData = FdrAdditionalHeaderData{BQ->ConfiguredBufferSize()};
-  retryingWriteAll(Fd, reinterpret_cast<char *>(&Header),
-                   reinterpret_cast<char *>(&Header) + sizeof(Header));
+  LW->WriteAll(reinterpret_cast<char *>(&Header),
+               reinterpret_cast<char *>(&Header) + sizeof(Header));
 
   // Release the current thread's buffer before we attempt to write out all the
   // buffers. This ensures that in case we had only a single thread going, that
@@ -871,11 +871,11 @@ XRayLogFlushStatus fdrLoggingFlush() XRA
         uint8_t(MetadataRecord::RecordKinds::BufferExtents);
     internal_memcpy(ExtentsRecord.Data, &BufferExtents, sizeof(BufferExtents));
     if (BufferExtents > 0) {
-      retryingWriteAll(Fd, reinterpret_cast<char *>(&ExtentsRecord),
-                       reinterpret_cast<char *>(&ExtentsRecord) +
-                           sizeof(MetadataRecord));
-      retryingWriteAll(Fd, reinterpret_cast<char *>(B.Data),
-                       reinterpret_cast<char *>(B.Data) + BufferExtents);
+      LW->WriteAll(reinterpret_cast<char *>(&ExtentsRecord),
+                   reinterpret_cast<char *>(&ExtentsRecord) +
+                   sizeof(MetadataRecord));
+      LW->WriteAll(reinterpret_cast<char *>(B.Data),
+                   reinterpret_cast<char *>(B.Data) + BufferExtents);
     }
   });
 

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=344578&r1=344577&r2=344578&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_profiling.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_profiling.cc Mon Oct 15 18:24:46 2018
@@ -133,21 +133,20 @@ XRayLogFlushStatus profilingFlush() XRAY
       if (Verbosity())
         Report("profiling: No data to flush.\n");
     } else {
-      int Fd = getLogFD();
-      if (Fd == -1) {
+      LogWriter* LW = LogWriter::Open();
+      if (LW == nullptr) {
         if (Verbosity())
           Report("profiling: Failed to flush to file, dropping data.\n");
       } else {
         // Now for each of the buffers, write out the profile data as we would
         // see it in memory, verbatim.
         while (B.Data != nullptr && B.Size != 0) {
-          retryingWriteAll(Fd, reinterpret_cast<const char *>(B.Data),
-                           reinterpret_cast<const char *>(B.Data) + B.Size);
+          LW->WriteAll(reinterpret_cast<const char *>(B.Data),
+                       reinterpret_cast<const char *>(B.Data) + B.Size);
           B = profileCollectorService::nextBuffer(B);
         }
-        // Then we close out the file.
-        internal_close(Fd);
       }
+      LogWriter::Close(LW);
     }
   }
 

Modified: compiler-rt/trunk/lib/xray/xray_utils.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_utils.cc?rev=344578&r1=344577&r2=344578&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_utils.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_utils.cc Mon Oct 15 18:24:46 2018
@@ -12,7 +12,9 @@
 //===----------------------------------------------------------------------===//
 #include "xray_utils.h"
 
+#include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_common.h"
+#include "xray_allocator.h"
 #include "xray_defs.h"
 #include "xray_flags.h"
 #include <cstdio>
@@ -31,7 +33,11 @@ void printToStdErr(const char *Buffer) X
   fprintf(stderr, "%s", Buffer);
 }
 
-void retryingWriteAll(int Fd, const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
+LogWriter::~LogWriter() {
+  internal_close(Fd);
+}
+
+void LogWriter::WriteAll(const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
   if (Begin == End)
     return;
   auto TotalBytes = std::distance(Begin, End);
@@ -49,50 +55,11 @@ void retryingWriteAll(int Fd, const char
   }
 }
 
-std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin,
-                                          char *End) XRAY_NEVER_INSTRUMENT {
-  auto BytesToRead = std::distance(Begin, End);
-  ssize_t BytesRead;
-  ssize_t TotalBytesRead = 0;
-  while (BytesToRead && (BytesRead = read(Fd, Begin, BytesToRead))) {
-    if (BytesRead == -1) {
-      if (errno == EINTR)
-        continue;
-      Report("Read error; errno = %d\n", errno);
-      return std::make_pair(TotalBytesRead, false);
-    }
-
-    TotalBytesRead += BytesRead;
-    BytesToRead -= BytesRead;
-    Begin += BytesRead;
-  }
-  return std::make_pair(TotalBytesRead, true);
+void LogWriter::Flush() XRAY_NEVER_INSTRUMENT {
+  fsync(Fd);
 }
 
-bool readValueFromFile(const char *Filename,
-                       long long *Value) XRAY_NEVER_INSTRUMENT {
-  int Fd = open(Filename, O_RDONLY | O_CLOEXEC);
-  if (Fd == -1)
-    return false;
-  static constexpr size_t BufSize = 256;
-  char Line[BufSize] = {};
-  ssize_t BytesRead;
-  bool Success;
-  std::tie(BytesRead, Success) = retryingReadSome(Fd, Line, Line + BufSize);
-  if (!Success)
-    return false;
-  close(Fd);
-  const char *End = nullptr;
-  long long Tmp = internal_simple_strtoll(Line, &End, 10);
-  bool Result = false;
-  if (Line[0] != '\0' && (*End == '\n' || *End == '\0')) {
-    *Value = Tmp;
-    Result = true;
-  }
-  return Result;
-}
-
-int getLogFD() XRAY_NEVER_INSTRUMENT {
+LogWriter *LogWriter::Open() XRAY_NEVER_INSTRUMENT {
   // Open a temporary file once for the log.
   char TmpFilename[256] = {};
   char TmpWildcardPattern[] = "XXXXXX";
@@ -108,18 +75,25 @@ int getLogFD() XRAY_NEVER_INSTRUMENT {
       flags()->xray_logfile_base, Progname, TmpWildcardPattern);
   if (NeededLength > int(sizeof(TmpFilename))) {
     Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename);
-    return -1;
+    return nullptr;
   }
   int Fd = mkstemp(TmpFilename);
   if (Fd == -1) {
     Report("XRay: Failed opening temporary file '%s'; not logging events.\n",
            TmpFilename);
-    return -1;
+    return nullptr;
   }
   if (Verbosity())
     Report("XRay: Log file in '%s'\n", TmpFilename);
 
-  return Fd;
+  LogWriter *LW = allocate<LogWriter>();
+  new (LW) LogWriter(Fd);
+  return LW;
+}
+
+void LogWriter::Close(LogWriter *LW) {
+  LW->~LogWriter();
+  deallocate(LW);
 }
 
 } // namespace __xray

Modified: compiler-rt/trunk/lib/xray/xray_utils.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_utils.h?rev=344578&r1=344577&r2=344578&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_utils.h (original)
+++ compiler-rt/trunk/lib/xray/xray_utils.h Mon Oct 15 18:24:46 2018
@@ -22,22 +22,28 @@
 
 namespace __xray {
 
+class LogWriter {
+public:
+  explicit LogWriter(int Fd) : Fd(Fd) {}
+  ~LogWriter();
+
+  // Write a character range into a log.
+  void WriteAll(const char *Begin, const char *End);
+
+  void Flush();
+
+  // Returns a new log instance initialized using the flag-provided values.
+  static LogWriter *Open();
+  // Closes and deallocates the log instance.
+  static void Close(LogWriter *LogWriter);
+
+private:
+  int Fd = -1;
+};
+
 // Default implementation of the reporting interface for sanitizer errors.
 void printToStdErr(const char *Buffer);
 
-// EINTR-safe write routine, provided a file descriptor and a character range.
-void retryingWriteAll(int Fd, const char *Begin, const char *End);
-
-// Reads a long long value from a provided file.
-bool readValueFromFile(const char *Filename, long long *Value);
-
-// EINTR-safe read routine, providing a file descriptor and a character range.
-std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin, char *End);
-
-// EINTR-safe open routine, uses flag-provided values for initialising a log
-// file.
-int getLogFD();
-
 constexpr size_t gcd(size_t a, size_t b) {
   return (b == 0) ? a : gcd(b, a % b);
 }




More information about the llvm-commits mailing list