Skip to content
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

[stdlib] Implement Mutex in Synchronization #71383

Merged
merged 21 commits into from
Jun 5, 2024
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
86 changes: 84 additions & 2 deletions stdlib/cmake/modules/AddSwiftStdlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,45 @@ endfunction()
# Presence of a build flavor requires SWIFT_MODULE_DEPENDS_MACCATALYST to be
# defined and have values.
#
# SWIFT_SOURCES_DEPENDS_MACOS
# Sources that are built when this library is being built for macOS
#
# SWIFT_SOURCES_DEPENDS_IOS
# Sources that are built when this library is being built for iOS
#
# SWIFT_SOURCES_DEPENDS_TVOS
# Sources that are built when this library is being built for tvOS
#
# SWIFT_SOURCES_DEPENDS_WATCHOS
# Sources that are built when this library is being built for watchOS
#
# SWIFT_SOURCES_DEPENDS_VISIONOS
# Sources that are built when this library is being built for visionOS
#
# SWIFT_SOURCES_DEPENDS_FREESTANDING
# Sources that are built when this library is being built for freestanding
#
# SWIFT_SOURCES_DEPENDS_FREEBSD
# Sources that are built when this library is being built for FreeBSD
#
# SWIFT_SOURCES_DEPENDS_OPENBSD
# Sources that are built when this library is being built for OpenBSD
#
# SWIFT_SOURCES_DEPENDS_LINUX
# Sources that are built when this library is being built for Linux
#
# SWIFT_SOURCES_DEPENDS_CYGWIN
# Sources that are built when this library is being built for Cygwin
#
# SWIFT_SOURCES_DEPENDS_HAIKU
# Sources that are built when this library is being built for Haiku
#
# SWIFT_SOURCES_DEPENDS_WASI
# Sources that are built when this library is being built for WASI
#
# SWIFT_SOURCES_DEPENDS_WINDOWS
# Sources that are built when this library is being built for Windows
#
# source1 ...
# Sources to add into this library.
function(add_swift_target_library name)
Expand Down Expand Up @@ -1898,7 +1937,20 @@ function(add_swift_target_library name)
TARGET_SDKS
SWIFT_COMPILE_FLAGS_MACCATALYST
SWIFT_MODULE_DEPENDS_MACCATALYST
SWIFT_MODULE_DEPENDS_MACCATALYST_UNZIPPERED)
SWIFT_MODULE_DEPENDS_MACCATALYST_UNZIPPERED
SWIFT_SOURCES_DEPENDS_MACOS
SWIFT_SOURCES_DEPENDS_IOS
SWIFT_SOURCES_DEPENDS_TVOS
SWIFT_SOURCES_DEPENDS_WATCHOS
SWIFT_SOURCES_DEPENDS_VISIONOS
SWIFT_SOURCES_DEPENDS_FREESTANDING
SWIFT_SOURCES_DEPENDS_FREEBSD
SWIFT_SOURCES_DEPENDS_OPENBSD
SWIFT_SOURCES_DEPENDS_LINUX
SWIFT_SOURCES_DEPENDS_CYGWIN
SWIFT_SOURCES_DEPENDS_HAIKU
SWIFT_SOURCES_DEPENDS_WASI
SWIFT_SOURCES_DEPENDS_WINDOWS)

cmake_parse_arguments(SWIFTLIB
"${SWIFTLIB_options}"
Expand Down Expand Up @@ -2169,6 +2221,36 @@ function(add_swift_target_library name)
list(APPEND swiftlib_link_flags_all "-Xlinker" "-ignore_auto_link")
endif()

# Append SDK specific sources to the full list of sources
set(sources ${SWIFTLIB_SOURCES})
if(sdk STREQUAL "OSX")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_MACOS})
elseif(sdk STREQUAL "IOS" OR sdk STREQUAL "IOS_SIMULATOR")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_IOS})
elseif(sdk STREQUAL "TVOS" OR sdk STREQUAL "TVOS_SIMULATOR")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_TVOS})
elseif(sdk STREQUAL "WATCHOS" OR sdk STREQUAL "WATCHOS_SIMULATOR")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_WATCHOS})
elseif(sdk STREQUAL "XROS" OR sdk STREQUAL "XROS_SIMULATOR")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_VISIONOS})
elseif(sdk STREQUAL "FREESTANDING")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_FREESTANDING})
elseif(sdk STREQUAL "FREEBSD")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_FREEBSD})
elseif(sdk STREQUAL "OPENBSD")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_OPENBSD})
elseif(sdk STREQUAL "LINUX" OR sdk STREQUAL "ANDROID")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_LINUX})
elseif(sdk STREQUAL "CYGWIN")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_CYGWIN})
elseif(sdk STREQUAL "HAIKU")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_HAIKU})
elseif(sdk STREQUAL "WASI")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_WASI})
elseif(sdk STREQUAL "WINDOWS")
list(APPEND sources ${SWIFTLIB_SWIFT_SOURCES_DEPENDS_WINDOWS})
endif()

# We unconditionally removed "-z,defs" from CMAKE_SHARED_LINKER_FLAGS in
# swift_common_standalone_build_config_llvm within
# SwiftSharedCMakeConfig.cmake, where it was added by a call to
Expand Down Expand Up @@ -2373,7 +2455,7 @@ function(add_swift_target_library name)
${SWIFTLIB_NO_LINK_NAME_keyword}
${SWIFTLIB_OBJECT_LIBRARY_keyword}
${SWIFTLIB_INSTALL_WITH_SHARED_keyword}
${SWIFTLIB_SOURCES}
${sources}
MODULE_TARGETS ${module_variant_names}
SDK ${sdk}
ARCHITECTURE ${arch}
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/SwiftShims/swift/shims/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set(sources
Visibility.h
_SwiftConcurrency.h
_SwiftDistributed.h
_SynchronizationShims.h

module.modulemap
)
Expand Down
69 changes: 69 additions & 0 deletions stdlib/public/SwiftShims/swift/shims/_SynchronizationShims.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 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
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_STDLIB_SYNCHRONIZATION_SHIMS_H
#define SWIFT_STDLIB_SYNCHRONIZATION_SHIMS_H

#include "SwiftStdbool.h"
#include "SwiftStdint.h"

#if defined(__linux__)
#include <errno.h>
#include <linux/futex.h>
#include <sys/syscall.h>
#include <unistd.h>

static inline __swift_uint32_t _swift_stdlib_gettid() {
static __thread tid = 0;

if (tid == 0) {
tid = syscall(SYS_gettid);
}

return tid;
}

static inline __swift_uint32_t _swift_stdlib_futex_lock(__swift_uint32_t *lock) {
int ret = syscall(SYS_futex, lock, FUTEX_LOCK_PI_PRIVATE,
/* val */ 0, // this value is ignored by this futex op
/* timeout */ NULL); // block indefinitely

if (ret == 0) {
return ret;
}

return errno;
}

static inline __swift_uint32_t _swift_stdlib_futex_trylock(__swift_uint32_t *lock) {
int ret = syscall(SYS_futex, lock, FUTEX_TRYLOCK_PI);

if (ret == 0) {
return ret;
}

return errno;
}

static inline __swift_uint32_t _swift_stdlib_futex_unlock(__swift_uint32_t *lock) {
int ret = syscall(SYS_futex, lock, FUTEX_UNLOCK_PI_PRIVATE);

if (ret == 0) {
return ret;
}

return errno;
}

#endif // defined(__linux__)

#endif // SWIFT_STDLIB_SYNCHRONIZATION_SHIMS_H
5 changes: 5 additions & 0 deletions stdlib/public/SwiftShims/swift/shims/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ module SwiftOverlayShims {
header "LibcOverlayShims.h"
export *
}

module _SynchronizationShims {
header "_SynchronizationShims.h"
export *
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ public struct Atomic<Value: AtomicRepresentable>: ~Copyable {
@available(SwiftStdlib 6.0, *)
@_alwaysEmitIntoClient
@_transparent
var address: UnsafeMutablePointer<Value.AtomicRepresentation> {
UnsafeMutablePointer<Value.AtomicRepresentation>(rawAddress)
var _address: UnsafeMutablePointer<Value.AtomicRepresentation> {
UnsafeMutablePointer<Value.AtomicRepresentation>(_rawAddress)
}

@available(SwiftStdlib 6.0, *)
@_alwaysEmitIntoClient
@_transparent
var rawAddress: Builtin.RawPointer {
var _rawAddress: Builtin.RawPointer {
Builtin.unprotectedAddressOfBorrow(self)
}

Expand All @@ -39,7 +39,7 @@ public struct Atomic<Value: AtomicRepresentable>: ~Copyable {
@_alwaysEmitIntoClient
@_transparent
public init(_ initialValue: consuming Value) {
address.initialize(to: Value.encodeAtomicRepresentation(initialValue))
_address.initialize(to: Value.encodeAtomicRepresentation(initialValue))
}

// Deinit's can't be marked @_transparent. Do these things need all of these
Expand All @@ -48,10 +48,10 @@ public struct Atomic<Value: AtomicRepresentable>: ~Copyable {
@_alwaysEmitIntoClient
@inlinable
deinit {
let oldValue = Value.decodeAtomicRepresentation(address.pointee)
let oldValue = Value.decodeAtomicRepresentation(_address.pointee)
_ = consume oldValue

address.deinitialize(count: 1)
_address.deinitialize(count: 1)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,31 +93,31 @@ extension Atomic where Value == Bool {
let original = switch ordering {
case .relaxed:
Builtin.atomicrmw_and_monotonic_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .acquiring:
Builtin.atomicrmw_and_acquire_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .releasing:
Builtin.atomicrmw_and_release_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .acquiringAndReleasing:
Builtin.atomicrmw_and_acqrel_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .sequentiallyConsistent:
Builtin.atomicrmw_and_seqcst_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

Expand Down Expand Up @@ -151,31 +151,31 @@ extension Atomic where Value == Bool {
let original = switch ordering {
case .relaxed:
Builtin.atomicrmw_or_monotonic_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .acquiring:
Builtin.atomicrmw_or_acquire_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .releasing:
Builtin.atomicrmw_or_release_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .acquiringAndReleasing:
Builtin.atomicrmw_or_acqrel_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .sequentiallyConsistent:
Builtin.atomicrmw_or_seqcst_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

Expand Down Expand Up @@ -209,31 +209,31 @@ extension Atomic where Value == Bool {
let original = switch ordering {
case .relaxed:
Builtin.atomicrmw_xor_monotonic_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .acquiring:
Builtin.atomicrmw_xor_acquire_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .releasing:
Builtin.atomicrmw_xor_release_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .acquiringAndReleasing:
Builtin.atomicrmw_xor_acqrel_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

case .sequentiallyConsistent:
Builtin.atomicrmw_xor_seqcst_Int8(
rawAddress,
_rawAddress,
builtinOperand
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,20 @@ extension Atomic where Value == ${intType} {
% if intType == "Int" or intType == "UInt":
#if _pointerBitWidth(_64)
Builtin.atomicrmw_${atomicOperationName(intType, builtinName)}_${llvmOrder}_Int64(
rawAddress,
_rawAddress,
operand._value
)
#elseif _pointerBitWidth(_32)
Builtin.atomicrmw_${atomicOperationName(intType, builtinName)}_${llvmOrder}_Int32(
rawAddress,
_rawAddress,
operand._value
)
#else
#error("Unsupported platform")
#endif
% else:
Builtin.atomicrmw_${atomicOperationName(intType, builtinName)}_${llvmOrder}_Int${bits}(
rawAddress,
_rawAddress,
operand._value
)
% end
Expand Down
Loading