[Build][Runtime] Replace SWIFT_STDLIB_SINGLE_THREADED_RUNTIME.

SWIFT_STDLIB_SINGLE_THREADED_RUNTIME is too much of a blunt instrument here.
It covers both the Concurrency runtime and the rest of the runtime, but we'd
like to be able to have e.g. a single-threaded Concurrency runtime while
the rest of the runtime is still thread safe (for instance).

So: rename it to SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY and make it just
control the Concurrency runtime, then add a SWIFT_STDLIB_THREADING_PACKAGE
setting at the CMake/build-script level, which defines
SWIFT_STDLIB_THREADING_xxx where xxx depends on the chosen threading package.

This is especially useful on systems where there may be a choice of threading
package that you could use.

rdar://90776105
This commit is contained in:
Alastair Houghton
2022-03-25 16:10:39 +00:00
parent 3c0b1ab03f
commit dadcb04ae2
44 changed files with 547 additions and 204 deletions

View File

@@ -66,6 +66,27 @@ else()
any compiler host sources written in Swift")
endif()
# A convenience pattern to match Darwin platforms. Example:
# if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}")
# ...
# endif()
set(SWIFT_DARWIN_VARIANTS "^(macosx|iphoneos|iphonesimulator|appletvos|appletvsimulator|watchos|watchsimulator)")
set(SWIFT_DARWIN_EMBEDDED_VARIANTS "^(iphoneos|iphonesimulator|appletvos|appletvsimulator|watchos|watchsimulator)")
# A convenient list to match Darwin SDKs. Example:
# if("${SWIFT_HOST_VARIANT_SDK}" IN_LIST SWIFT_DARWIN_PLATFORMS)
# ...
# endif()
set(SWIFT_DARWIN_PLATFORMS "IOS" "IOS_SIMULATOR" "TVOS" "TVOS_SIMULATOR" "WATCHOS" "WATCHOS_SIMULATOR" "OSX")
set(SWIFT_APPLE_PLATFORMS ${SWIFT_DARWIN_PLATFORMS})
if(SWIFT_FREESTANDING_FLAVOR STREQUAL "apple")
list(APPEND SWIFT_APPLE_PLATFORMS "FREESTANDING")
if(SWIFT_FREESTANDING_IS_DARWIN)
list(APPEND SWIFT_DARWIN_PLATFORMS "FREESTANDING")
endif()
endif()
#
# User-configurable options that control the inclusion and default build
# behavior for components which may not strictly be necessary (tools, examples,
@@ -103,6 +124,15 @@ option(SWIFT_STDLIB_ENABLE_UNICODE_DATA
NOTE: Disabling this will cause many String methods to crash."
TRUE)
include(Threading)
threading_package_default(SWIFT_STDLIB_THREADING_PACKAGE_default)
set(SWIFT_STDLIB_THREADING_PACKAGE "${SWIFT_STDLIB_THREADING_PACKAGE_default}"
CACHE STRING
"The threading package to use. Must be one of 'none', 'pthreads',
'darwin', 'win32', 'c11'.")
option(SWIFT_BUILD_DYNAMIC_SDK_OVERLAY
"Build dynamic variants of the Swift SDK overlay"
TRUE)
@@ -671,27 +701,6 @@ include_directories(BEFORE
${SWIFT_INCLUDE_DIR}
)
# A convenience pattern to match Darwin platforms. Example:
# if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}")
# ...
# endif()
set(SWIFT_DARWIN_VARIANTS "^(macosx|iphoneos|iphonesimulator|appletvos|appletvsimulator|watchos|watchsimulator)")
set(SWIFT_DARWIN_EMBEDDED_VARIANTS "^(iphoneos|iphonesimulator|appletvos|appletvsimulator|watchos|watchsimulator)")
# A convenient list to match Darwin SDKs. Example:
# if("${SWIFT_HOST_VARIANT_SDK}" IN_LIST SWIFT_DARWIN_PLATFORMS)
# ...
# endif()
set(SWIFT_DARWIN_PLATFORMS "IOS" "IOS_SIMULATOR" "TVOS" "TVOS_SIMULATOR" "WATCHOS" "WATCHOS_SIMULATOR" "OSX")
set(SWIFT_APPLE_PLATFORMS ${SWIFT_DARWIN_PLATFORMS})
if(SWIFT_FREESTANDING_FLAVOR STREQUAL "apple")
list(APPEND SWIFT_APPLE_PLATFORMS "FREESTANDING")
if(SWIFT_FREESTANDING_IS_DARWIN)
list(APPEND SWIFT_DARWIN_PLATFORMS "FREESTANDING")
endif()
endif()
# Configuration flags passed to all of our invocations of gyb. Try to
# avoid making up new variable names here if you can find a CMake
# variable that will do the job.
@@ -1037,11 +1046,12 @@ if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_SDK_OVERLAY)
message(STATUS " Leak Detection Checker Entrypoints: ${SWIFT_RUNTIME_ENABLE_LEAK_CHECKER}")
message(STATUS "")
message(STATUS "Threading Package: ${SWIFT_STDLIB_THREADING_PACKAGE}")
message(STATUS "Differentiable Programming Support: ${SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING}")
message(STATUS "Concurrency Support: ${SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY}")
message(STATUS "Distributed Support: ${SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED}")
message(STATUS "String Processing Support: ${SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING}")
message(STATUS "Unicode Support: ${SWIFT_STDLIB_ENABLE_UNICODE_DATA}")
message(STATUS "Concurrency Support: ${SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY}")
message(STATUS "Distributed Support: ${SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED}")
message(STATUS "String Processing Support: ${SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING}")
message(STATUS "Unicode Support: ${SWIFT_STDLIB_ENABLE_UNICODE_DATA}")
message(STATUS "")
else()
message(STATUS "Not building Swift standard library, SDK overlays, and runtime")

View File

@@ -23,4 +23,4 @@ set(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY YES CACHE BOOL "")
# build with the host compiler
set(SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER YES CACHE BOOL "")
set(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME TRUE CACHE BOOL "")
set(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY TRUE CACHE BOOL "")

View File

@@ -1,5 +1,6 @@
include(AddSwift)
include(Threading)
add_custom_target(SwiftUnitTests)
@@ -47,11 +48,15 @@ function(add_swift_unittest test_dirname)
endif()
# some headers switch their inline implementations based on
# SWIFT_STDLIB_SINGLE_THREADED_RUNTIME definition
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
# SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY and
# SWIFT_STDLIB_THREADING_PACKAGE definitions
if(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
target_compile_definitions("${test_dirname}" PRIVATE
SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
endif()
threading_package_name(_threading_package)
target_compile_definitions("${test_dirname}" PRIVATE
"SWIFT_STDLIB_THREADING_${_threading_package}")
if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
if(SWIFT_USE_LINKER)

View File

@@ -0,0 +1,27 @@
# Get the default threading package for the platform
function(threading_package_default out_var)
if("${SWIFT_HOST_VARIANT_SDK}" IN_LIST SWIFT_DARWIN_PLATFORMS)
set("${out_var}" "darwin" PARENT_SCOPE)
elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "WINDOWS")
set("${out_var}" "win32" PARENT_SCOPE)
elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "WASI")
set("${out_var}" "none" PARENT_SCOPE)
else()
set("${out_var}" "pthreads" PARENT_SCOPE)
endif()
endfunction()
# Given the threading package, find the name for the preprocessor
# define that we need to make. Also deals with the default platform
# setting.
function(threading_package_name out_var)
precondition(SWIFT_HOST_VARIANT_SDK)
precondition(SWIFT_DARWIN_PLATFORMS)
string(TOUPPER "${SWIFT_STDLIB_THREADING_PACKAGE}" package)
if(package STREQUAL "")
threading_package_default(package)
string(TOUPPER "${package}" package)
endif()
set("${out_var}" "${package}" PARENT_SCOPE)
endfunction()

View File

@@ -14,44 +14,26 @@
#define SWIFT_BASIC_LAZY_H
#include <memory>
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_THREADING_NONE
// No dependencies on single-threaded environments.
#elif defined(__APPLE__)
#elif SWIFT_STDLIB_THREADING_DARWIN
#include <dispatch/dispatch.h>
#elif defined(__wasi__)
// No pthread on wasi, see https://bugs.swift.org/browse/SR-12097 for more details.
#else
#include <mutex>
#endif
#include "swift/Basic/Malloc.h"
#include "swift/Basic/type_traits.h"
#if defined(__wasi__)
// Temporary single-threaded stub. Should be replaced with a thread-safe version
// as soon as the WASI SDK allows it. See https://bugs.swift.org/browse/SR-12766.
inline void wasi_call_once(int *flag, void *context, void (*func)(void *)) {
switch (*flag) {
case 0:
*flag = 1;
func(context);
return;
case 1:
return;
default:
assert(false && "wasi_call_once got invalid flag");
abort();
}
}
#endif
namespace swift {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_THREADING_NONE
using OnceToken_t = bool;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
if (!TOKEN) { TOKEN = true; (FUNC)(CONTEXT); }
#elif defined(__APPLE__)
using OnceToken_t = dispatch_once_t;
do { if (!TOKEN) { TOKEN = true; (FUNC)(CONTEXT); } } while (0)
#elif SWIFT_STDLIB_THREADING_DARWIN
using OnceToken_t = ::dispatch_once_t;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
::dispatch_once_f(&TOKEN, CONTEXT, FUNC)
#elif defined(__CYGWIN__)
@@ -62,10 +44,6 @@ namespace swift {
using OnceToken_t = unsigned long;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
_swift_once_f(&TOKEN, CONTEXT, FUNC)
#elif defined(__wasi__)
using OnceToken_t = int;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
::wasi_call_once(&TOKEN, CONTEXT, FUNC)
#else
using OnceToken_t = std::once_flag;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \

View File

@@ -26,7 +26,7 @@
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
// Does the runtime use a cooperative global executor?
#if defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
#if defined(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 1
#else
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 0

View File

@@ -30,14 +30,14 @@
#include <unistd.h>
#endif
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_THREADING_NONE
#include "swift/Runtime/MutexSingleThreaded.h"
#elif defined(_POSIX_THREADS)
#elif SWIFT_STDLIB_THREADING_PTHREADS || SWIFT_STDLIB_THREADING_DARWIN
#include "swift/Runtime/MutexPThread.h"
#elif defined(_WIN32)
#elif SWIFT_STDLIB_THREADING_WIN32
#include "swift/Runtime/MutexWin32.h"
#elif defined(__wasi__)
#include "swift/Runtime/MutexSingleThreaded.h"
#elif SWIFT_STDLIB_THREADING_C11
#include "swift/Runtime/MutexC11.h"
#else
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
#endif

View File

@@ -0,0 +1,162 @@
//===--- MutexC11.h - Supports Mutex.h using C11 threading ------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 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
//
//===----------------------------------------------------------------------===//
//
// Mutex, Read/Write lock, and Scoped lock implementations
// using C11 threading primtives.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_RUNTIME_MUTEX_C11_H
#define SWIFT_RUNTIME_MUTEX_C11_H
#include <threads.h>
namespace swift {
namespace c11threads {
class rwlock;
static void fatalError(int errcode);
static inline void handleError(int errcode) {
if (SWIFT_LIKELY(errcode == thrd_success))
return;
fatalError(errcode);
}
}
typedef c11threads::rwlock *ReadWriteLockHandle;
typedef ::mtx_t MutexHandle;
#define SWIFT_MUTEX_SUPPORTS_CONSTEXPR 0
#define SWIFT_READWRITELOCK_SUPPORTS_CONSTEXPR 0
/// C11 low-level implementation that supports Mutex
/// found in Mutex.h
///
/// See Mutex
class MutexPlatformHelper {
public:
static MutexHandle staticInit() {
::mtx_t mutex;
::mtx_init(&mutex, ::mtx_plain);
return mutex;
}
static void init(MutexHandle &mutex, bool checked = false) {
// C11 mutexes can't be checked
c11threads::handleError(::mtx_init(&mutex, ::mtx_plain));
}
static void destroy(MutexHandle &mutex) {
::mtx_destroy(&mutex);
}
static void lock(MutexHandle &mutex) {
c11threads::handleError(::mtx_lock(&mutex));
}
static void unlock(MutexHandle &mutex) {
c11threads::handleError(::mtx_unlock(&mutex));
}
static bool try_lock(MutexHandle &mutex) {
int err = ::mtx_trylock(&mutex);
switch (err) {
case thrd_success:
return true;
case thrd_busy:
return false;
default:
c11threads::handleError(err);
}
}
// Skip error checking for the unsafe versions.
static void unsafeLock(MutexHandle &mutex) {
(void)::mtx_lock(&mutex);
}
static void unsafeUnlock(MutexHandle &mutex) {
(void)::mtx_unlock(&mutex);
}
};
/// C11 low-level implementation that supports ReadWriteLock
/// found in Mutex.h
///
/// See ReadWriteLock
namespace c11threads {
class rwlock {
private:
unsigned activeReaders_;
unsigned waitingWriters_;
bool writerActive_;
::cnd_t cond_;
::mtx_t mutex_;
public:
rwlock();
~rwlock();
rwlock(const rwlock &other) = delete;
rwlock &operator=(const rwlock &other) = delete;
void readLock();
bool try_readLock();
void readUnlock();
void writeLock();
bool try_writeLock();
void writeUnlock();
};
}
class ReadWriteLockPlatformHelper {
public:
static ReadWriteLockHandle staticInit() {
return new c11threads::rwlock();
};
static void init(ReadWriteLockHandle &rwlock) {
rwlock = new c11threads::rwlock();
}
static void destroy(ReadWriteLockHandle &rwlock) {
delete rwlock;
}
static void readLock(ReadWriteLockHandle &rwlock) {
rwlock->readLock();
}
static bool try_readLock(ReadWriteLockHandle &rwlock) {
rwlock->try_readLock();
}
static void readUnlock(ReadWriteLockHandle &rwlock) {
rwlock->readUnlock();
}
static void writeLock(ReadWriteLockHandle &rwlock) {
rwlock->writeLock();
}
static bool try_writeLock(ReadWriteLockHandle &rwlock) {
rwlock->try_writeLock();
}
static void writeUnlock(ReadWriteLockHandle &rwlock) {
rwlock->writeUnlock();
}
};
}
#endif

View File

@@ -18,18 +18,23 @@
#define SWIFT_RUNTIME_ONCE_H
#include "swift/Runtime/HeapObject.h"
#if SWIFT_STDLIB_THREADING_DARWIN
#include <dispatch/dispatch.h>
#else
#include <mutex>
#endif
namespace swift {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
typedef bool swift_once_t;
#elif defined(__APPLE__)
#elif SWIFT_STDLIB_THREADING_DARWIN
// On OS X and iOS, swift_once_t matches dispatch_once_t.
typedef long swift_once_t;
// On OS X and iOS, swift_once_t is really a dispatch_once_t.
typedef dispatch_once_t swift_once_t;
#elif defined(__CYGWIN__)

View File

@@ -20,14 +20,15 @@
#include <type_traits>
#include "ThreadLocalStorage.h"
#include "Once.h"
/// SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL - Does the current configuration
/// allow the use of SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL?
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_THREADING_NONE
// We define SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL to nothing in this
// configuration and just use a global variable, so this is okay.
#define SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL 1
#elif defined(__APPLE__)
#elif SWIFT_STDLIB_THREADING_DARWIN
// The pthread TLS APIs work better than C++ TLS on Apple platforms.
#define SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL 0
#elif __has_feature(tls)
@@ -43,7 +44,7 @@
/// SWIFT_RUNTIME_THREAD_LOCAL - Declare that something is a
/// thread-local variable in the runtime.
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_THREADING_NONE
// In a single-threaded runtime, thread-locals are global.
#define SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL
#elif defined(__GNUC__)
@@ -81,14 +82,14 @@ namespace swift {
// SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL. This makes the object
// itself thread-local, and no internal support is required.
//
// Note that this includes platforms that set
// SWIFT_STDLIB_SINGLE_THREADED_RUNTIME, for which
// SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL is empty;
// Note that this includes platforms that don't support threading,
// for which SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL is empty;
// thread-local declarations then create an ordinary global.
//
// - On platforms that don't report SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL,
// we have to simulate thread-local storage. Fortunately, all of
// these platforms (at least for now) support pthread_getspecific.
// these platforms (at least for now) support pthread_getspecific
// or similar.
#if SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL
template <class T>
class ThreadLocal {
@@ -104,29 +105,30 @@ public:
void set(T newValue) { value = newValue; }
};
#else
// A wrapper around a pthread_key_t that is lazily initialized using
// A wrapper around a __swift_thread_key_t that is lazily initialized using
// dispatch_once.
class ThreadLocalKey {
// We rely on the zero-initialization of objects with static storage
// duration.
dispatch_once_t once;
pthread_key_t key;
swift_once_t once;
__swift_thread_key_t key;
public:
pthread_key_t getKey() {
dispatch_once_f(&once, &key, [](void *ctx) {
pthread_key_create(reinterpret_cast<pthread_key_t *>(ctx), nullptr);
});
__swift_thread_key_t getKey() {
swift_once(&once, [](void *ctx) {
SWIFT_THREAD_KEY_CREATE(reinterpret_cast<__swift_thread_key_t *>(ctx),
nullptr);
}, &key);
return key;
}
};
// A type representing a constant pthread_key_t, for use on platforms that
// provide reserved keys.
template <pthread_key_t constantKey>
// A type representing a constant __swift_thread_key_t, for use on platforms
// that provide reserved keys.
template <__swift_thread_key_t constantKey>
class ConstantThreadLocalKey {
public:
pthread_key_t getKey() { return constantKey; }
__swift_thread_key_t getKey() { return constantKey; }
};
template <class T, class Key>

View File

@@ -15,23 +15,30 @@
#include "swift/Runtime/Config.h"
#if SWIFT_STDLIB_THREADING_DARWIN || SWIFT_STDLIB_THREADING_PTHREADS
#include <pthread.h>
#elif SWIFT_STDLIB_THREADING_C11
#include <threads.h>
#elif SWIFT_STDLIB_THREADING_WIN32
# define WIN32_LEAN_AND_MEAN
# include <Windows.h>
#endif
// Depending on the target, we may be able to use dedicated TSD keys or
// thread_local variables. When dedicated TSD keys aren't available,
// wrap the target's API for thread-local data for things that don't want
// to use thread_local.
// On Apple platforms, we have dedicated TSD keys.
#if defined(__APPLE__)
#if SWIFT_STDLIB_THREADING_DARWIN
# define SWIFT_TLS_HAS_RESERVED_PTHREAD_SPECIFIC 1
#endif
#if SWIFT_TLS_HAS_RESERVED_PTHREAD_SPECIFIC
// Use reserved TSD keys.
# if __has_include(<pthread/tsd_private.h>)
# include <pthread/tsd_private.h>
# else
// We still need to use the SPI for setting the destructor, so declare it here.
extern "C" int pthread_key_init_np(int key, void (*destructor)(void *));
#define SWIFT_THREAD_KEY_INIT pthread_key_init_np
# endif
// If the keys are not available from the header, define them ourselves. The values match
@@ -83,46 +90,25 @@ extern "C" int pthread_key_init_np(int key, void (*destructor)(void *));
#ifndef SWIFT_THREAD_GETSPECIFIC
// Pick the right typedef for the key.
# if defined(__linux__)
# if defined(__ANDROID__)
typedef int __swift_thread_key_t;
# else
typedef unsigned int __swift_thread_key_t;
# endif
# elif defined(__FreeBSD__)
typedef int __swift_thread_key_t;
# elif defined(__OpenBSD__)
typedef int __swift_thread_key_t;
# elif defined(_WIN32)
typedef unsigned long __swift_thread_key_t;
# elif defined(__HAIKU__)
typedef int __swift_thread_key_t;
# else
typedef unsigned long __swift_thread_key_t;
# endif
# if defined(_WIN32) && !defined(__CYGWIN__)
// Windows has its own flavor of API.
# include <io.h>
# define WIN32_LEAN_AND_MEAN
# include <Windows.h>
#include <type_traits>
static_assert(std::is_same<__swift_thread_key_t, DWORD>::value,
"__swift_thread_key_t is not a DWORD");
#if SWIFT_STDLIB_THREADING_WIN32
typedef DWORD __swift_thread_key_t;
# define SWIFT_THREAD_KEY_CREATE _stdlib_thread_key_create
# define SWIFT_THREAD_GETSPECIFIC FlsGetValue
# define SWIFT_THREAD_SETSPECIFIC(key, value) (FlsSetValue(key, value) == FALSE)
# elif !defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
// Otherwise use the pthread API.
# include <pthread.h>
#elif SWIFT_STDLIB_THREADING_PTHREADS || SWIFT_STDLIB_THREADING_DARWIN
typedef pthread_key_t __swift_thread_key_t;
# define SWIFT_THREAD_KEY_CREATE pthread_key_create
# define SWIFT_THREAD_GETSPECIFIC pthread_getspecific
# define SWIFT_THREAD_SETSPECIFIC pthread_setspecific
# endif
#elif SWIFT_STDLIB_THREADING_C11
typedef tss_t __swift_thread_key_t;
# define SWIFT_THREAD_KEY_CREATE tss_create
# define SWIFT_THREAD_GETSPECIFIC tss_get
# define SWIFT_THREAD_SETSPECIFIC tss_set
#else
typedef unsigned long __swift_thread_key_t;
#endif
#endif
#endif // SWIFT_RUNTIME_THREADLOCALSTORAGE_H

View File

@@ -22,7 +22,7 @@
// swift-corelibs-libdispatch has os/voucher_private.h but it doesn't work for
// us yet, so only look for it on Apple platforms. We also don't need vouchers
// in the single threaded concurrency runtime.
#if __APPLE__ && !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME \
#if __APPLE__ && !SWIFT_STDLIB_THREADING_NONE \
&& __has_include(<os/voucher_private.h>)
#define SWIFT_HAS_VOUCHER_HEADER 1
#include <os/voucher_private.h>

View File

@@ -174,8 +174,8 @@ function(swift_create_stdlib_targets name variant define_all_alias)
endfunction()
if("${SWIFT_CONCURRENCY_GLOBAL_EXECUTOR}" STREQUAL "singlethreaded"
AND NOT SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
message(SEND_ERROR "Cannot enable the single-threaded global executor without enabling SWIFT_STDLIB_SINGLE_THREADED_RUNTIME")
AND NOT SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
message(SEND_ERROR "Cannot enable the single-threaded global executor without enabling SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY")
endif()
swift_create_stdlib_targets("swift-stdlib" "" TRUE)

View File

@@ -1,6 +1,7 @@
include(AddSwift)
include(SwiftSource)
include(Threading)
function(add_dependencies_multiple_targets)
cmake_parse_arguments(
@@ -350,10 +351,13 @@ function(_add_target_variant_c_compile_flags)
list(APPEND result "-DSWIFT_STDLIB_HAS_LOCALE")
endif()
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
list(APPEND result "-DSWIFT_STDLIB_SINGLE_THREADED_RUNTIME")
if(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
list(APPEND result "-DSWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY")
endif()
threading_package_name(_threading_package)
list(APPEND result "-DSWIFT_STDLIB_THREADING_${_threading_package}")
if(SWIFT_STDLIB_OS_VERSIONING)
list(APPEND result "-DSWIFT_RUNTIME_OS_VERSIONING")
endif()

View File

@@ -1,6 +1,8 @@
include_guard(GLOBAL)
include(${CMAKE_CURRENT_LIST_DIR}/../../../cmake/modules/SwiftUtils.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../../../cmake/modules/Threading.cmake)
precondition(SWIFT_HOST_VARIANT_SDK)
precondition(SWIFT_DARWIN_PLATFORMS)
@@ -166,11 +168,11 @@ option(SWIFT_STDLIB_HAS_ENVIRON
"Build stdlib assuming the platform supports environment variables."
TRUE)
option(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
option(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
"Build the standard libraries assuming that they will be used in an environment with only a single thread."
FALSE)
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
if(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
set(SWIFT_CONCURRENCY_GLOBAL_EXECUTOR_default "singlethreaded")
else()
set(SWIFT_CONCURRENCY_GLOBAL_EXECUTOR_default "dispatch")

View File

@@ -1,5 +1,6 @@
include(macCatalystUtils)
include(SwiftUtils)
include(Threading)
function(_compute_lto_swift_flag option out_var)
string(TOLOWER "${option}" lowercase_option)
@@ -322,10 +323,13 @@ function(_add_target_variant_swift_compile_flags
list(APPEND result "-Xcc" "-DSWIFT_STDLIB_HAS_ENVIRON")
endif()
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
list(APPEND result "-D" "SWIFT_STDLIB_SINGLE_THREADED_RUNTIME")
if(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
list(APPEND result "-D" "SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY")
endif()
threading_package_name(_threading_package)
list(APPEND result "-D" "SWIFT_STDLIB_THREADING_${_threading_package}")
set("${result_var_name}" "${result}" PARENT_SCOPE)
endfunction()
@@ -479,7 +483,7 @@ function(_compile_swift_files
list(APPEND swift_flags "-Xfrontend" "-library-level" "-Xfrontend" "api")
endif()
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
if(SWIFT_STDLIB_THREADING_PACKAGE STREQUAL "none")
list(APPEND swift_flags "-Xfrontend" "-assume-single-threaded")
endif()

View File

@@ -619,12 +619,6 @@ class _InterruptibleSleep {
}
#endif
#if os(Windows)
typealias ThreadHandle = HANDLE
#else
typealias ThreadHandle = pthread_t
#endif
public func runRaceTest<RT : RaceTestWithPerTrialData>(
_: RT.Type,
trials: Int,

View File

@@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.19.6)
include("${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/modules/StandaloneOverlay.cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules")
set(SWIFT_STDLIB_STABLE_ABI TRUE)
set(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME FALSE)
set(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY FALSE)
set(SWIFT_CONCURRENCY_GLOBAL_EXECUTOR "dispatch")
include(AddSwiftStdlib)

View File

@@ -287,7 +287,7 @@ static HANDLE __initialPthread = INVALID_HANDLE_VALUE;
/// Determine whether we are currently executing on the main thread
/// independently of whether we know that we are on the main actor.
static bool isExecutingOnMainThread() {
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
return true;
#elif defined(__linux__)
return syscall(SYS_gettid) == getpid();
@@ -307,7 +307,7 @@ static bool isExecutingOnMainThread() {
}
JobPriority swift::swift_task_getCurrentThreadPriority() {
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
return JobPriority::UserInitiated;
#elif defined(__APPLE__)
return static_cast<JobPriority>(qos_class_self());

View File

@@ -93,7 +93,7 @@ func _checkExpectedExecutor(_filenameStart: Builtin.RawPointer,
_filenameStart, _filenameLength, _filenameIsASCII, _line, _executor)
}
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
// This must take a DispatchQueueShim, not something like AnyObject,
// or else SILGen will emit a retain/release in unoptimized builds,
// which won't work because DispatchQueues aren't actually

View File

@@ -19,6 +19,7 @@
#include "../runtime/MutexPThread.cpp"
#include "../runtime/MutexWin32.cpp"
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#include "../runtime/MutexC11.cpp"
#ifdef SWIFT_STDLIB_THREADING_NONE
#include "swift/Runtime/MutexSingleThreaded.h"
#endif

View File

@@ -34,6 +34,11 @@
#include "queue" // TODO: remove and replace with usage of our mpsc queue
#include <atomic>
#include <new>
#if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
#include <mutex>
#endif
#include <assert.h>
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
#include <dispatch/dispatch.h>
@@ -280,7 +285,7 @@ public:
private:
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
// TODO: move to lockless via the status atomic (make readyQueue an mpsc_queue_t<ReadyQueueItem>)
mutable std::mutex mutex_;

View File

@@ -114,7 +114,7 @@ void _swift_tsan_release(void *addr);
/// executors.
#define DISPATCH_QUEUE_GLOBAL_EXECUTOR (void *)1
#if !defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
#if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
inline SerialExecutorWitnessTable *
_swift_task_getDispatchQueueSerialExecutorWitnessTable() {
extern SerialExecutorWitnessTable wtable

View File

@@ -59,6 +59,7 @@ set(swift_runtime_sources
KnownMetadata.cpp
Metadata.cpp
MetadataLookup.cpp
MutexC11.cpp
MutexPThread.cpp
MutexWin32.cpp
Numeric.cpp

View File

@@ -350,7 +350,7 @@ static HeapObject *_swift_retain_(HeapObject *object) {
}
HeapObject *swift::swift_retain(HeapObject *object) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
return swift_nonatomic_retain(object);
#else
CALL_IMPL(swift_retain, (object));
@@ -377,7 +377,7 @@ static HeapObject *_swift_retain_n_(HeapObject *object, uint32_t n) {
}
HeapObject *swift::swift_retain_n(HeapObject *object, uint32_t n) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
return swift_nonatomic_retain_n(object, n);
#else
CALL_IMPL(swift_retain_n, (object, n));
@@ -403,7 +403,7 @@ static void _swift_release_(HeapObject *object) {
}
void swift::swift_release(HeapObject *object) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
swift_nonatomic_release(object);
#else
CALL_IMPL(swift_release, (object));
@@ -428,7 +428,7 @@ static void _swift_release_n_(HeapObject *object, uint32_t n) {
}
void swift::swift_release_n(HeapObject *object, uint32_t n) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
swift_nonatomic_release_n(object, n);
#else
CALL_IMPL(swift_release_n, (object, n));
@@ -460,7 +460,7 @@ size_t swift::swift_weakRetainCount(HeapObject *object) {
}
HeapObject *swift::swift_unownedRetain(HeapObject *object) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
return static_cast<HeapObject *>(swift_nonatomic_unownedRetain(object));
#else
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRetain);
@@ -473,7 +473,7 @@ HeapObject *swift::swift_unownedRetain(HeapObject *object) {
}
void swift::swift_unownedRelease(HeapObject *object) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
swift_nonatomic_unownedRelease(object);
#else
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRelease);
@@ -520,7 +520,7 @@ void swift::swift_nonatomic_unownedRelease(HeapObject *object) {
}
HeapObject *swift::swift_unownedRetain_n(HeapObject *object, int n) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
return swift_nonatomic_unownedRetain_n(object, n);
#else
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRetain_n);
@@ -533,7 +533,7 @@ HeapObject *swift::swift_unownedRetain_n(HeapObject *object, int n) {
}
void swift::swift_unownedRelease_n(HeapObject *object, int n) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
swift_nonatomic_unownedRelease_n(object, n);
#else
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRelease_n);
@@ -583,7 +583,7 @@ static HeapObject *_swift_tryRetain_(HeapObject *object) {
if (!isValidPointerForNativeRetain(object))
return nullptr;
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
if (object->refCounts.tryIncrementNonAtomic()) return object;
else return nullptr;
#else
@@ -612,7 +612,7 @@ void swift::swift_setDeallocating(HeapObject *object) {
}
HeapObject *swift::swift_unownedRetainStrong(HeapObject *object) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
return swift_nonatomic_unownedRetainStrong(object);
#else
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRetainStrong);
@@ -640,7 +640,7 @@ HeapObject *swift::swift_nonatomic_unownedRetainStrong(HeapObject *object) {
}
void swift::swift_unownedRetainStrongAndRelease(HeapObject *object) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
swift_nonatomic_unownedRetainStrongAndRelease(object);
#else
SWIFT_RT_TRACK_INVOCATION(object, swift_unownedRetainStrongAndRelease);

View File

@@ -137,7 +137,7 @@ template <class Impl, class T> struct RetainableBoxBase {
static constexpr size_t stride = sizeof(T);
static constexpr bool isPOD = false;
static constexpr bool isBitwiseTakable = true;
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
static constexpr bool isAtomic = false;
#else
static constexpr bool isAtomic = true;

View File

@@ -0,0 +1,110 @@
//===--- MutexC11.cpp - Supports Mutex.h using C11 threads ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 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
//
//===----------------------------------------------------------------------===//
//
// Mutex and Read/Write lock implementations using C11 threads.
//
//===----------------------------------------------------------------------===//
#include "swift/Runtime/Mutex.h"
#include "swift/Runtime/Debug.h"
#if SWIFT_STDLIB_THREADING_C11
using namespace swift;
namespace {
// A simple scoped locker class for a C11 mutex
class locker {
private:
mtx_t &mutex_;
public:
explicit locker(mtx_t &mutex) : mutex_(mutex) {
c11threads::handleError(mtx_lock(&mutex_));
}
~locker() {
c11threads::handleError(mtx_unlock(&mutex_));
}
};
}
namespace c11threads {
#ifndef SWIFT_FATAL_ERROR
#define SWIFT_FATAL_ERROR swift::fatalError
#endif
// Triggered if a C11 threads call fails
void fatalError(int errcode) {
SWIFT_FATAL_ERROR(0, "C11 threads call failed with %d\n", errcode);
}
// A simple reader/writer lock implementation, with writer priority
rwlock::rwlock() : activeReaders_(0), waitingWriters_(0), writerActive_(false) {
handleError(::cnd_init(&cond_));
handleError(::mtx_init(&mutex_, ::mtx_plain));
}
rwlock::~rwlock() {
::cnd_destroy(&cond_);
::mtx_destroy(&mutex_);
}
void rwlock::readLock() {
locker l(mutex_);
while (waitingWriters_ || writerActive_)
handleError(::cnd_wait(&cond_, &mutex_));
++activeReaders_;
}
bool rwlock::try_readLock() {
locker l(mutex_);
if (waitingWriters_ || writerActive_)
return false;
++activeReaders_;
return true;
}
void rwlock::readUnlock() {
locker l(mutex_);
if (!--activeReaders_)
handleError(::cnd_broadcast(&cond_));
}
void rwlock::writeLock() {
locker l(mutex_);
++waitingWriters_;
while (activeReaders_ || writerActive_)
handleError(::cnd_wait(&cond_, mutex_));
--waitingWriters_;
writerActive_ = true;
}
bool rwlock::try_writeLock() {
locker l(mutex_);
if (activeReaders_ || writerActive_)
return false;
writerActive_ = true;
return true;
}
void rwlock::writeUnlock() {
locker l(mutex_);
writerActive_ = false;
handleError(::cnd_broadcast(&cond_));
}
}
#endif // SWIFT_STDLIB_THREADING_C11

View File

@@ -17,12 +17,12 @@
//
//===----------------------------------------------------------------------===//
#if SWIFT_STDLIB_THREADING_PTHREADS || SWIFT_STDLIB_THREADING_DARWIN
#if __has_include(<unistd.h>)
#include <unistd.h>
#endif
#if defined(_POSIX_THREADS) && !defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
// Notes: swift::fatalError is not shared between libswiftCore and libswift_Concurrency
// and libswift_Concurrency uses swift_Concurrency_fatalError instead.
#ifndef SWIFT_FATAL_ERROR
@@ -139,4 +139,5 @@ void ReadWriteLockPlatformHelper::readUnlock(pthread_rwlock_t &rwlock) {
void ReadWriteLockPlatformHelper::writeUnlock(pthread_rwlock_t &rwlock) {
reportError(pthread_rwlock_unlock(&rwlock));
}
#endif
#endif // SWIFT_STDLIB_THREADING_PTHREADS

View File

@@ -21,11 +21,11 @@
using namespace swift;
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#if SWIFT_STDLIB_THREADING_NONE
// No dependencies on single-threaded environments.
#elif defined(__APPLE__)
#elif SWIFT_STDLIB_THREADING_DARWIN
// On macOS and iOS, swift_once is implemented using GCD.
// The compiler emits an inline check matching the barrier-free inline fast
@@ -52,16 +52,16 @@ static_assert(sizeof(swift_once_t) <= sizeof(void*),
/// extent of type swift_once_t.
void swift::swift_once(swift_once_t *predicate, void (*fn)(void *),
void *context) {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
if (! *predicate) {
*predicate = true;
fn(context);
}
#elif defined(__APPLE__)
#elif SWIFT_STDLIB_THREADING_DARWIN
dispatch_once_f(predicate, context, fn);
#elif defined(__CYGWIN__)
_swift_once_f(predicate, context, fn);
#else
std::call_once(*predicate, [fn, context]() { fn(context); });
std::call_once(*predicate, fn, context);
#endif
}

View File

@@ -18,7 +18,7 @@
using namespace swift;
using namespace swift::runtime;
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
SwiftTLSContext &SwiftTLSContext::get() {
static SwiftTLSContext TLSContext;
@@ -38,7 +38,7 @@ SwiftTLSContext &SwiftTLSContext::get() {
SWIFT_ONCE_F(
setupToken,
[](void *) {
pthread_key_init_np(SWIFT_RUNTIME_TLS_KEY, [](void *pointer) {
SWIFT_THREAD_KEY_INIT(SWIFT_RUNTIME_TLS_KEY, [](void *pointer) {
delete static_cast<SwiftTLSContext *>(pointer);
});
},

View File

@@ -484,7 +484,7 @@ int _swift_stdlib_putc_stderr(int C) {
}
size_t _swift_stdlib_getHardwareConcurrency() {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
return 1;
#else
return std::thread::hardware_concurrency();
@@ -537,16 +537,17 @@ __swift_bool swift_stdlib_isStackAllocationSafe(__swift_size_t byteCount,
__swift_bool _swift_stdlib_getCurrentStackBounds(__swift_uintptr_t *outBegin,
__swift_uintptr_t *outEnd) {
#if defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
#if SWIFT_STDLIB_THREADING_NONE
// This platform does not support threads, so the API we'd call to get stack
// bounds (i.e. libpthread) is not going to be usable.
return false;
#elif defined(__APPLE__)
#elif SWIFT_STDLIB_THREADING_DARWIN
pthread_t thread = pthread_self();
// On Apple platforms, the stack grows down, so that the end of the stack
// comes before the beginning on the number line, and an address on the stack
// will be LESS than the start of the stack and GREATER than the end.
// On Apple platforms, pthread_get_stackaddr_np() gets the address of the
// *end* of the stack (i.e. the highest address in stack space), *NOT* the
// address of the *base* of the stack (the lowest address).
void *end = pthread_get_stackaddr_np(thread);
if (!end) {
return false;
@@ -555,15 +556,29 @@ __swift_bool _swift_stdlib_getCurrentStackBounds(__swift_uintptr_t *outBegin,
*outBegin = *outEnd - pthread_get_stacksize_np(thread);
return true;
#elif defined(_WIN32) && (_WIN32_WINNT >= 0x0602)
#elif SWIFT_STDLIB_THREADING_C11
// We don't know any way to do this for C11 threads
return false
#elif SWIFT_STDLIB_THREADING_WIN32
# if _WIN32_WINNT >= 0x0602
ULONG_PTR lowLimit = 0;
ULONG_PTR highLimit = 0;
GetCurrentThreadStackLimits(&lowLimit, &highLimit);
*outBegin = lowLimit;
*outEnd = highLimit;
return true;
# else
// Need _WIN32_WINNT to be 0x0602 or higher to use
// GetCurrentThreadStackLimits(). We could use VirtualQuery() instead,
// and give it the address of a page we know is on the stack?
return false;
# endif
#elif defined(__OpenBSD__)
#elif SWIFT_STDLIB_THREADING_PTHREADS
# if defined(__OpenBSD__)
stack_t sinfo;
if (pthread_stackseg_np(pthread_self(), &sinfo) != 0) {
return false;
@@ -572,18 +587,18 @@ __swift_bool _swift_stdlib_getCurrentStackBounds(__swift_uintptr_t *outBegin,
*outBegin = (uintptr_t)sinfo.ss_sp - sinfo.ss_size;
*outEnd = (uintptr_t)sinfo.ss_sp;
return true;
#elif defined(__FreeBSD__) || defined(__ANDROID__) || defined(__linux__)
# elif defined(__FreeBSD__) || defined(__ANDROID__) || defined(__linux__)
pthread_attr_t attr;
#if defined(__FreeBSD__)
# if defined(__FreeBSD__)
if (0 != pthread_attr_init(&attr) || 0 != pthread_attr_get_np(pthread_self(), &attr)) {
return false;
}
#else
# else
if (0 != pthread_getattr_np(pthread_self(), &attr)) {
return false;
}
#endif
# endif
void *begin = nullptr;
size_t size = 0;
@@ -594,9 +609,12 @@ __swift_bool _swift_stdlib_getCurrentStackBounds(__swift_uintptr_t *outBegin,
pthread_attr_destroy(&attr);
return success;
# else
# warning Please teach _swift_stdlib_getCurrentStackBounds() about your platform
return false;
# endif
#else
// FIXME: implement on this platform
return false;
# error Unknown threading package selected; please teach _swift_stdlib_getCurrentStackBounds() what to do.
#endif
}

View File

@@ -54,7 +54,7 @@ _stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
#endif
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifdef SWIFT_STDLIB_THREADING_NONE
SWIFT_RUNTIME_STDLIB_INTERNAL
void *
@@ -77,7 +77,7 @@ _swift_stdlib_threadLocalStorageGet(void) {
static swift::OnceToken_t token;
SWIFT_ONCE_F(token, [](void *) {
int result = pthread_key_init_np(SWIFT_STDLIB_TLS_KEY, [](void *pointer) {
int result = SWIFT_THREAD_KEY_INIT(SWIFT_STDLIB_TLS_KEY, [](void *pointer) {
_stdlib_destroyTLS(pointer);
});
if (result != 0)

View File

@@ -199,7 +199,7 @@ normalize_boolean_spelling(SWIFT_ENABLE_MACCATALYST)
normalize_boolean_spelling(SWIFT_RUN_TESTS_WITH_HOST_COMPILER)
normalize_boolean_spelling(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER)
normalize_boolean_spelling(SWIFT_OPTIMIZED)
normalize_boolean_spelling(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
normalize_boolean_spelling(SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY)
normalize_boolean_spelling(SWIFT_ENABLE_REFLECTION)
normalize_boolean_spelling(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS)
normalize_boolean_spelling(SWIFT_STDLIB_ENABLE_DEBUG_PRECONDITIONS_IN_RELEASE)

View File

@@ -8,7 +8,7 @@
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
// Disable on cooperative executor because it can't dispatch jobs before the end of main function
// UNSUPPORTED: single_threaded_runtime
// UNSUPPORTED: single_threaded_concurrency
// REQUIRES: rdar80824152
import Dispatch

View File

@@ -5,7 +5,7 @@
// rdar://76038845
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
// UNSUPPORTED: single_threaded_runtime
// UNSUPPORTED: single_threaded_concurrency
// for sleep
#if canImport(Darwin)

View File

@@ -8,7 +8,7 @@
// rdar://76038845
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
// UNSUPPORTED: single_threaded_runtime
// UNSUPPORTED: single_threaded_concurrency
import _Concurrency
import Dispatch

View File

@@ -7,7 +7,7 @@
// rdar://76038845
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
// UNSUPPORTED: single_threaded_runtime
// UNSUPPORTED: single_threaded_concurrency
import Dispatch

View File

@@ -4,7 +4,7 @@
// RUN: %target-codesign %t/a.out
// RUN: %target-run %t/a.out
// REQUIRES: executable_test
// UNSUPPORTED: single_threaded_runtime
// REQUIRES: thread_safe_runtime
// UNSUPPORTED: use_os_stdlib

View File

@@ -96,8 +96,13 @@ else:
if "@SWIFT_OPTIMIZED@" == "TRUE":
config.available_features.add("optimized_stdlib")
if "@SWIFT_STDLIB_SINGLE_THREADED_RUNTIME@" == "TRUE":
config.available_features.add("single_threaded_runtime")
if "@SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY@" == "TRUE":
config.available_features.add("single_threaded_concurrency")
if "@SWIFT_STDLIB_THREADING_PACKAGE@" != "none":
# This is not called "threading" because we might want that later
config.available_features.add("thread_safe_runtime")
config.available_features.add("threading_@SWIFT_STDLIB_THREADING_PACKAGE@")
if "@SWIFT_ENABLE_REFLECTION@" == "TRUE":
config.available_features.add("reflection")

View File

@@ -84,7 +84,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
endif()
endif()
if(NOT SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
if(NOT "${SWIFT_STDLIB_THREADING_PACKAGE}" STREQUAL "none")
list(APPEND PLATFORM_SOURCES Mutex.cpp)
endif()

View File

@@ -45,7 +45,7 @@ TEST(ConcurrentReadableArrayTest, SingleThreaded) {
check();
}
#ifndef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#ifndef SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
TEST(ConcurrentReadableArrayTest, MultiThreaded) {
const int insertCount = 100000;
@@ -544,4 +544,4 @@ TEST(ConcurrentReadableHashMapTest, MultiThreaded4) {
runTest(16, 1);
runTest(16, 8);
}
#endif // !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#endif // !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY

View File

@@ -1205,7 +1205,8 @@ mixin-preset=buildbot_incremental_linux_base
llvm-targets-to-build=X86;ARM;AArch64;WebAssembly
# Ensure single-thread-mode is not broken because it's used
# by stdlib for wasm32 in SwiftWasm fork.
swift-stdlib-single-threaded-runtime=1
swift-stdlib-threading-package=none
swift-stdlib-single-threaded-concurrency=1
#===------------------------------------------------------------------------===#
# OS X Package Builders
@@ -2508,7 +2509,8 @@ swift-stdlib-has-stdin=0
swift-stdlib-has-environ=0
swift-stdlib-has-locale=0
swift-runtime-static-image-inspection=1
swift-stdlib-single-threaded-runtime=1
swift-stdlib-threading-package=none
swift-stdlib-single-threaded-concurrency=1
swift-stdlib-concurrency-tracing=0
swift-stdlib-os-versioning=0
swift-stdlib-has-commandline=0

View File

@@ -206,7 +206,8 @@ KNOWN_SETTINGS=(
swift-stdlib-has-dladdr "1" "whether to build stdlib assuming the runtime environment provides dladdr API"
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-stdlib-single-threaded-runtime "0" "whether to build stdlib as a single-threaded runtime only"
swift-stdlib-threading-package "" "which threading package to use for Swift; valid values are empty string (default based on platform), 'pthreads', 'darwin', 'win32', 'c11', 'none'"
swift-stdlib-single-threaded-concurrency "0" "build Swift concurrency in single-threaded mode"
swift-stdlib-concurrency-tracing "" "whether to enable tracing signposts for concurrency; default is 1 on Darwin platforms, 0 otherwise"
swift-stdlib-os-versioning "1" "whether to build stdlib with availability based on OS versions (Darwin only)"
swift-stdlib-has-commandline "1" "whether to build stdlib with the CommandLine enum and support for argv/argc"
@@ -2012,7 +2013,7 @@ for host in "${ALL_HOSTS[@]}"; do
-DSWIFT_ENABLE_DISPATCH:BOOL=$(true_false "${SWIFT_ENABLE_DISPATCH}")
-DSWIFT_IMPLICIT_CONCURRENCY_IMPORT:BOOL=$(true_false "${SWIFT_IMPLICIT_CONCURRENCY_IMPORT}")
-DSWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT:BOOL=$(true_false "${SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT}")
-DSWIFT_STDLIB_SINGLE_THREADED_RUNTIME:BOOL=$(true_false "${SWIFT_STDLIB_SINGLE_THREADED_RUNTIME}")
-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_RUNTIME_STATIC_IMAGE_INSPECTION:BOOL=$(true_false "${SWIFT_RUNTIME_STATIC_IMAGE_INSPECTION}")
@@ -2234,6 +2235,21 @@ for host in "${ALL_HOSTS[@]}"; do
)
fi
if [[ "${SWIFT_STDLIB_THREADING_PACKAGE}" ]] ; then
case "${SWIFT_STDLIB_THREADING_PACKAGE}" in
"" | pthreads | darwin | win32 | c11 | none) ;;
*)
echo "build-script: unknown threading package ${SWIFT_STDLIB_THREADING_PACKAGE}; must be one of 'pthreads', 'darwin', 'win32', 'c11', 'none', or empty for platform default" >&2
exit 1
;;
esac
cmake_options=(
"${cmake_options[@]}"
-DSWIFT_STDLIB_THREADING_PACKAGE:STRING="${SWIFT_STDLIB_THREADING_PACKAGE}"
)
fi
build_targets=(all "${SWIFT_STDLIB_TARGETS[@]}")
if [[ $(true_false "${build_perf_testsuite_this_time}") == "TRUE" ]]; then
native_swift_tools_path="$(build_directory_bin ${LOCAL_HOST} swift)"

View File

@@ -94,8 +94,13 @@ if "@SWIFT_OPTIMIZED@" == "TRUE":
if "@SWIFT_ENABLE_SOURCEKIT_TESTS@" == "TRUE":
config.available_features.add('sourcekit')
if "@SWIFT_STDLIB_SINGLE_THREADED_RUNTIME@" == "TRUE":
config.available_features.add("single_threaded_runtime")
if "@SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY@" == "TRUE":
config.available_features.add("single_threaded_concurrency")
if "@SWIFT_STDLIB_THREADING_PACKAGE@" != "none":
# This is not called "threading" because we might want that later
config.available_features.add("thread_safe_runtime")
config.available_features.add("threading_@SWIFT_STDLIB_THREADING_PACKAGE@")
if "@SWIFT_ENABLE_REFLECTION@" == "TRUE":
config.available_features.add("reflection")