[compiler-rt] e3f4c63 - tsan: don't use spinning in __cxa_guard_acquire/pthread_once

Dmitry Vyukov via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 4 04:56:36 PDT 2021


Author: Dmitry Vyukov
Date: 2021-08-04T13:56:33+02:00
New Revision: e3f4c63e78b1ed54f0a35aeb30730e5c74bcfeed

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

LOG: tsan: don't use spinning in __cxa_guard_acquire/pthread_once

Currently we use passive spinning with internal_sched_yield to wait
in __cxa_guard_acquire/pthread_once. Passive spinning tends to degrade
ungracefully under high load. Use FutexWait/Wake instead.

Depends on D107359.

Reviewed By: vitalybuka, melver

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index cc109599f8be..34190e5d01ef 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -853,6 +853,7 @@ TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {
 constexpr u32 kGuardInit = 0;
 constexpr u32 kGuardDone = 1;
 constexpr u32 kGuardRunning = 1 << 16;
+constexpr u32 kGuardWaiter = 1 << 17;
 
 static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g) {
   OnPotentiallyBlockingRegionBegin();
@@ -868,7 +869,10 @@ static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g) {
         Acquire(thr, pc, (uptr)g);
       return 0;
     } else {
-      internal_sched_yield();
+      if ((cmp & kGuardWaiter) ||
+          atomic_compare_exchange_strong(g, &cmp, cmp | kGuardWaiter,
+                                         memory_order_relaxed))
+        FutexWait(g, cmp | kGuardWaiter);
     }
   }
 }
@@ -876,7 +880,9 @@ static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g) {
 static void guard_release(ThreadState *thr, uptr pc, atomic_uint32_t *g) {
   if (!thr->in_ignored_lib)
     Release(thr, pc, (uptr)g);
-  atomic_store(g, kGuardDone, memory_order_release);
+  u32 old = atomic_exchange(g, kGuardDone, memory_order_release);
+  if (old & kGuardWaiter)
+    FutexWake(g, 1 << 30);
 }
 
 // __cxa_guard_acquire and friends need to be intercepted in a special way -


        


More information about the llvm-commits mailing list