[compiler-rt] [llvm] [tsan] Introduce Adaptive Delay Scheduling to TSAN (PR #178836)
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 15 02:35:00 PST 2026
================
@@ -0,0 +1,170 @@
+//===-- tsan_adaptive_delay.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TSAN_ADAPTIVE_DELAY_H
+#define TSAN_ADAPTIVE_DELAY_H
+
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+
+namespace __tsan {
+
+extern bool is_adaptive_delay_enabled;
+
+// AdaptiveDelay injects delays at synchronization points, atomic operations,
+// and thread lifecycle events to increase the likelihood of exposing data
+// races. The delay injection is controlled by an approximate time budget to
+// maintain a configurable overhead target.
+//
+// SyncOp() delays non-atomic synchronization points (those with clear
+// happens-before relationships):
+// - Acquire operations like locking a mutex delays before the mutex is locked.
+// - Release operations like unlocking a mutex delays after the mutex is
+// unlocked
+// These are more likely to expose interesting (rare) thread interleavings.
+// For example, delaying a thread that unlocks a mutex from running to allow
+// newly woken thread to execute before the unlocking thread would normally
+// execute.
+struct AdaptiveDelay {
+ ALWAYS_INLINE static void Init() { InitImpl(); }
+
+ ALWAYS_INLINE static void SyncOp() {
+ if (!is_adaptive_delay_enabled)
+ return;
+ SyncOpImpl();
+ }
+
+ ALWAYS_INLINE static void AtomicOpFence(int mo) {
+ if (!is_adaptive_delay_enabled)
+ return;
+ AtomicOpFenceImpl(mo);
+ }
+
+ ALWAYS_INLINE static void AtomicOpAddr(__sanitizer::uptr addr, int mo) {
+ if (!is_adaptive_delay_enabled)
+ return;
+ AtomicOpAddrImpl(addr, mo);
+ }
+
+ ALWAYS_INLINE static void AfterThreadCreation() {
+ if (!is_adaptive_delay_enabled)
+ return;
+ AfterThreadCreationImpl();
+ }
+
+ ALWAYS_INLINE static void BeforeChildThreadRuns() {
+ if (!is_adaptive_delay_enabled)
+ return;
+ BeforeChildThreadRunsImpl();
+ }
+
+ private:
+ static void InitImpl();
+
+ static void SyncOpImpl();
+
+ static void AtomicOpFenceImpl(int mo);
+ static void AtomicOpAddrImpl(__sanitizer::uptr addr, int mo);
+
+ static void AfterThreadCreationImpl();
+ static void BeforeChildThreadRunsImpl();
+};
+
+AdaptiveDelay& GetAdaptiveDelay();
----------------
dvyukov wrote:
This does not seem to be used.
https://github.com/llvm/llvm-project/pull/178836
More information about the llvm-commits
mailing list