Skip to content

Commit 8390c68

Browse files
yoneymeta-codesync[bot]
authored andcommitted
Reset TSAN mutex state after fork
Summary: Prevent false TSAN mutex warnings after fork(). ThreadSanitizer: double lock of a mutex (/data/users/alperyoney/fbsource/buck-out/v2/art/fbcode/a57827884e45a11c/cinderx/PythonBin/__python_3.14__/out/install/bin/python3.14+0x14f5b7) (BuildId: c5243aa7a162ca3f6d8416f73eb62bded97747ae) in pthread_mutex_lock ================== ThreadSanitizer: reported 1 warnings ``` Reviewed By: alexmalyshev Differential Revision: D116817969 fbshipit-source-id: dea4a4e46b3819193457d4cd5797a3a234934482
1 parent 0601978 commit 8390c68

3 files changed

Lines changed: 38 additions & 13 deletions

File tree

cinderx/Common/define.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@
1010

1111
#include "cinderx/python.h"
1212

13+
#if defined(__has_feature)
14+
#define CINDER_HAS_FEATURE(x) __has_feature(x)
15+
#else
16+
#define CINDER_HAS_FEATURE(x) 0
17+
#endif
18+
19+
#if defined(__SANITIZE_THREAD__) || CINDER_HAS_FEATURE(thread_sanitizer)
20+
#define CINDER_TSAN_ENABLED 1
21+
#else
22+
#define CINDER_TSAN_ENABLED 0
23+
#endif
24+
1325
namespace cinderx {
1426

1527
// Whether CinderX is being built with a debug build configuration.

cinderx/Jit/codegen/tsan.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,6 @@
66

77
#include <cstddef>
88

9-
#if defined(__has_feature)
10-
#define CINDER_TSAN_HAS_FEATURE(x) __has_feature(x)
11-
#else
12-
#define CINDER_TSAN_HAS_FEATURE(x) 0
13-
#endif
14-
15-
#if defined(__SANITIZE_THREAD__) || CINDER_TSAN_HAS_FEATURE(thread_sanitizer)
16-
#define CINDER_TSAN_ENABLED 1
17-
#else
18-
#define CINDER_TSAN_ENABLED 0
19-
#endif
20-
219
// JIT TSAN instrumentation is currently implemented for Linux x86-64. Other
2210
// platforms can still use TSAN for non-JIT code.
2311
#if CINDER_TSAN_ENABLED && defined(CINDER_X86_64) && defined(__linux__)

cinderx/Jit/compilation_lock.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,35 @@
22

33
#include "cinderx/Jit/compilation_lock.h"
44

5+
#include "cinderx/Common/define.h"
6+
7+
#if CINDER_TSAN_ENABLED
8+
#include <sanitizer/tsan_interface.h>
9+
#endif
10+
511
#include <new>
612

713
namespace cinderx::jit {
814

15+
namespace {
16+
17+
void resetMutexAfterFork(std::recursive_mutex& mutex) {
18+
#if CINDER_TSAN_ENABLED
19+
void* native_mutex = mutex.native_handle();
20+
__tsan_mutex_pre_unlock(native_mutex, __tsan_mutex_recursive_unlock);
21+
__tsan_mutex_post_unlock(native_mutex, 0);
22+
__tsan_mutex_destroy(native_mutex, 0);
23+
#endif
24+
25+
new (&mutex) std::recursive_mutex{};
26+
27+
#if CINDER_TSAN_ENABLED
28+
__tsan_mutex_create(mutex.native_handle(), __tsan_mutex_write_reentrant);
29+
#endif
30+
}
31+
32+
} // namespace
33+
934
std::recursive_mutex& jitCompilationMutex() {
1035
static std::recursive_mutex mutex;
1136
return mutex;
@@ -26,7 +51,7 @@ void jitCompilationAtForkChild() {
2651
// across the fork, so unlock() would fail with EPERM and leave the lock held
2752
// forever. Destroying it isn't an option either, as it is still locked by
2853
// atForkPrepare(), so its lifetime ends without running its destructor.
29-
new (&jitCompilationMutex()) std::recursive_mutex{};
54+
resetMutexAfterFork(jitCompilationMutex());
3055
}
3156

3257
} // namespace cinderx::jit

0 commit comments

Comments
 (0)