mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
#ifndef SWIFT_THREADING_THREAD_SANITIZER_H
|
||||
#define SWIFT_THREADING_THREAD_SANITIZER_H
|
||||
|
||||
#include "swift/shims/Visibility.h"
|
||||
|
||||
namespace swift {
|
||||
|
||||
#if defined(_WIN32) || defined(__wasi__) || !__has_include(<dlfcn.h>)
|
||||
@@ -34,9 +36,9 @@ template <typename T> T *release(T *ptr) { return ptr; }
|
||||
|
||||
namespace threading_impl {
|
||||
|
||||
extern bool tsan_enabled;
|
||||
extern void (*tsan_acquire)(const void *ptr);
|
||||
extern void (*tsan_release)(const void *ptr);
|
||||
SWIFT_RUNTIME_EXPORT bool _swift_tsan_enabled;
|
||||
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_acquire)(const void *ptr);
|
||||
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_release)(const void *ptr);
|
||||
|
||||
} // namespace threading_impl
|
||||
|
||||
@@ -44,7 +46,7 @@ namespace tsan {
|
||||
|
||||
/// Returns true if TSan is enabled
|
||||
inline bool enabled() {
|
||||
return threading_impl::tsan_enabled;
|
||||
return threading_impl::_swift_tsan_enabled;
|
||||
}
|
||||
|
||||
/// Indicate to TSan that an acquiring load has occurred on the current
|
||||
@@ -54,8 +56,8 @@ inline bool enabled() {
|
||||
/// `acquire()`.
|
||||
template <typename T>
|
||||
T *acquire(T *ptr) {
|
||||
if (threading_impl::tsan_acquire) {
|
||||
threading_impl::tsan_acquire(ptr);
|
||||
if (threading_impl::_swift_tsan_acquire) {
|
||||
threading_impl::_swift_tsan_acquire(ptr);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
@@ -66,8 +68,8 @@ T *acquire(T *ptr) {
|
||||
/// see all writes that happened before the `release()`.
|
||||
template <typename T>
|
||||
T *release(T *ptr) {
|
||||
if (threading_impl::tsan_release) {
|
||||
threading_impl::tsan_release(ptr);
|
||||
if (threading_impl::_swift_tsan_release) {
|
||||
threading_impl::_swift_tsan_release(ptr);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -10,5 +10,4 @@ add_swift_host_library(swiftThreading STATIC
|
||||
Linux.cpp
|
||||
Pthreads.cpp
|
||||
Win32.cpp
|
||||
Errors.cpp
|
||||
ThreadSanitizer.cpp)
|
||||
Errors.cpp)
|
||||
|
||||
@@ -9,5 +9,4 @@ add_swift_target_library(swiftThreading OBJECT_LIBRARY
|
||||
"${SWIFT_SOURCE_DIR}/lib/Threading/Linux.cpp"
|
||||
"${SWIFT_SOURCE_DIR}/lib/Threading/Pthreads.cpp"
|
||||
"${SWIFT_SOURCE_DIR}/lib/Threading/Win32.cpp"
|
||||
"${SWIFT_SOURCE_DIR}/lib/Threading/ThreadSanitizer.cpp"
|
||||
INSTALL_IN_COMPONENT never_install)
|
||||
|
||||
@@ -76,6 +76,7 @@ set(swift_runtime_sources
|
||||
SwiftDtoa.cpp
|
||||
SwiftTLSContext.cpp
|
||||
ThreadingError.cpp
|
||||
ThreadSanitizer.cpp
|
||||
Tracing.cpp
|
||||
AccessibleFunction.cpp
|
||||
Win32.cpp)
|
||||
|
||||
@@ -20,28 +20,35 @@
|
||||
#include "swift/Threading/ThreadSanitizer.h"
|
||||
#include "swift/shims/Visibility.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace swift {
|
||||
namespace threading_impl {
|
||||
|
||||
bool tsan_enabled = false;
|
||||
void (*tsan_acquire)(const void *) = nullptr;
|
||||
void (*tsan_release)(const void *) = nullptr;
|
||||
SWIFT_RUNTIME_EXPORT bool _swift_tsan_enabled = false;
|
||||
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_acquire)(const void *) = nullptr;
|
||||
SWIFT_RUNTIME_EXPORT void (*_swift_tsan_release)(const void *) = nullptr;
|
||||
|
||||
#if __has_include(<dlfcn.h>)
|
||||
#include <dlfcn.h>
|
||||
|
||||
// The TSan library code will call this function when it starts up
|
||||
extern "C" SWIFT_ATTRIBUTE_FOR_EXPORTS
|
||||
SWIFT_RUNTIME_EXPORT
|
||||
void __tsan_on_initialize() {
|
||||
tsan_enabled = true;
|
||||
tsan_acquire = (void (*)(const void *))dlsym(RTLD_DEFAULT, "__tsan_acquire");
|
||||
tsan_release = (void (*)(const void *))dlsym(RTLD_DEFAULT, "__tsan_release");
|
||||
_swift_tsan_enabled = true;
|
||||
_swift_tsan_acquire = (void (*)(const void *))dlsym(RTLD_DEFAULT,
|
||||
"__tsan_acquire");
|
||||
_swift_tsan_release = (void (*)(const void *))dlsym(RTLD_DEFAULT,
|
||||
"__tsan_release");
|
||||
|
||||
// Always call through to the next image
|
||||
// Always call through to the next image; this won't work on macOS, but it's
|
||||
// important on Linux to allow others to hook into the thread sanitizer if
|
||||
// they wish.
|
||||
void (*next_init)(void);
|
||||
next_init = (void (*)(void))dlsym(RTLD_NEXT, "__tsan_on_initialize");
|
||||
if (next_init)
|
||||
if (next_init) {
|
||||
next_init();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user