1919#include " iree/base/internal/atomics.h"
2020#include " iree/base/threading/futex.h"
2121
22- // NOTE: clang cannot support thread annotations in C code due to some
23- // representational bugs... which means that we can't use it here. Boo.
24- // There's some workarounds I've seen but getting TSAN working would be much
25- // easier as a starting point.
26- #if 0 // defined(IREE_COMPILER_CLANG)
22+ // Clang thread-safety analysis is a C++ language extension. The capability
23+ // model requires capabilities to be C++ records with annotated acquire/release
24+ // member functions, and GUARDED_BY() uses C++ name lookup to resolve the
25+ // capability object. These assumptions do not hold in C: the attribute may be
26+ // ignored or mis-parsed by the C frontend, and free-function lock/unlock
27+ // primitives lack the this-based capability tracking that the analysis relies
28+ // on. The analysis therefore only fires meaningfully in C++.
29+ // See https://clang.llvm.org/docs/ThreadSafetyAnalysis.html ("Introduction").
30+ // Enable the annotations when compiling C++ with Clang so that callers can use
31+ // IREE_GUARDED_BY et al. and iree_slim_mutex_t carries the required capability
32+ // annotation.
33+ #if defined(__cplusplus) && defined(__clang__)
2734#define IREE_THREAD_ANNOTATION_ATTRIBUTE (x ) __attribute__((x))
2835#else
2936#define IREE_THREAD_ANNOTATION_ATTRIBUTE (x )
30- #endif // IREE_COMPILER_CLANG
37+ #endif // __cplusplus && __clang__
3138
3239#ifdef __cplusplus
3340// Documents if a shared field or global variable needs to be protected by a
4754#define IREE_PTR_GUARDED_BY (x )
4855#endif // __cplusplus
4956
57+ // Disables thread-safety analysis for a function. Use on init/destroy functions
58+ // that access mutex-guarded data before/after the mutex is live, where single-
59+ // threaded access is guaranteed by the caller's lifecycle contract.
60+ #define IREE_NO_THREAD_SAFETY_ANALYSIS \
61+ IREE_THREAD_ANNOTATION_ATTRIBUTE (no_thread_safety_analysis)
62+
5063// Allow users to fully disable all synchronization for systems that are known
5164// to never need it. This removes our dependency on pthreads.
5265#if !IREE_SYNCHRONIZATION_DISABLE_UNSAFE
@@ -83,8 +96,7 @@ extern "C" {
8396//
8497// Windows: Slim Reader/Writer (SRW) Locks
8598// All others: pthread_mutex_t
86- typedef struct iree_mutex_t IREE_THREAD_ANNOTATION_ATTRIBUTE (
87- capability (" mutex" )) {
99+ typedef struct iree_mutex_t {
88100#if IREE_SYNCHRONIZATION_DISABLE_UNSAFE
89101 int reserved;
90102#elif defined(IREE_PLATFORM_WINDOWS) && defined(IREE_MUTEX_USE_WIN32_SRW)
@@ -97,7 +109,7 @@ typedef struct iree_mutex_t IREE_THREAD_ANNOTATION_ATTRIBUTE(
97109#if (IREE_TRACING_FEATURES & IREE_TRACING_FEATURE_SLOW_LOCKS)
98110 uint32_t lock_id;
99111#endif // IREE_TRACING_FEATURE_SLOW_LOCKS
100- } iree_mutex_t ;
112+ } IREE_THREAD_ANNOTATION_ATTRIBUTE (capability( " mutex " )) iree_mutex_t ;
101113
102114#if (IREE_TRACING_FEATURES & IREE_TRACING_FEATURE_SLOW_LOCKS)
103115// Initializes |out_mutex| to the well-defined unlocked contents.
@@ -224,8 +236,7 @@ IREE_API_EXPORT void iree_mutex_unlock(iree_mutex_t* mutex)
224236// https://man7.org/linux/man-pages/man2/futex.2.html
225237// https://eli.thegreenplace.net/2018/basics-of-futexes/
226238// https://bartoszmilewski.com/2008/09/01/thin-lock-vs-futex/
227- typedef struct iree_slim_mutex_t IREE_THREAD_ANNOTATION_ATTRIBUTE (
228- capability (" mutex" )) {
239+ typedef struct iree_slim_mutex_t {
229240#if IREE_SYNCHRONIZATION_DISABLE_UNSAFE
230241 int reserved;
231242#elif (IREE_TRACING_FEATURES & IREE_TRACING_FEATURE_FAST_LOCKS)
@@ -239,7 +250,7 @@ typedef struct iree_slim_mutex_t IREE_THREAD_ANNOTATION_ATTRIBUTE(
239250#else
240251 iree_mutex_t impl; // fallback
241252#endif // IREE_PLATFORM_*
242- } iree_slim_mutex_t ;
253+ } IREE_THREAD_ANNOTATION_ATTRIBUTE (capability( " mutex " )) iree_slim_mutex_t;
243254
244255#if (IREE_TRACING_FEATURES & IREE_TRACING_FEATURE_FAST_LOCKS)
245256// Initializes |out_mutex| to the well-defined unlocked contents.
0 commit comments