[compiler-rt] 8a49e05 - tsan: inline ProcessPendingSignals check

Dmitry Vyukov via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 2 02:05:51 PDT 2021


Author: Dmitry Vyukov
Date: 2021-08-02T11:05:45+02:00
New Revision: 8a49e053caac1623b7f0d87b68d21fb6526cad43

URL: https://github.com/llvm/llvm-project/commit/8a49e053caac1623b7f0d87b68d21fb6526cad43
DIFF: https://github.com/llvm/llvm-project/commit/8a49e053caac1623b7f0d87b68d21fb6526cad43.diff

LOG: tsan: inline ProcessPendingSignals check

ProcessPendingSignals is called in all interceptors
and user atomic operations. Make the fast-path check
(no pending signals) inlinable.

Reviewed By: melver

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

Added: 
    

Modified: 
    compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
    compiler-rt/lib/tsan/rtl/tsan_rtl.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 34e5ac6e59c5..01d1c1512307 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -168,7 +168,6 @@ struct SignalDesc {
 struct ThreadSignalContext {
   int int_signal_send;
   atomic_uintptr_t in_blocking_func;
-  atomic_uintptr_t have_pending_signals;
   SignalDesc pending_signals[kSigCount];
   // emptyset and oldset are too big for stack.
   __sanitizer_sigset_t emptyset;
@@ -322,7 +321,7 @@ struct BlockingCall {
       , ctx(SigCtx(thr)) {
     for (;;) {
       atomic_store(&ctx->in_blocking_func, 1, memory_order_relaxed);
-      if (atomic_load(&ctx->have_pending_signals, memory_order_relaxed) == 0)
+      if (atomic_load(&thr->pending_signals, memory_order_relaxed) == 0)
         break;
       atomic_store(&ctx->in_blocking_func, 0, memory_order_relaxed);
       ProcessPendingSignals(thr);
@@ -1992,12 +1991,11 @@ static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire,
   errno = saved_errno;
 }
 
-void ProcessPendingSignals(ThreadState *thr) {
+void ProcessPendingSignalsImpl(ThreadState *thr) {
+  atomic_store(&thr->pending_signals, 0, memory_order_relaxed);
   ThreadSignalContext *sctx = SigCtx(thr);
-  if (sctx == 0 ||
-      atomic_load(&sctx->have_pending_signals, memory_order_relaxed) == 0)
+  if (sctx == 0)
     return;
-  atomic_store(&sctx->have_pending_signals, 0, memory_order_relaxed);
   atomic_fetch_add(&thr->in_signal_handler, 1, memory_order_relaxed);
   internal_sigfillset(&sctx->emptyset);
   int res = REAL(pthread_sigmask)(SIG_SETMASK, &sctx->emptyset, &sctx->oldset);
@@ -2064,7 +2062,7 @@ void sighandler(int sig, __sanitizer_siginfo *info, void *ctx) {
     signal->armed = true;
     internal_memcpy(&signal->siginfo, info, sizeof(*info));
     internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx));
-    atomic_store(&sctx->have_pending_signals, 1, memory_order_relaxed);
+    atomic_store(&thr->pending_signals, 1, memory_order_relaxed);
   }
 }
 

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
index e5d751f6de33..1f8602072f78 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h
@@ -380,6 +380,7 @@ struct ThreadState {
   // We do not distinguish beteween ignoring reads and writes
   // for better performance.
   int ignore_reads_and_writes;
+  atomic_sint32_t pending_signals;
   int ignore_sync;
   int suppress_reports;
   // Go does not support ignores.
@@ -752,7 +753,7 @@ void ThreadDetach(ThreadState *thr, uptr pc, Tid tid);
 void ThreadFinalize(ThreadState *thr);
 void ThreadSetName(ThreadState *thr, const char *name);
 int ThreadCount(ThreadState *thr);
-void ProcessPendingSignals(ThreadState *thr);
+void ProcessPendingSignalsImpl(ThreadState *thr);
 void ThreadNotJoined(ThreadState *thr, uptr pc, Tid tid, uptr uid);
 
 Processor *ProcCreate();
@@ -858,6 +859,11 @@ enum FiberSwitchFlags {
   FiberSwitchFlagNoSync = 1 << 0, // __tsan_switch_to_fiber_no_sync
 };
 
+ALWAYS_INLINE void ProcessPendingSignals(ThreadState *thr) {
+  if (UNLIKELY(atomic_load_relaxed(&thr->pending_signals)))
+    ProcessPendingSignalsImpl(thr);
+}
+
 extern bool is_initialized;
 
 ALWAYS_INLINE


        


More information about the llvm-commits mailing list