-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-9144] Low-level atomics in Swift #51640
Comments
I don't think there are any safe ways to use atomic operations from Swift right now. Even the helpers you've written aren't really safe because nothing stops you (or the compiler) from copying the struct around. @rjmccall, @airspeedswift, do we have a bug tracking the general request already? |
Hmm, maybe not in JIRA. |
Comment by Krunoslav Zaher (JIRA) I've wrote unit tests to confirm that the compiler is performing the expected behavior regarding atomic operations. https://github.com/ReactiveX/RxSwift/blob/master/Tests/RxSwiftTests/AtomicTests.swift I understand that the compiler doesn't make any guarantees regarding additional copying of the struct, but can anybody provide any reason/rationale why would the Swift compiler decide to perform additional copying of these structs around instead of just passing the pointer to atomic operations? |
Comment by Krunoslav Zaher (JIRA) Is there any timeline when will the Swift compiler allow using atomic operations equivalent to c11 atomics or to deprecated |
The main thing is that, not knowing that the struct is used as part of an atomic sequence, we reserve the right to rearrange and break up its storage in ways that would defeat atomicity. Forming a pointer to e.g. an Int would require us to reassemble that into the normal ABI, but that guarantee only lasts for the lifetime of that pointer. |
Comment by Krunoslav Zaher (JIRA) @rjmccall Thank you for taking the time to answer my question. Let me try to rephrase the question. I'm aware that Swift compiler could in theory decide to rearrange the I'm trying to find out is anyone aware of any reasons why would the Swift compiler decide to transform code like this. var atomic = AtomicPrimitive()
DispatchQueue.main.async
{ atomic.fetchOr(0) } Atomic definition can be found here. into something that would defy the atomic operations. E.g. I'm aware that if one has a property in a class that has class A {
var notAtomic: AtomicInt { didSet { print("Atomic") } }
}
let a = A()
a.notAtomic.fetchOr(8) // <– fail |
Comment by Krunoslav Zaher (JIRA) If the Swift compiler makes absolutely no promises, then what is the rationale for adding This means that my |
Swift can make a large number of high-level guarantees (e.g. that a stored property will be modified "directly" without introducing a semantic copy) without having to make fine-grained low-level guarantees like pointer equality. In general, the exclusivity rules on structs prohibit them from being used to implement a meaningful atomic API: you cannot modify `self` in a non-`mutating` method, and it is illegal for other threads to concurrently call any other method while a `mutating` method is underway. |
I'm taking this as I'm working on introducing low-level atomic operations. Atomics require stable memory locations, which are currently achievable by either
Therefore, we are building unsafe atomic constructs that specifically fit these two cases. We expect that move-only (or non-movable) types will eventually replace these with memory-safe alternatives, but it makes sense to still add them so that people can start experimenting with concurrency support in Swift. Swift-evolution pitch: https://gist.github.com/lorentey/cf8703b5974ebe8f85cfb92a6628880d Forum thread: Implementation: |
Should we close this since swift-atomics is now available? |
Environment
Xcode 10 / Swift 4.2 / High Sierra
Additional Detail from JIRA
md5: b50a38690fc8b14739d06ef73d3de3c8
Issue Description:
Using the following methods:
OSAtomicCompareAndSwap32Barrier
OSAtomicIncrement32Barrier
OSAtomicDecrement32Barrier
OSAtomicOr32OrigBarrier
OSAtomicXor32OrigBarrier
Provides deprecation warnings under Swift 4.2:
Unfortunately, there is no Swift interface for stdatomic.h which forces us to use a really icky low-level LLVM implementation instead: https://github.com/ReactiveX/RxSwift/blob/45c85f9fc1ee1a007984cd9a61c098c315c7c9d2/RxAtomic/include/RxAtomic.h#L16-L42 in C.
It seems like a bug to me that there's a deprecation warning with no actual deprecation path. Any thoughts?
The text was updated successfully, but these errors were encountered: