Skip to content

Instantly share code, notes, and snippets.

@swhitty
Last active April 18, 2023 02:07
Show Gist options
  • Select an option

  • Save swhitty/5c1edc9bd5dc0cd7650ccf1c14bbe32e to your computer and use it in GitHub Desktop.

Select an option

Save swhitty/5c1edc9bd5dc0cd7650ccf1c14bbe32e to your computer and use it in GitHub Desktop.

Revisions

  1. swhitty revised this gist Apr 18, 2023. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions AllocatedUnfairLock.swift
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    @_implementationOnly import os

    // Backports the Swift interface around os_unfair_lock_t available in recent Darwin platforms
    // https://github.com/swhitty/AllocatedLock
    //
    @available(iOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
    @available(tvOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
  2. swhitty revised this gist Apr 18, 2023. 1 changed file with 34 additions and 0 deletions.
    34 changes: 34 additions & 0 deletions AllocatedUnfairLock.swift
    Original file line number Diff line number Diff line change
    @@ -46,3 +46,37 @@ public extension AllocatedLock where State == Void {
    return try body()
    }
    }

    @_implementationOnly import os

    extension AllocatedLock {
    @usableFromInline
    final class Storage {
    private let _lock: os_unfair_lock_t

    @usableFromInline
    var state: State

    init(initialState: State) {
    self._lock = .allocate(capacity: 1)
    self._lock.initialize(to: os_unfair_lock())
    self.state = initialState
    }

    @usableFromInline
    func lock() {
    os_unfair_lock_lock(_lock)
    }

    @usableFromInline
    func unlock() {
    os_unfair_lock_unlock(_lock)
    }

    deinit {
    self._lock.deinitialize(count: 1)
    self._lock.deallocate()
    }
    }
    }

  3. swhitty revised this gist Apr 18, 2023. 1 changed file with 17 additions and 28 deletions.
    45 changes: 17 additions & 28 deletions AllocatedUnfairLock.swift
    Original file line number Diff line number Diff line change
    @@ -6,54 +6,43 @@
    @available(tvOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
    @available(watchOS, deprecated: 9, message: "use OSAllocatedUnfairLock directly")
    @available(macOS, deprecated: 13.0, message: "use OSAllocatedUnfairLock directly")
    struct AllocatedUnfairLock<State> {
    public struct AllocatedLock<State>: @unchecked Sendable {

    private let storage: Storage
    @usableFromInline
    let storage: Storage

    init(initialState: State) {
    public init(initialState: State) {
    self.storage = Storage(initialState: initialState)
    }

    func withLock<R>(_ body: @Sendable (inout State) throws -> R) rethrows -> R where R: Sendable {
    os_unfair_lock_lock(storage.lock)
    defer { os_unfair_lock_unlock(storage.lock) }
    @inlinable
    public func withLock<R>(_ body: @Sendable (inout State) throws -> R) rethrows -> R where R: Sendable {
    storage.lock()
    defer { storage.unlock() }
    return try body(&storage.state)
    }

    private final class Storage {
    let lock: os_unfair_lock_t
    var state: State

    init(initialState: State) {
    self.lock = .allocate(capacity: 1)
    self.lock.initialize(to: os_unfair_lock())
    self.state = initialState
    }

    deinit {
    self.lock.deinitialize(count: 1)
    self.lock.deallocate()
    }
    }
    }

    extension AllocatedUnfairLock where State == Void {
    public extension AllocatedLock where State == Void {

    init() {
    self.storage = .init(initialState: ())
    self.storage = Storage(initialState: ())
    }

    @inlinable @available(*, noasync)
    func lock() {
    os_unfair_lock_lock(storage.lock)
    storage.lock()
    }

    @inlinable @available(*, noasync)
    func unlock() {
    os_unfair_lock_unlock(storage.lock)
    storage.unlock()
    }

    @inlinable
    func withLock<R>(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable {
    os_unfair_lock_lock(storage.lock)
    defer { os_unfair_lock_unlock(storage.lock) }
    storage.lock()
    defer { storage.unlock() }
    return try body()
    }
    }
  4. swhitty created this gist Apr 10, 2023.
    59 changes: 59 additions & 0 deletions AllocatedUnfairLock.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    @_implementationOnly import os

    // Backports the Swift interface around os_unfair_lock_t available in recent Darwin platforms
    //
    @available(iOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
    @available(tvOS, deprecated: 16.0, message: "use OSAllocatedUnfairLock directly")
    @available(watchOS, deprecated: 9, message: "use OSAllocatedUnfairLock directly")
    @available(macOS, deprecated: 13.0, message: "use OSAllocatedUnfairLock directly")
    struct AllocatedUnfairLock<State> {

    private let storage: Storage

    init(initialState: State) {
    self.storage = Storage(initialState: initialState)
    }

    func withLock<R>(_ body: @Sendable (inout State) throws -> R) rethrows -> R where R: Sendable {
    os_unfair_lock_lock(storage.lock)
    defer { os_unfair_lock_unlock(storage.lock) }
    return try body(&storage.state)
    }

    private final class Storage {
    let lock: os_unfair_lock_t
    var state: State

    init(initialState: State) {
    self.lock = .allocate(capacity: 1)
    self.lock.initialize(to: os_unfair_lock())
    self.state = initialState
    }

    deinit {
    self.lock.deinitialize(count: 1)
    self.lock.deallocate()
    }
    }
    }

    extension AllocatedUnfairLock where State == Void {

    init() {
    self.storage = .init(initialState: ())
    }

    func lock() {
    os_unfair_lock_lock(storage.lock)
    }

    func unlock() {
    os_unfair_lock_unlock(storage.lock)
    }

    func withLock<R>(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable {
    os_unfair_lock_lock(storage.lock)
    defer { os_unfair_lock_unlock(storage.lock) }
    return try body()
    }
    }