Skip to content

Commit

Permalink
Add <os/lock_private.h> and OSUnfairRecursiveLock (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle-Ye committed Dec 27, 2023
1 parent 5113764 commit e11317a
Show file tree
Hide file tree
Showing 7 changed files with 907 additions and 31 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/compatibility_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ jobs:
- name: Build with library evolution
run: make library-evolution
- name: Generate swiftinterface
run: make module-interface
run: make module-interface
- name: Build without private header of OSLock
run: make disable-oslock-private
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ library-evolution:
module-interface:
xcodebuild build -scheme OpenCombine -sdk macosx -destination "platform=macOS" BUILD_LIBRARY_FOR_DISTRIBUTION=1

disable-oslock-private:
OPENCOMBINE_OSLOCK_PRIVATE=0 $(SWIFT_EXE) build

gyb:
$(shell ./utils/recursively_gyb.sh)

Expand All @@ -42,5 +45,6 @@ clean:
test-compatibility-debug \
library-evolution \
module-interface \
disable-oslock-private \
gyb \
clean
48 changes: 34 additions & 14 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ let supportedPlatforms: [Platform] = [
.wasi,
]

let cOpenCombineHelpersTarget: Target = .target(
name: "COpenCombineHelpers"
)
let openCombineShimTarget: Target = .target(
name: "OpenCombineShim",
dependencies: [
"OpenCombine",
.target(name: "OpenCombineDispatch",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
.target(name: "OpenCombineFoundation",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
]
)
let openCombineTarget: Target = .target(
name: "OpenCombine",
dependencies: [
Expand Down Expand Up @@ -47,7 +60,6 @@ let openCombineDispatchTarget: Target = .target(
name: "OpenCombineDispatch",
dependencies: ["OpenCombine"]
)

let openCombineTestsTarget: Target = .testTarget(
name: "OpenCombineTests",
dependencies: [
Expand All @@ -71,17 +83,8 @@ let package = Package(
.library(name: "OpenCombineShim", targets: ["OpenCombineShim"]),
],
targets: [
.target(name: "COpenCombineHelpers"),
.target(
name: "OpenCombineShim",
dependencies: [
"OpenCombine",
.target(name: "OpenCombineDispatch",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
.target(name: "OpenCombineFoundation",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
]
),
cOpenCombineHelpersTarget,
openCombineShimTarget,
openCombineTarget,
openCombineFoundationTarget,
openCombineDispatchTarget,
Expand All @@ -98,11 +101,17 @@ extension [Platform] {
}
}

func envEnable(_ key: String) -> Bool {
func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool {
guard let value = ProcessInfo.processInfo.environment[key] else {
return defaultValue
}
if value == "1" {
return true
} else if value == "0" {
return false
} else {
return defaultValue
}
return value == "1"
}

let enableLibraryEvolution = envEnable("OPENCOMBINE_LIBRARY_EVOLUTION")
Expand All @@ -124,3 +133,14 @@ if enableCompatibilityTest {
settings.append(.define("OPENCOMBINE_COMPATIBILITY_TEST"))
openCombineTestsTarget.swiftSettings = settings
}

let enableOSLockPrivate = envEnable("OPENCOMBINE_OSLOCK_PRIVATE", default: true)
if enableOSLockPrivate {
var cSettings = cOpenCombineHelpersTarget.cSettings ?? []
cSettings.append(.define("OPENCOMBINE_OSLOCK_PRIVATE"))
cOpenCombineHelpersTarget.cSettings = cSettings

var cxxSettings = cOpenCombineHelpersTarget.cxxSettings ?? []
cxxSettings.append(.define("OPENCOMBINE_OSLOCK_PRIVATE"))
cOpenCombineHelpersTarget.cxxSettings = cxxSettings
}
50 changes: 35 additions & 15 deletions Package@swift-5.9.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ let supportedPlatforms: [Platform] = [
.visionOS,
]

let cOpenCombineHelpersTarget: Target = .target(
name: "COpenCombineHelpers"
)
let openCombineShimTarget: Target = .target(
name: "OpenCombineShim",
dependencies: [
"OpenCombine",
.target(name: "OpenCombineDispatch",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
.target(name: "OpenCombineFoundation",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
]
)
let openCombineTarget: Target = .target(
name: "OpenCombine",
dependencies: [
Expand Down Expand Up @@ -48,7 +61,6 @@ let openCombineDispatchTarget: Target = .target(
name: "OpenCombineDispatch",
dependencies: ["OpenCombine"]
)

let openCombineTestsTarget: Target = .testTarget(
name: "OpenCombineTests",
dependencies: [
Expand All @@ -66,23 +78,14 @@ let openCombineTestsTarget: Target = .testTarget(
let package = Package(
name: "OpenCombine",
products: [
.library(name: "OpenCombine",targets: ["OpenCombine"]),
.library(name: "OpenCombine", targets: ["OpenCombine"]),
.library(name: "OpenCombineDispatch", targets: ["OpenCombineDispatch"]),
.library(name: "OpenCombineFoundation", targets: ["OpenCombineFoundation"]),
.library(name: "OpenCombineShim", targets: ["OpenCombineShim"]),
],
targets: [
.target(name: "COpenCombineHelpers"),
.target(
name: "OpenCombineShim",
dependencies: [
"OpenCombine",
.target(name: "OpenCombineDispatch",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
.target(name: "OpenCombineFoundation",
condition: .when(platforms: supportedPlatforms.except([.wasi]))),
]
),
cOpenCombineHelpersTarget,
openCombineShimTarget,
openCombineTarget,
openCombineFoundationTarget,
openCombineDispatchTarget,
Expand All @@ -99,11 +102,17 @@ extension [Platform] {
}
}

func envEnable(_ key: String) -> Bool {
func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool {
guard let value = ProcessInfo.processInfo.environment[key] else {
return defaultValue
}
if value == "1" {
return true
} else if value == "0" {
return false
} else {
return defaultValue
}
return value == "1"
}

let enableLibraryEvolution = envEnable("OPENCOMBINE_LIBRARY_EVOLUTION")
Expand All @@ -125,3 +134,14 @@ if enableCompatibilityTest {
settings.append(.define("OPENCOMBINE_COMPATIBILITY_TEST"))
openCombineTestsTarget.swiftSettings = settings
}

let enableOSLockPrivate = envEnable("OPENCOMBINE_OSLOCK_PRIVATE", default: true)
if enableOSLockPrivate {
var cSettings = cOpenCombineHelpersTarget.cSettings ?? []
cSettings.append(.define("OPENCOMBINE_OSLOCK_PRIVATE"))
cOpenCombineHelpersTarget.cSettings = cSettings

var cxxSettings = cOpenCombineHelpersTarget.cxxSettings ?? []
cxxSettings.append(.define("OPENCOMBINE_OSLOCK_PRIVATE"))
cOpenCombineHelpersTarget.cxxSettings = cxxSettings
}
36 changes: 35 additions & 1 deletion Sources/COpenCombineHelpers/COpenCombineHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,33 @@ class OS_UNFAIR_LOCK_AVAILABILITY OSUnfairLock final : PlatformIndependentMutex
os_unfair_lock_assert_owner(&mutex_);
}
};

#ifdef OPENCOMBINE_OSLOCK_PRIVATE
class OS_UNFAIR_RECURSIVE_LOCK_AVAILABILITY OSUnfairRecursiveLock final : PlatformIndependentMutex {
os_unfair_recursive_lock mutex_ = OS_UNFAIR_RECURSIVE_LOCK_INIT;
public:
OSUnfairRecursiveLock() = default;

OSUnfairRecursiveLock(const OSUnfairRecursiveLock&) = delete;
OSUnfairRecursiveLock& operator=(const OSUnfairRecursiveLock&) = delete;

OSUnfairRecursiveLock(OSUnfairRecursiveLock&&) = delete;
OSUnfairRecursiveLock& operator=(OSUnfairRecursiveLock&&) = delete;

void lock() override {
os_unfair_recursive_lock_lock(&mutex_);
}

void unlock() override {
os_unfair_recursive_lock_unlock(&mutex_);
}

void assertOwner() override {
os_unfair_recursive_lock_assert_owner(&mutex_);
}
};
#endif // OPENCOMBINE_OSLOCK_PRIVATE

#endif // __APPLE__

template <typename Mu>
Expand Down Expand Up @@ -216,8 +243,15 @@ OpenCombineUnfairLock opencombine_unfair_lock_alloc(void) {

OpenCombineUnfairRecursiveLock opencombine_unfair_recursive_lock_alloc(void) {
OPENCOMBINE_HANDLE_EXCEPTION_BEGIN
// TODO: Use os_unfair_recursive_lock on Darwin as soon as it becomes public API.
#if defined(__APPLE__) && defined(OPENCOMBINE_OSLOCK_PRIVATE)
if (__builtin_available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 5.0, *)) {
return {new OSUnfairRecursiveLock};
} else {
return {new StdRecursiveMutex};
}
#else
return {new StdRecursiveMutex};
#endif
OPENCOMBINE_HANDLE_EXCEPTION_END
}

Expand Down
1 change: 1 addition & 0 deletions Sources/COpenCombineHelpers/include/COpenCombineHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "Compiler.h"
#include "lock_private.h"

#if __has_attribute(swift_name)
# define OPENCOMBINE_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
Expand Down

0 comments on commit e11317a

Please sign in to comment.