I haven't used this in production, but this repository looks pretty promising. It's more or less just wrapping up the clang atomic intrinsics into a Swift package.
https://github.com/glessard/swift-atomics -Colin On Mon, May 1, 2017 at 12:43 PM Joe Groff via swift-users < swift-users@swift.org> wrote: > > > On Apr 25, 2017, at 1:08 PM, Shawn Erickson <shaw...@gmail.com> wrote: > > > > > > On Mon, Dec 5, 2016 at 9:28 AM Joe Groff via swift-users < > swift-users@swift.org> wrote: > > > >> On Dec 4, 2016, at 4:53 PM, Andrew Trick via swift-users < > swift-users@swift.org> wrote: > >> > >> > >>> On Nov 30, 2016, at 5:40 AM, Anders Ha via swift-users < > swift-users@swift.org> wrote: > >>> > >>> Hi guys > >>> > >>> I have recently started adopting lock-free atomics with memory fences, > but it seems Swift at this moment does not have any native instruments. > >>> > >>> Then I read a thread in the Apple Developer Forum ( > https://forums.developer.apple.com/thread/49334), which an Apple staff > claimed that all imported atomic operations are "not guaranteed to be > atomic". But for my tests with all optimizations enabled (-Owholemodule and > -O), the OSAtomic primitives and stdatomic fences do not seem going wild. > >>> > >>> Is these `atomic_*` and `OSAtomic*` primitives really unsafe in Swift > as claimed? It doesn't seem like the Swift compiler would reorder memory > accesses around a C function call that it wouldn't be able to see through. > >> > >> Did you get an answer to this? I’m not sure what led you to believe the > primitives are unsafe in Swift. Importing them doesn’t change their > semantics. > > > > If you apply them to memory you allocated manually with malloc/free on > UnsafeMutablePointer's allocation methods, then yeah, they should work as > they do in C. That's the safest way to use these functions today. Passing a > Swift `var` inout to one of these functions does not guarantee that > accesses to that var will maintain atomicity, since there may be bridging > or reabstracting conversions happening under the hood. > > > > -Joe > > > > Is the following in the ball park of being correct (going back over some > old code we have)... > > > > public struct AtomicBool { > > > > private static let bitLocation: UInt32 = 0 > > private static let trueValue: UInt8 = 0x80 > > private static let falseValue: UInt8 = 0x00 > > > > private let value = UnsafeMutablePointer<UInt8>.allocate(capacity: > 1) // TODO - leaking right? How to deal with that in a struct situation...? > > public var onSet: ((_ old: Bool, _ new: Bool) -> ())? > > > > public init(_ intialValue: Bool = false) { > > value.initialize(to: intialValue ? AtomicBool.trueValue : > AtomicBool.falseValue) > > onSet = nil > > } > > > > public init(_ intialValue: Bool = false, onSet: ((_ old: Bool, _ > new: Bool) -> ())?) { > > value.initialize(to: intialValue ? AtomicBool.trueValue : > AtomicBool.falseValue) > > self.onSet = onSet > > } > > > > public mutating func set(_ newValue: Bool) { > > _ = getAndSet(newValue) > > } > > > > public mutating func getAndSet(_ newValue: Bool) -> Bool { > > let oldValue: Bool > > if newValue { > > oldValue = > Darwin.OSAtomicTestAndSetBarrier(AtomicBool.bitLocation, value) > > } > > else { > > oldValue = > Darwin.OSAtomicTestAndClearBarrier(AtomicBool.bitLocation, value) > > } > > > > onSet?(oldValue, newValue) > > return oldValue > > } > > > > public func get() -> Bool { // TODO - document the lazy "safety" > aspect of get > > return value.pointee != AtomicBool.falseValue > > } > > That looks OK. It might be better to provide an allocate/deallocate or > with { ... } interface instead of burying the allocate call in the > initializer since the user will need to handle the deallocation of the > buffer at some point. > > -Joe > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users