diff --git a/include/swift/Threading/ThreadSanitizer.h b/include/swift/Threading/ThreadSanitizer.h index 19923c3689c..c97ab2c4241 100644 --- a/include/swift/Threading/ThreadSanitizer.h +++ b/include/swift/Threading/ThreadSanitizer.h @@ -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() @@ -34,9 +36,9 @@ template 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 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 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; } diff --git a/lib/Threading/CMakeLists.txt b/lib/Threading/CMakeLists.txt index 4e0e6aed05e..029a52b68e1 100644 --- a/lib/Threading/CMakeLists.txt +++ b/lib/Threading/CMakeLists.txt @@ -10,5 +10,4 @@ add_swift_host_library(swiftThreading STATIC Linux.cpp Pthreads.cpp Win32.cpp - Errors.cpp - ThreadSanitizer.cpp) + Errors.cpp) diff --git a/stdlib/public/Threading/CMakeLists.txt b/stdlib/public/Threading/CMakeLists.txt index 961c643b756..007289ed3fa 100644 --- a/stdlib/public/Threading/CMakeLists.txt +++ b/stdlib/public/Threading/CMakeLists.txt @@ -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) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 18320c6d768..05fa2f65b9a 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -76,6 +76,7 @@ set(swift_runtime_sources SwiftDtoa.cpp SwiftTLSContext.cpp ThreadingError.cpp + ThreadSanitizer.cpp Tracing.cpp AccessibleFunction.cpp Win32.cpp) diff --git a/lib/Threading/ThreadSanitizer.cpp b/stdlib/public/runtime/ThreadSanitizer.cpp similarity index 63% rename from lib/Threading/ThreadSanitizer.cpp rename to stdlib/public/runtime/ThreadSanitizer.cpp index bee0b8529c5..75b282f3e46 100644 --- a/lib/Threading/ThreadSanitizer.cpp +++ b/stdlib/public/runtime/ThreadSanitizer.cpp @@ -20,28 +20,35 @@ #include "swift/Threading/ThreadSanitizer.h" #include "swift/shims/Visibility.h" +#include + 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() #include // 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