Skip to content

Commit 8ed8a28

Browse files
committed
[Threading][TSan] Move ThreadSanitizer.cpp into the main runtime.
On Darwin, `RTLD_NEXT` doesn't do what we need it to here, with the result that if `libswiftCore`'s TSan initializer gets found first, then `libswift_Concurrency` won't have its initializer called at all, in spite of us using `RTLD_NEXT` to find the next definition. Fix this by centralising the initializer in `libswiftCore` instead. rdar://110665213
1 parent ee5efff commit 8ed8a28

File tree

5 files changed

+28
-20
lines changed

5 files changed

+28
-20
lines changed

include/swift/Threading/ThreadSanitizer.h

+10-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#ifndef SWIFT_THREADING_THREAD_SANITIZER_H
2121
#define SWIFT_THREADING_THREAD_SANITIZER_H
2222

23+
#include "swift/shims/Visibility.h"
24+
2325
namespace swift {
2426

2527
#if defined(_WIN32) || defined(__wasi__) || !__has_include(<dlfcn.h>)
@@ -34,17 +36,17 @@ template <typename T> T *release(T *ptr) { return ptr; }
3436

3537
namespace threading_impl {
3638

37-
extern bool tsan_enabled;
38-
extern void (*tsan_acquire)(const void *ptr);
39-
extern void (*tsan_release)(const void *ptr);
39+
SWIFT_RUNTIME_EXPORT bool _swift_tsan_enabled;
40+
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_acquire)(const void *ptr);
41+
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_release)(const void *ptr);
4042

4143
} // namespace threading_impl
4244

4345
namespace tsan {
4446

4547
/// Returns true if TSan is enabled
4648
inline bool enabled() {
47-
return threading_impl::tsan_enabled;
49+
return threading_impl::_swift_tsan_enabled;
4850
}
4951

5052
/// Indicate to TSan that an acquiring load has occurred on the current
@@ -54,8 +56,8 @@ inline bool enabled() {
5456
/// `acquire()`.
5557
template <typename T>
5658
T *acquire(T *ptr) {
57-
if (threading_impl::tsan_acquire) {
58-
threading_impl::tsan_acquire(ptr);
59+
if (threading_impl::_swift_tsan_acquire) {
60+
threading_impl::_swift_tsan_acquire(ptr);
5961
}
6062
return ptr;
6163
}
@@ -66,8 +68,8 @@ T *acquire(T *ptr) {
6668
/// see all writes that happened before the `release()`.
6769
template <typename T>
6870
T *release(T *ptr) {
69-
if (threading_impl::tsan_release) {
70-
threading_impl::tsan_release(ptr);
71+
if (threading_impl::_swift_tsan_release) {
72+
threading_impl::_swift_tsan_release(ptr);
7173
}
7274
return ptr;
7375
}

lib/Threading/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ add_swift_host_library(swiftThreading STATIC
1010
Linux.cpp
1111
Pthreads.cpp
1212
Win32.cpp
13-
Errors.cpp
14-
ThreadSanitizer.cpp)
13+
Errors.cpp)

stdlib/public/Threading/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ add_swift_target_library(swiftThreading OBJECT_LIBRARY
99
"${SWIFT_SOURCE_DIR}/lib/Threading/Linux.cpp"
1010
"${SWIFT_SOURCE_DIR}/lib/Threading/Pthreads.cpp"
1111
"${SWIFT_SOURCE_DIR}/lib/Threading/Win32.cpp"
12-
"${SWIFT_SOURCE_DIR}/lib/Threading/ThreadSanitizer.cpp"
1312
INSTALL_IN_COMPONENT never_install)

stdlib/public/runtime/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ set(swift_runtime_sources
7676
SwiftDtoa.cpp
7777
SwiftTLSContext.cpp
7878
ThreadingError.cpp
79+
ThreadSanitizer.cpp
7980
Tracing.cpp
8081
AccessibleFunction.cpp
8182
Win32.cpp)

lib/Threading/ThreadSanitizer.cpp renamed to stdlib/public/runtime/ThreadSanitizer.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,35 @@
2020
#include "swift/Threading/ThreadSanitizer.h"
2121
#include "swift/shims/Visibility.h"
2222

23+
#include <cstdio>
24+
2325
namespace swift {
2426
namespace threading_impl {
2527

26-
bool tsan_enabled = false;
27-
void (*tsan_acquire)(const void *) = nullptr;
28-
void (*tsan_release)(const void *) = nullptr;
28+
SWIFT_RUNTIME_EXPORT bool _swift_tsan_enabled = false;
29+
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_acquire)(const void *) = nullptr;
30+
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_release)(const void *) = nullptr;
2931

3032
#if __has_include(<dlfcn.h>)
3133
#include <dlfcn.h>
3234

3335
// The TSan library code will call this function when it starts up
34-
extern "C" SWIFT_ATTRIBUTE_FOR_EXPORTS
36+
SWIFT_RUNTIME_EXPORT
3537
void __tsan_on_initialize() {
36-
tsan_enabled = true;
37-
tsan_acquire = (void (*)(const void *))dlsym(RTLD_DEFAULT, "__tsan_acquire");
38-
tsan_release = (void (*)(const void *))dlsym(RTLD_DEFAULT, "__tsan_release");
38+
_swift_tsan_enabled = true;
39+
_swift_tsan_acquire = (void (*)(const void *))dlsym(RTLD_DEFAULT,
40+
"__tsan_acquire");
41+
_swift_tsan_release = (void (*)(const void *))dlsym(RTLD_DEFAULT,
42+
"__tsan_release");
3943

40-
// Always call through to the next image
44+
// Always call through to the next image; this won't work on macOS, but it's
45+
// important on Linux to allow others to hook into the thread sanitizer if
46+
// they wish.
4147
void (*next_init)(void);
4248
next_init = (void (*)(void))dlsym(RTLD_NEXT, "__tsan_on_initialize");
43-
if (next_init)
49+
if (next_init) {
4450
next_init();
51+
}
4552
}
4653
#endif
4754

0 commit comments

Comments
 (0)