SynchronizationKit - Mutex and Atomic back-deployed + RWLock, Semaphore, and async-aware locks for Swift Concurrency

Hello,

I'd like to share SynchronizationKit, a package of synchronization primitives for Swift.

It started as a way to use the standard library's Mutex and Atomic on OS versions that predate the Synchronization module, and grew into a small family of primitives the standard library doesn't provide:

  • Mutex and Atomic: back-deployed to macOS 12 / iOS 15, matching the standard library's API and performance. On Linux, Android, WASI, and Windows the standard library's own types are re-exported, so client code is the same everywhere.
  • RWLock: a writer-preferring reader-writer lock. Readers publish themselves in a shared table and touch nothing in common, so reads stay cheap however many threads read at once.
  • Semaphore: a counting semaphore stored inline, with no Dispatch dependency.
  • AsyncMutex, AsyncRWLock, AsyncSemaphore: the same primitives for Swift Concurrency. They suspend the waiting task instead of blocking its thread, so a critical section can span an await when it has to. Each also has a synchronous form for a thread that has no task, so a thread and a task can take turns on one value. Cancellation and priority escalation are handled and documented on the types.

Every primitive owns the value it protects: it's reachable only inside withLock-style methods, and all of them store their value inline, so they're safe as a let property or a global.

Each primitive lives in its own target behind a package trait of the same name, so you can enable only what you need:

.package(
    url: "https://github.com/sinoru/swift-synchronization-kit.git",
    from: "1.1.1",
    traits: ["Mutex", "AsyncMutex"]
),

Platforms: macOS 12, iOS 15, tvOS 15, watchOS 8, visionOS 1 or later, Linux (glibc and musl), Android, WASI, and Windows. Backends are selected per platform and documented in the README. Requires Swift 6.3 or later to build.

The README includes performance measurements for each primitive next to what a client would otherwise write (the standard library's Mutex, DispatchSemaphore, pthread_rwlock_t, a concurrent DispatchQueue, an actor), with the suites in the repository so the numbers can be reproduced.

API docs are hosted on the Swift Package Index:
https://swiftpackageindex.com/sinoru/swift-synchronization-kit/documentation/synchronizationkit

Feedback, bug reports, and pull requests are welcome. Thanks!

3 Likes