<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">On Mon, Dec 5, 2016 at 9:28 AM Joe Groff via swift-users &lt;<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Dec 4, 2016, at 4:53 PM, Andrew Trick via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt; wrote:</div><br class="m_-5702835400351017933Apple-interchange-newline"><div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Nov 30, 2016, at 5:40 AM, Anders Ha via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt; wrote:</div><br class="m_-5702835400351017933Apple-interchange-newline"><div><div style="word-wrap:break-word"><div dir="auto" style="word-wrap:break-word"><div dir="auto" style="word-wrap:break-word"><div dir="auto" style="word-wrap:break-word"><div dir="auto" style="word-wrap:break-word"><div>Hi guys</div><div><br></div><div>I have recently started adopting lock-free atomics with memory fences, but it seems Swift at this moment does not have any native instruments.</div><div><br></div><div>Then I read a thread in the Apple Developer Forum (<a href="https://forums.developer.apple.com/thread/49334" target="_blank">https://forums.developer.apple.com/thread/49334</a>), which an Apple staff claimed that all imported atomic operations are &quot;not guaranteed to be atomic&quot;. But for my tests with all optimizations enabled (-Owholemodule and -O), the OSAtomic primitives and stdatomic fences do not seem going wild.</div><div><br></div><div>Is these `atomic_*` and `OSAtomic*` primitives really unsafe in Swift as claimed? It doesn&#39;t seem like the Swift compiler would reorder memory accesses around a C function call that it wouldn&#39;t be able to see through.</div></div></div></div></div></div></div></blockquote><div><br></div><div>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.</div></div></div></div></blockquote><br></div></div><div style="word-wrap:break-word"><div>If you apply them to memory you allocated manually with malloc/free on UnsafeMutablePointer&#39;s allocation methods, then yeah, they should work as they do in C. That&#39;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.</div></div><div style="word-wrap:break-word"><div><br></div><div>-Joe</div></div></blockquote><div><br></div><div>Is the following in the ball park of being correct (going back over some old code we have)...</div><div><br></div><div>public struct AtomicBool {</div><div><br></div><div>    private static let bitLocation: UInt32 = 0</div><div>    private static let trueValue: UInt8 = 0x80</div><div>    private static let falseValue: UInt8 = 0x00</div><div><br></div><div>    private let value = UnsafeMutablePointer&lt;UInt8&gt;.allocate(capacity: 1) // TODO - leaking right? How to deal with that in a struct situation...?</div><div>    public var onSet: ((_ old: Bool, _ new: Bool) -&gt; ())?</div><div><br></div><div>    public init(_ intialValue: Bool = false) {</div><div>        value.initialize(to: intialValue ? AtomicBool.trueValue : AtomicBool.falseValue)</div><div>        onSet = nil</div><div>    }</div><div><br></div><div>    public init(_ intialValue: Bool = false, onSet: ((_ old: Bool, _ new: Bool) -&gt; ())?) {</div><div>        value.initialize(to: intialValue ? AtomicBool.trueValue : AtomicBool.falseValue)</div><div>        self.onSet = onSet</div><div>    }</div><div><br></div><div>    public mutating func set(_ newValue: Bool) {</div><div>        _ = getAndSet(newValue)</div><div>    }</div><div><br></div><div>    public mutating func getAndSet(_ newValue: Bool) -&gt; Bool {</div><div>        let oldValue: Bool</div><div>        if newValue {</div><div>            oldValue = Darwin.OSAtomicTestAndSetBarrier(AtomicBool.bitLocation, value)</div><div>        }</div><div>        else {</div><div>            oldValue = Darwin.OSAtomicTestAndClearBarrier(AtomicBool.bitLocation, value)</div><div>        }</div><div><br></div><div>        onSet?(oldValue, newValue)</div><div>        return oldValue</div><div>    }</div><div><br></div><div>    public func get() -&gt; Bool { // TODO - document the lazy &quot;safety&quot; aspect of get</div><div>        return value.pointee != AtomicBool.falseValue</div><div>    }</div><div><br></div><div>} </div></div></div>