Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01baf0e

Browse files
authored
[Runtime] Revive thread-safety analysis (#24560)
(Re-) Enables C++ users of the IREE runtime to use clang's thread-safety-analysis to detect bugs before they materialize. Enabling thread-safety-analysis attributes behind a `defined(__cplusplus) && defined(__clang__)` guard. Previous attribute placement was non-standard: per https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html "An attribute specifier list may appear as part of a struct, union or enum specifier. It may go either immediately after the struct, union or enum keyword, or after the closing brace". Signed-off-by: Tobias Fuchs <[email protected]>
1 parent 8e158ad commit 01baf0e

1 file changed

Lines changed: 23 additions & 12 deletions

File tree

  • runtime/src/iree/base/threading

runtime/src/iree/base/threading/mutex.h

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@
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
@@ -47,6 +54,12 @@
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

Comments
 (0)