From d9aed16e2b11efb6c84e2d6fc7533f8b051a4f30 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Thu, 22 Jun 2023 20:03:00 +0100 Subject: [PATCH 1/2] [Threading][TSan] Fix TSan errors from lazy init on Linux. Move the TSan functionality from Concurrency into Threading. Use it in the Linux ulock implementation so that TSan knows about ulock and will tolerate the newer swift_once implementation that uses it. This should also slightly improve the performance of Concurrency, since the tsan tests will be inlined rather than it always doing a subroutine call. rdar://110665213 --- cmake/modules/AddSwiftUnittests.cmake | 3 +- include/swift/Threading/Impl/Linux/ulock.h | 29 +++-- include/swift/Threading/ThreadSanitizer.h | 120 ++++++++++++++++++ lib/Threading/CMakeLists.txt | 3 +- lib/Threading/Linux.cpp | 3 +- lib/Threading/ThreadSanitizer.cpp | 61 +++++++++ stdlib/public/Concurrency/CMakeLists.txt | 1 - stdlib/public/Concurrency/TaskPrivate.h | 13 +- stdlib/public/Concurrency/ThreadSanitizer.cpp | 50 -------- stdlib/public/Threading/CMakeLists.txt | 1 + stdlib/public/runtime/CMakeLists.txt | 12 ++ test/Sanitizers/tsan/once.swift | 55 ++++++++ 12 files changed, 283 insertions(+), 68 deletions(-) create mode 100644 include/swift/Threading/ThreadSanitizer.h create mode 100644 lib/Threading/ThreadSanitizer.cpp delete mode 100644 stdlib/public/Concurrency/ThreadSanitizer.cpp create mode 100644 test/Sanitizers/tsan/once.swift diff --git a/cmake/modules/AddSwiftUnittests.cmake b/cmake/modules/AddSwiftUnittests.cmake index 9dff9f77a2e02..35081f3dcee71 100644 --- a/cmake/modules/AddSwiftUnittests.cmake +++ b/cmake/modules/AddSwiftUnittests.cmake @@ -56,7 +56,8 @@ function(add_swift_unittest test_dirname) string(TOUPPER "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_THREADING_PACKAGE}" _threading_package) target_compile_definitions("${test_dirname}" PRIVATE - "SWIFT_THREADING_${_threading_package}") + "SWIFT_THREADING_${_threading_package}" + "SWIFT_THREADING_STATIC") if(NOT SWIFT_COMPILER_IS_MSVC_LIKE) if(SWIFT_USE_LINKER) diff --git a/include/swift/Threading/Impl/Linux/ulock.h b/include/swift/Threading/Impl/Linux/ulock.h index a9020965ec5d4..af04e74aa08ef 100644 --- a/include/swift/Threading/Impl/Linux/ulock.h +++ b/include/swift/Threading/Impl/Linux/ulock.h @@ -34,6 +34,8 @@ #include #include +#include "swift/Threading/ThreadSanitizer.h" + namespace swift { namespace threading_impl { namespace linux { @@ -59,31 +61,38 @@ inline void ulock_lock(ulock_t *lock) { const ulock_t tid = ulock_get_tid(); do { ulock_t zero = 0; - if (ulock_fastpath(__atomic_compare_exchange_n( - lock, &zero, tid, true, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))) - return; - + if (ulock_fastpath(__atomic_compare_exchange_n(lock, &zero, tid, + true, __ATOMIC_ACQUIRE, + __ATOMIC_RELAXED))) + break; } while (ulock_futex(lock, FUTEX_LOCK_PI) != 0); + + tsan::acquire(lock); } inline bool ulock_trylock(ulock_t *lock) { ulock_t zero = 0; if (ulock_fastpath(__atomic_compare_exchange_n(lock, &zero, ulock_get_tid(), true, __ATOMIC_ACQUIRE, - __ATOMIC_RELAXED))) + __ATOMIC_RELAXED)) + || ulock_futex(lock, FUTEX_TRYLOCK_PI) == 0) { + tsan::acquire(lock); return true; + } - return ulock_futex(lock, FUTEX_TRYLOCK_PI) == 0; + return false; } inline void ulock_unlock(ulock_t *lock) { + tsan::release(lock); + const ulock_t tid = ulock_get_tid(); do { ulock_t expected = tid; - if (ulock_fastpath(__atomic_compare_exchange_n( - lock, &expected, 0, true, __ATOMIC_RELEASE, __ATOMIC_RELAXED))) - return; - + if (ulock_fastpath(__atomic_compare_exchange_n(lock, &expected, 0, + true, __ATOMIC_RELEASE, + __ATOMIC_RELAXED))) + break; } while (ulock_futex(lock, FUTEX_UNLOCK_PI) != 0); } diff --git a/include/swift/Threading/ThreadSanitizer.h b/include/swift/Threading/ThreadSanitizer.h new file mode 100644 index 0000000000000..0a6a8028ea183 --- /dev/null +++ b/include/swift/Threading/ThreadSanitizer.h @@ -0,0 +1,120 @@ +//===--- ThreadSanitizer.h - Thread Sanitizer support --------- -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Helper functions for code that needs to integrate with the thread +// sanitizer. In particular, TSan can't see inside the runtime libraries, +// so we occasionally need to give it a hint that we're doing synchronization +// in order to avoid false positives. +// +//===----------------------------------------------------------------------===// + +#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() + +#define SWIFT_THREADING_TSAN_SUPPORT 0 + +namespace tsan { + +inline bool enabled() { return false; } +template T *acquire(T *ptr) { return ptr; } +template T *release(T *ptr) { return ptr; } + +} // namespace tsan +#else + +#define SWIFT_THREADING_TSAN_SUPPORT 1 + +// If we're static linking to libswiftThreading.a, these symbols can come +// from there. If, on the other hand, we're dynamically linked, we want +// to get them from libswiftCore.dylib instead. +#if SWIFT_THREADING_STATIC +#define SWIFT_THREADING_EXPORT extern "C" +#else +#define SWIFT_THREADING_EXPORT SWIFT_RUNTIME_EXPORT +#endif + +namespace threading_impl { + +SWIFT_THREADING_EXPORT bool _swift_tsan_enabled; +SWIFT_THREADING_EXPORT void (*_swift_tsan_acquire)(const void *ptr); +SWIFT_THREADING_EXPORT void (*_swift_tsan_release)(const void *ptr); + +} // namespace threading_impl + +namespace tsan { + +/// Returns true if TSan is enabled +inline bool enabled() { + return threading_impl::_swift_tsan_enabled; +} + +/// Inform TSan about a synchronization operation. +/// +/// This is used when TSan cannot see the synchronization operation, for +/// example, if it is using a custom primitive for which TSan doesn't have +/// a built-in interceptor. This does not necessarily mean a lock or a C(++) +/// atomic operation - it could be any kind of synchronization mechanism. +/// +/// An acquire-release pair using the same address establishes an ordering +/// constraint in TSan's happens-before graph, which TSan uses to determine +/// whether two memory accesses from different threads have a well-defined +/// order. +/// +/// For instance, in +/// +/// Thread 1 Thread 2 +/// +/// access to y +/// tsan::release(x) +/// lock given away +/// +/// --> sync point --> +/// +/// lock taken +/// tsan::acquire(x) +/// access to y +/// +/// the access to y from Thread 2 is safe relative to the preceding access to +/// y on Thread 1 because it is preceded by an acquire of x that was itself +/// preceded by a release of x. +template +T *acquire(T *ptr) { + if (threading_impl::_swift_tsan_acquire) { + threading_impl::_swift_tsan_acquire(ptr); + } + return ptr; +} + +/// Inform TSan about a synchronization operation. +/// +/// This is the counterpart to tsan::acquire. +template +T *release(T *ptr) { + if (threading_impl::_swift_tsan_release) { + threading_impl::_swift_tsan_release(ptr); + } + return ptr; +} + +} // namespace tsan + +#endif + +} // namespace swift + +#endif diff --git a/lib/Threading/CMakeLists.txt b/lib/Threading/CMakeLists.txt index 029a52b68e1e3..4e0e6aed05e3b 100644 --- a/lib/Threading/CMakeLists.txt +++ b/lib/Threading/CMakeLists.txt @@ -10,4 +10,5 @@ add_swift_host_library(swiftThreading STATIC Linux.cpp Pthreads.cpp Win32.cpp - Errors.cpp) + Errors.cpp + ThreadSanitizer.cpp) diff --git a/lib/Threading/Linux.cpp b/lib/Threading/Linux.cpp index 811f470ba0832..93963a7c30ad2 100644 --- a/lib/Threading/Linux.cpp +++ b/lib/Threading/Linux.cpp @@ -18,6 +18,7 @@ #include "swift/Threading/Impl.h" #include "swift/Threading/Errors.h" +#include "swift/Threading/ThreadSanitizer.h" namespace { @@ -61,7 +62,7 @@ void swift::threading_impl::once_slow(once_t &predicate, void (*fn)(void *), #endif if (predicate.flag.load(std::memory_order_acquire) == 0) { fn(context); - predicate.flag.store(-1, std::memory_order_release); + predicate.flag.store(tsan::enabled() ? 1 : -1, std::memory_order_release); } #if defined(__LP64__) || defined(_LP64) linux::ulock_unlock(&predicate.lock); diff --git a/lib/Threading/ThreadSanitizer.cpp b/lib/Threading/ThreadSanitizer.cpp new file mode 100644 index 0000000000000..a103c161dce91 --- /dev/null +++ b/lib/Threading/ThreadSanitizer.cpp @@ -0,0 +1,61 @@ +//===--- ThreadSanitizer.cpp - Thread Sanitizer support -------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Helper functions for code that needs to integrate with the thread +// sanitizer. In particular, TSan can't see inside the runtime libraries, +// so we occasionally need to give it a hint that we're doing synchronization +// in order to avoid false positives. +// +//===----------------------------------------------------------------------===// + +#include "swift/Threading/ThreadSanitizer.h" + +#if SWIFT_THREADING_TSAN_SUPPORT + +#include "swift/shims/Visibility.h" + +#include + +namespace swift { +namespace threading_impl { + +SWIFT_THREADING_EXPORT bool _swift_tsan_enabled = false; +SWIFT_THREADING_EXPORT void (*_swift_tsan_acquire)(const void *) = nullptr; +SWIFT_THREADING_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 +void __tsan_on_initialize() { + _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; 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) { + next_init(); + } +} +#endif // __has_include() + +} // namespace threading_impl +} // namespace swift + +#endif // SWIFT_THREADING_TSAN_SUPPORT diff --git a/stdlib/public/Concurrency/CMakeLists.txt b/stdlib/public/Concurrency/CMakeLists.txt index ff614adce7625..c43078573c951 100644 --- a/stdlib/public/Concurrency/CMakeLists.txt +++ b/stdlib/public/Concurrency/CMakeLists.txt @@ -117,7 +117,6 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I TaskLocal.cpp TaskLocal.swift TaskSleep.swift - ThreadSanitizer.cpp ThreadingError.cpp TracingSignpost.cpp AsyncStreamBuffer.swift diff --git a/stdlib/public/Concurrency/TaskPrivate.h b/stdlib/public/Concurrency/TaskPrivate.h index 0b071d5a6d7b6..02899334edd67 100644 --- a/stdlib/public/Concurrency/TaskPrivate.h +++ b/stdlib/public/Concurrency/TaskPrivate.h @@ -28,6 +28,7 @@ #include "swift/Runtime/Exclusivity.h" #include "swift/Runtime/HeapObject.h" #include "swift/Threading/Thread.h" +#include "swift/Threading/ThreadSanitizer.h" #include #include @@ -97,10 +98,14 @@ void _swift_taskGroup_cancelAllChildren(TaskGroup *group); /// should generally use a higher-level function. void _swift_taskGroup_detachChild(TaskGroup *group, AsyncTask *child); -/// release() establishes a happens-before relation with a preceding acquire() -/// on the same address. -void _swift_tsan_acquire(void *addr); -void _swift_tsan_release(void *addr); +/// Tell TSan about an acquiring load +inline void _swift_tsan_acquire(void *addr) { + swift::tsan::acquire(addr); +} +/// Tell TSan about a releasing store +inline void _swift_tsan_release(void *addr) { + swift::tsan::release(addr); +} /// Special values used with DispatchQueueIndex to indicate the global and main /// executors. diff --git a/stdlib/public/Concurrency/ThreadSanitizer.cpp b/stdlib/public/Concurrency/ThreadSanitizer.cpp deleted file mode 100644 index c9d1d5027732b..0000000000000 --- a/stdlib/public/Concurrency/ThreadSanitizer.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===--- ThreadSanitizer.cpp - Thread Sanitizer support -------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// Thread Sanitizer support for the Swift Task runtime. -// -//===----------------------------------------------------------------------===// - -#include "TaskPrivate.h" - -// Thread Sanitizer is not supported on Windows or WASI. -#if defined(_WIN32) || defined(__wasi__) || !__has_include() -void swift::_swift_tsan_acquire(void *addr) {} -void swift::_swift_tsan_release(void *addr) {} -#else -#include - -namespace { -using TSanFunc = void(void *); -TSanFunc *tsan_acquire, *tsan_release; -} // anonymous namespace - -void swift::_swift_tsan_acquire(void *addr) { - if (tsan_acquire) { - tsan_acquire(addr); - SWIFT_TASK_DEBUG_LOG("tsan_acquire on %p", addr); - } -} - -void swift::_swift_tsan_release(void *addr) { - if (tsan_release) { - tsan_release(addr); - SWIFT_TASK_DEBUG_LOG("tsan_release on %p", addr); - } -} - -SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(c) -void __tsan_on_initialize() { - tsan_acquire = (TSanFunc *)dlsym(RTLD_DEFAULT, "__tsan_acquire"); - tsan_release = (TSanFunc *)dlsym(RTLD_DEFAULT, "__tsan_release"); -} -#endif diff --git a/stdlib/public/Threading/CMakeLists.txt b/stdlib/public/Threading/CMakeLists.txt index 007289ed3fac7..96ea52d1d8f7e 100644 --- a/stdlib/public/Threading/CMakeLists.txt +++ b/stdlib/public/Threading/CMakeLists.txt @@ -4,6 +4,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules") include(AddSwiftStdlib) +# This should *not* include ThreadSanitizer.cpp, as that is part of libswiftCore add_swift_target_library(swiftThreading OBJECT_LIBRARY "${SWIFT_SOURCE_DIR}/lib/Threading/C11.cpp" "${SWIFT_SOURCE_DIR}/lib/Threading/Linux.cpp" diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index e46c37d626be4..16037836fa57f 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -71,6 +71,17 @@ set(swift_runtime_sources ThreadingError.cpp AccessibleFunction.cpp) +# We pull this in separately here because other dylibs will need it, but only +# will have the __tsan_on_initialize called, and on Darwin, RTLD_NEXT can't be +# used to call subsequence dylibs' copies of that. +set(swift_runtime_threading_sources + ${SWIFT_SOURCE_DIR}/lib/Threading/ThreadSanitizer.cpp) + +set(swift_runtime_backtracing_sources + Backtrace.cpp + CrashHandlerMacOS.cpp + CrashHandlerLinux.cpp) + # Acknowledge that the following sources are known. set(LLVM_OPTIONAL_SOURCES SwiftRT-COFF.cpp @@ -112,6 +123,7 @@ add_swift_target_library(swiftRuntime OBJECT_LIBRARY ${swift_runtime_sources} ${swift_runtime_objc_sources} ${swift_runtime_leaks_sources} + ${swift_runtime_threading_sources} C_COMPILE_FLAGS ${swift_runtime_library_compile_flags} LINK_FLAGS ${swift_runtime_linker_flags} diff --git a/test/Sanitizers/tsan/once.swift b/test/Sanitizers/tsan/once.swift new file mode 100644 index 0000000000000..f3bcc562403f5 --- /dev/null +++ b/test/Sanitizers/tsan/once.swift @@ -0,0 +1,55 @@ +// RUN: %target-swiftc_driver %s -Xfrontend -parse-as-library -g -sanitize=thread %import-libdispatch -o %t_tsan-binary +// RUN: %target-codesign %t_tsan-binary +// RUN: env %env-TSAN_OPTIONS=abort_on_error=0 %target-run %t_tsan-binary 2>&1 | %FileCheck %s --implicit-check-not='ThreadSanitizer' +// REQUIRES: executable_test +// REQUIRES: tsan_runtime + +// rdar://101876380 +// UNSUPPORTED: OS=ios + +// FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs +// don't support TSan. +// UNSUPPORTED: remote_run + +// Test that we do not report a race on initialization; Swift doesn't initialize +// globals at start-up, but rather uses `swift_once()`. This is thread safe, but +// on some platforms TSan wasn't seeing the synchronization, so would report +// a false positive. + +import Dispatch + +var count = 0 + +// This initialization will be done via a call to `swift_once()`. Prior to +// the fix for rdar://110665213, the addition to `count` would trigger a +// TSan message on Linux because the sanitizer couldn't see the lock we're +// using to make `swift_once()` thread safe. +let foo = { + count += 1 + return count +}() + +@main +struct Main { + static func main() { + let q = DispatchQueue(label: "q", attributes: .concurrent) + let finished = DispatchSemaphore(value: 0) + let count = 100 + + for _ in 0.. Date: Fri, 23 Jun 2023 16:03:26 +0100 Subject: [PATCH 2/2] [Freestanding] Remove uses of stat() and dlsym(). We shouldn't be using stat() or dlsym() in the freestanding runtime. rdar://111214571 rdar://106555012 --- CMakeLists.txt | 5 +++++ cmake/modules/AddSwiftUnittests.cmake | 9 ++++++++- include/swift/Threading/ThreadSanitizer.h | 6 +++++- lib/Threading/ThreadSanitizer.cpp | 6 ++---- stdlib/cmake/modules/AddSwiftStdlib.cmake | 10 ++++++++++ stdlib/cmake/modules/StdlibOptions.cmake | 10 +++++++++- utils/build-presets.ini | 2 ++ utils/build-script-impl | 4 ++++ 8 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6d35ff781df0..28653cfa5c6da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -585,6 +585,11 @@ option(SWIFT_THREADING_PACKAGE Valid package names are 'pthreads', 'darwin', 'linux', 'win32', 'c11', 'none' or the empty string for the SDK default.") +option(SWIFT_THREADING_HAS_DLSYM + "Enable the use of the dlsym() function. This gets used to provide TSan + support on some platforms." + TRUE) + # # End of user-configurable options. # diff --git a/cmake/modules/AddSwiftUnittests.cmake b/cmake/modules/AddSwiftUnittests.cmake index 35081f3dcee71..7dcdc0dddb4b5 100644 --- a/cmake/modules/AddSwiftUnittests.cmake +++ b/cmake/modules/AddSwiftUnittests.cmake @@ -47,12 +47,19 @@ function(add_swift_unittest test_dirname) endif() # some headers switch their inline implementations based on - # SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY and + # SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY, SWIFT_STDLIB_HAS_DLSYM and # SWIFT_THREADING_PACKAGE definitions if(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY) target_compile_definitions("${test_dirname}" PRIVATE SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY) endif() + if(SWIFT_STDLIB_HAS_DLSYM) + target_compile_definitions("${test_dirname}" PRIVATE + "SWIFT_STDLIB_HAS_DLSYM=1") + else() + target_compile_definitions("${test_dirname}" PRIVATE + "SWIFT_STDLIB_HAS_DLSYM=0") + endif() string(TOUPPER "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_THREADING_PACKAGE}" _threading_package) target_compile_definitions("${test_dirname}" PRIVATE diff --git a/include/swift/Threading/ThreadSanitizer.h b/include/swift/Threading/ThreadSanitizer.h index 0a6a8028ea183..a50a554f08c40 100644 --- a/include/swift/Threading/ThreadSanitizer.h +++ b/include/swift/Threading/ThreadSanitizer.h @@ -24,7 +24,10 @@ namespace swift { -#if defined(_WIN32) || defined(__wasi__) || !__has_include() +#if SWIFT_THREADING_NONE \ + || defined(_WIN32) || defined(__wasi__) \ + || !__has_include() \ + || (defined(SWIFT_STDLIB_HAS_DLSYM) && !SWIFT_STDLIB_HAS_DLSYM) #define SWIFT_THREADING_TSAN_SUPPORT 0 @@ -35,6 +38,7 @@ template T *acquire(T *ptr) { return ptr; } template T *release(T *ptr) { return ptr; } } // namespace tsan + #else #define SWIFT_THREADING_TSAN_SUPPORT 1 diff --git a/lib/Threading/ThreadSanitizer.cpp b/lib/Threading/ThreadSanitizer.cpp index a103c161dce91..36a64b166e799 100644 --- a/lib/Threading/ThreadSanitizer.cpp +++ b/lib/Threading/ThreadSanitizer.cpp @@ -23,6 +23,8 @@ #include "swift/shims/Visibility.h" +#include + #include namespace swift { @@ -32,9 +34,6 @@ SWIFT_THREADING_EXPORT bool _swift_tsan_enabled = false; SWIFT_THREADING_EXPORT void (*_swift_tsan_acquire)(const void *) = nullptr; SWIFT_THREADING_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 void __tsan_on_initialize() { @@ -53,7 +52,6 @@ void __tsan_on_initialize() { next_init(); } } -#endif // __has_include() } // namespace threading_impl } // namespace swift diff --git a/stdlib/cmake/modules/AddSwiftStdlib.cmake b/stdlib/cmake/modules/AddSwiftStdlib.cmake index 25a79d145fb63..9cdb19c7e8167 100644 --- a/stdlib/cmake/modules/AddSwiftStdlib.cmake +++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake @@ -323,6 +323,16 @@ function(_add_target_variant_c_compile_flags) list(APPEND result "-DSWIFT_STDLIB_HAS_DLADDR") endif() + if(SWIFT_STDLIB_HAS_DLSYM) + list(APPEND result "-DSWIFT_STDLIB_HAS_DLSYM=1") + else() + list(APPEND result "-DSWIFT_STDLIB_HAS_DLSYM=0") + endif() + + if(SWIFT_STDLIB_HAS_FILESYSTEM) + list(APPEND result "-DSWIFT_STDLIB_HAS_FILESYSTEM") + endif() + if(SWIFT_RUNTIME_STATIC_IMAGE_INSPECTION) list(APPEND result "-DSWIFT_RUNTIME_STATIC_IMAGE_INSPECTION") endif() diff --git a/stdlib/cmake/modules/StdlibOptions.cmake b/stdlib/cmake/modules/StdlibOptions.cmake index 5b10f93ad9f33..4f5dde141d807 100644 --- a/stdlib/cmake/modules/StdlibOptions.cmake +++ b/stdlib/cmake/modules/StdlibOptions.cmake @@ -135,7 +135,15 @@ option(SWIFT_STDLIB_BUILD_PRIVATE TRUE) option(SWIFT_STDLIB_HAS_DLADDR - "Build stdlib assuming the runtime environment runtime environment provides dladdr API." + "Build stdlib assuming the runtime environment provides the dladdr API." + TRUE) + +option(SWIFT_STDLIB_HAS_DLSYM + "Build stdlib assuming the runtime environment provides the dlsym API." + TRUE) + +option(SWIFT_STDLIB_HAS_FILESYSTEM + "Build stdlib assuming the runtime environment has a filesystem." TRUE) option(SWIFT_RUNTIME_STATIC_IMAGE_INSPECTION diff --git a/utils/build-presets.ini b/utils/build-presets.ini index 8d2c3f5e32dad..1d1a17b1f0b4f 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -2550,6 +2550,8 @@ swift-enable-reflection=0 swift-stdlib-reflection-metadata=debugger-only swift-stdlib-stable-abi=0 swift-stdlib-has-dladdr=0 +swift-stdlib-has-dlsym=0 +swift-stdlib-has-filesystem=0 swift-stdlib-supports-backtrace-reporting=0 swift-stdlib-has-darwin-libmalloc=0 swift-stdlib-has-asl=0 diff --git a/utils/build-script-impl b/utils/build-script-impl index 1c5fd2a75285a..d4b29892b9dc5 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -206,6 +206,8 @@ KNOWN_SETTINGS=( swift-enable-reflection "1" "whether to support reflection and mirrors" swift-stdlib-reflection-metadata "enabled" "whether to build stdlib with runtime metadata (valid options are 'enabled', 'disabled' and 'debugger-only')" swift-stdlib-has-dladdr "1" "whether to build stdlib assuming the runtime environment provides dladdr API" + swift-stdlib-has-dlsym "1" "whether to build stdlib assuming the runtime environment provides the dlsym API" + swift-stdlib-has-filesystem "1" "whether to build stdlib assuming the runtime environment provides a filesystem" swift-stdlib-supports-backtrace-reporting "" "whether to build stdlib assuming the runtime environment provides the backtrace(3) API, if not set defaults to true on all platforms except for Cygwin, Haiku and wasm" swift-runtime-static-image-inspection "0" "whether to build stdlib assuming the runtime environment only supports a single runtime image with Swift code" swift-threading-package "" "override the threading package for the host build; this is either a single package or a semicolon-separated list of sdk:package pairs. Valid packages are empty string (no override), 'pthreads', 'darwin', 'linux', 'win32', 'c11', 'none'" @@ -1940,6 +1942,8 @@ for host in "${ALL_HOSTS[@]}"; do -DSWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY:BOOL=$(true_false "${SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY}") -DSWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS:BOOL=$(true_false "${SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS}") -DSWIFT_STDLIB_HAS_DLADDR:BOOL=$(true_false "${SWIFT_STDLIB_HAS_DLADDR}") + -DSWIFT_STDLIB_HAS_DLSYM:BOOL=$(true_false "${SWIFT_STDLIB_HAS_DLSYM}") + -DSWIFT_STDLIB_HAS_FILESYSTEM:BOOL=$(true_false "${SWIFT_STDLIB_HAS_FILESYSTEM}") -DSWIFT_RUNTIME_STATIC_IMAGE_INSPECTION:BOOL=$(true_false "${SWIFT_RUNTIME_STATIC_IMAGE_INSPECTION}") -DSWIFT_STDLIB_OS_VERSIONING:BOOL=$(true_false "${SWIFT_STDLIB_OS_VERSIONING}") -DSWIFT_STDLIB_HAS_COMMANDLINE:BOOL=$(true_false "${SWIFT_STDLIB_HAS_COMMANDLINE}")