Skip to content

Add a single-threaded stdlib mode, use it for the 'minimal' stdlib #33437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,6 @@ option(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
"Should the runtime be built with support for non-thread-safe leak detecting entrypoints"
FALSE)

option(SWIFT_STDLIB_USE_NONATOMIC_RC
"Build the standard libraries and overlays with nonatomic reference count operations enabled"
FALSE)

option(SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS
"Enable runtime function counters and expose the API."
FALSE)
Expand Down
10 changes: 8 additions & 2 deletions include/swift/Basic/Lazy.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#define SWIFT_BASIC_LAZY_H

#include <memory>
#ifdef __APPLE__
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
// No dependencies on single-threaded environments.
#elif defined(__APPLE__)
#include <dispatch/dispatch.h>
#elif defined(__wasi__)
// No pthread on wasi, see https://bugs.swift.org/browse/SR-12097 for more details.
Expand Down Expand Up @@ -44,7 +46,11 @@ inline void wasi_call_once(int *flag, void *context, void (*func)(void *)) {

namespace swift {

#ifdef __APPLE__
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
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;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
::dispatch_once_f(&TOKEN, CONTEXT, FUNC)
Expand Down
6 changes: 4 additions & 2 deletions include/swift/Runtime/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
#include <unistd.h>
#endif

#if defined(_POSIX_THREADS)
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
#include "swift/Runtime/MutexSingleThreaded.h"
#elif defined(_POSIX_THREADS)
#include "swift/Runtime/MutexPThread.h"
#elif defined(_WIN32)
#include "swift/Runtime/MutexWin32.h"
#elif defined(__wasi__)
#include "swift/Runtime/MutexWASI.h"
#include "swift/Runtime/MutexSingleThreaded.h"
#else
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===--- MutexWASI.h - -----------------------------------------*- C++ -*-===//
//===--- MutexSingleThreaded.h - --------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
Expand All @@ -10,16 +10,12 @@
//
//===----------------------------------------------------------------------===//
//
// No-op implementation of locks for the WebAssembly System Interface. The
// implementation does not need to perform locking, because as of January 2020
// WebAssembly does not support threads.
// See the current status at https://github.com/WebAssembly/proposals and
// https://github.com/webassembly/threads
// No-op implementation of locks for single-threaded environments.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_RUNTIME_MUTEX_WASI_H
#define SWIFT_RUNTIME_MUTEX_WASI_H
#ifndef SWIFT_RUNTIME_MUTEX_SINGLE_THREADED_H
#define SWIFT_RUNTIME_MUTEX_SINGLE_THREADED_H

namespace swift {

Expand Down
6 changes: 5 additions & 1 deletion include/swift/Runtime/Once.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@

namespace swift {

#ifdef __APPLE__
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME

typedef bool swift_once_t;

#elif defined(__APPLE__)

// On OS X and iOS, swift_once_t matches dispatch_once_t.
typedef long swift_once_t;
Expand Down
12 changes: 12 additions & 0 deletions stdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ option(SWIFT_RUNTIME_MACHO_NO_DYLD
"Build stdlib assuming the runtime environment uses Mach-O but does not support dynamic modules."
FALSE)

option(SWIFT_STDLIB_USE_NONATOMIC_RC
"Build the standard libraries and overlays with nonatomic reference count operations enabled"
FALSE)

option(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
"Build the standard libraries assuming that they will be used in an environment with only a single thread. If set, also forces SWIFT_STDLIB_USE_NONATOMIC_RC to On."
FALSE)

if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
set(SWIFT_STDLIB_USE_NONATOMIC_RC TRUE)
endif()

#
# End of user-configurable options.
#
Expand Down
8 changes: 8 additions & 0 deletions stdlib/cmake/modules/AddSwiftStdlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,14 @@ function(_add_target_variant_c_compile_flags)
list(APPEND result "-DSWIFT_RUNTIME_MACHO_NO_DYLD")
endif()

if(SWIFT_STDLIB_USE_NONATOMIC_RC)
list(APPEND result "-DSWIFT_STDLIB_USE_NONATOMIC_RC")
endif()

if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
list(APPEND result "-DSWIFT_STDLIB_SINGLE_THREADED_RUNTIME")
endif()

set("${CFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE)
endfunction()

Expand Down
4 changes: 0 additions & 4 deletions stdlib/public/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,16 +152,12 @@ if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX")
INSTALL_IN_COMPONENT never_install)
endif()

if(SWIFT_STDLIB_USE_NONATOMIC_RC)
set(_RUNTIME_NONATOMIC_FLAGS -DSWIFT_STDLIB_USE_NONATOMIC_RC)
endif()
add_swift_target_library(swiftRuntime OBJECT_LIBRARY
${swift_runtime_sources}
${swift_runtime_objc_sources}
${swift_runtime_leaks_sources}
C_COMPILE_FLAGS
${swift_runtime_library_compile_flags}
${_RUNTIME_NONATOMIC_FLAGS}
LINK_FLAGS ${swift_runtime_linker_flags}
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
INSTALL_IN_COMPONENT never_install)
Expand Down
9 changes: 8 additions & 1 deletion stdlib/public/runtime/Exclusivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,14 @@ class SwiftTLSContext {
// Each of these cases should define a function with this prototype:
// AccessSets &getAllSets();

#if SWIFT_TLS_HAS_RESERVED_PTHREAD_SPECIFIC
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME

static SwiftTLSContext &getTLSContext() {
static SwiftTLSContext TLSContext;
return TLSContext;
}

#elif SWIFT_TLS_HAS_RESERVED_PTHREAD_SPECIFIC
// Use the reserved TSD key if possible.

static SwiftTLSContext &getTLSContext() {
Expand Down
18 changes: 15 additions & 3 deletions stdlib/public/runtime/MetadataCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,10 +775,22 @@ class MetadataCacheEntryBase
using super::asImpl;

private:
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
using ThreadID = int;
static ThreadID CurrentThreadID() {
return 0;
}
#else
using ThreadID = std::thread::id;
static ThreadID CurrentThreadID() {
return std::this_thread::get_id();
}
#endif

/// Additional storage that is only ever accessed under the lock.
union LockedStorage_t {
/// The thread that is allocating the entry.
std::thread::id AllocatingThread;
ThreadID AllocatingThread;

/// The completion queue.
MetadataCompletionQueueEntry *CompletionQueue;
Expand Down Expand Up @@ -837,7 +849,7 @@ class MetadataCacheEntryBase
MetadataCacheEntryBase()
: LockedStorageKind(LSK::AllocatingThread),
TrackingInfo(PrivateMetadataTrackingInfo::initial().getRawValue()) {
LockedStorage.AllocatingThread = std::this_thread::get_id();
LockedStorage.AllocatingThread = CurrentThreadID();
}

// Note that having an explicit destructor here is important to make this
Expand All @@ -850,7 +862,7 @@ class MetadataCacheEntryBase

bool isBeingAllocatedByCurrentThread() const {
return LockedStorageKind == LSK::AllocatingThread &&
LockedStorage.AllocatingThread == std::this_thread::get_id();
LockedStorage.AllocatingThread == CurrentThreadID();
}

/// Given that this thread doesn't own the right to initialize the
Expand Down
6 changes: 5 additions & 1 deletion stdlib/public/runtime/MutexPThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
//
//===----------------------------------------------------------------------===//

#if !defined(_WIN32) && !defined(__wasi__)
#if __has_include(<unistd.h>)
#include <unistd.h>
#endif

#if defined(_POSIX_THREADS) && !defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
#include "swift/Runtime/Mutex.h"

#include "swift/Runtime/Debug.h"
Expand Down
13 changes: 11 additions & 2 deletions stdlib/public/runtime/Once.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@

using namespace swift;

#ifdef __APPLE__
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME

// No dependencies on single-threaded environments.

#elif defined(__APPLE__)

// On macOS and iOS, swift_once is implemented using GCD.
// The compiler emits an inline check matching the barrier-free inline fast
Expand All @@ -48,7 +52,12 @@ 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) {
#if defined(__APPLE__)
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
if (! *predicate) {
*predicate = true;
fn(context);
}
#elif defined(__APPLE__)
dispatch_once_f(predicate, context, fn);
#elif defined(__CYGWIN__)
_swift_once_f(predicate, context, fn);
Expand Down
4 changes: 4 additions & 0 deletions stdlib/public/stubs/Stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,5 +510,9 @@ int _swift_stdlib_putc_stderr(int C) {
}

size_t _swift_stdlib_getHardwareConcurrency() {
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
return 1;
#else
return std::thread::hardware_concurrency();
#endif
}
14 changes: 13 additions & 1 deletion stdlib/public/stubs/ThreadLocalStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,19 @@ _stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,

#endif

#if SWIFT_TLS_HAS_RESERVED_PTHREAD_SPECIFIC
#ifdef SWIFT_STDLIB_SINGLE_THREADED_RUNTIME

SWIFT_RUNTIME_STDLIB_INTERNAL
void *
_swift_stdlib_threadLocalStorageGet(void) {
static void *value;
if (!value) {
value = _stdlib_createTLS();
}
return value;
}

#elif SWIFT_TLS_HAS_RESERVED_PTHREAD_SPECIFIC

SWIFT_RUNTIME_STDLIB_INTERNAL
void *
Expand Down
1 change: 1 addition & 0 deletions utils/build-presets.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2431,6 +2431,7 @@ build-swift-static-stdlib=1
swift-objc-interop=0
swift-enable-compatibility-overrides=0
swift-runtime-macho-no-dyld=1
swift-stdlib-single-threaded-runtime=1

[preset: stdlib_S_standalone_minimal_macho_x86_64,build]
mixin-preset=
Expand Down
2 changes: 2 additions & 0 deletions utils/build-script-impl
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ KNOWN_SETTINGS=(
swift-objc-interop "" "whether to enable interoperability with Objective-C, default is 1 on Apple platfors, 0 otherwise"
swift-enable-compatibility-overrides "1" "whether to support back-deploying compatibility fixes for newer apps running on older runtimes"
swift-runtime-macho-no-dyld "0" "whether to build stdlib assuming the runtime environment does not support dynamic modules"
swift-stdlib-single-threaded-runtime "0" "whether to build stdlib as a single-threaded runtime only"

## FREESTANDING Stdlib Options
swift-freestanding-sdk "" "which SDK to use when building the FREESTANDING stdlib"
Expand Down Expand Up @@ -1756,6 +1757,7 @@ for host in "${ALL_HOSTS[@]}"; do
-DSWIFT_STDLIB_ASSERTIONS:BOOL=$(true_false "${SWIFT_STDLIB_ENABLE_ASSERTIONS}")
-DSWIFT_STDLIB_USE_NONATOMIC_RC:BOOL=$(true_false "${SWIFT_STDLIB_USE_NONATOMIC_RC}")
-DSWIFT_ENABLE_COMPATIBILITY_OVERRIDES:BOOL=$(true_false "${SWIFT_ENABLE_COMPATIBILITY_OVERRIDES}")
-DSWIFT_STDLIB_SINGLE_THREADED_RUNTIME:BOOL=$(true_false "${SWIFT_STDLIB_SINGLE_THREADED_RUNTIME}")
-DSWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS:BOOL=$(true_false "${SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS}")
-DSWIFT_RUNTIME_MACHO_NO_DYLD:BOOL=$(true_false "${SWIFT_RUNTIME_MACHO_NO_DYLD}")
-DSWIFT_NATIVE_LLVM_TOOLS_PATH:STRING="${native_llvm_tools_path}"
Expand Down