-
-
Notifications
You must be signed in to change notification settings - Fork 17
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
Can atomic-polyfill
and portable-atomic
soundly coexist in the same dependency graph?
#39
Comments
Having both in the same dependency graph is not a problem. A case where problems can occur is when atomic operations are performed on the same memory location, one as If you do this for Footnotes
|
Re: footnote 2: Does footnote 2 only applies to archs which have the potential to be multicore? I.e. msp430 Re: footnote 3:
Well the user-provided implementations are marked In any case, like it or not, for maximum crate compat, I'll eventually have to implement msp430 for |
Yes. footnote 2 is only for multicore systems.
Well, since the critical-section safety requirements do not mention compatibility with these use cases, an implementation that is incompatible with them is also considered a sound critical-section implementation. |
Closing -- I believe I answered your question. |
@taiki-e I didn't close this because I thought I had ask "should "Relationship with But doing CTRL+F, I've found that that I'd never asked such a thing :P. Oops. Do you think such a mention of |
My thoughts on atomic-polyfill are that the atomic-polyfill and the feature-based approach it recommends can very easily introduce unsoundness (see smol-rs/atomic-waker#7 (comment) for more). So, my recommendation is that common libraries should avoid atomic-polyfill. If we mention the atomic-polyfill in README we cannot avoid mentioning it. And when we mention it, it makes little sense to explain interoperability with atomic-polyfill in README because we recommend not the use of atomic-polyfill anyway. (The link to this issue is fine though.) |
If you're referring to the multi-core unsoundness, that is gone in That said, seeing at peripheral I/O access in Rust-embedded requires I'll get over it, but the duplication doesn't feel right to me:
Footnotes
|
This seems to be about the unsoundness I mentioned in rust-lang/rust#99668 (comment), I see that it has been fixed. However, my concern here is about the feature-based approach recommended by atomic-polyfill and critical-section and used by the crate that implements critical-section. In smol-rs/atomic-waker#7 (comment), I said:
This is fine for some platforms (e,g., msp430 which is single core) and use cases, but can be problematic for libraries that are not embedded-specific. Reading the rest of your comment, I felt you are hoping for portable-atomic to support critical-section crate. (Sorry if this is a misunderstanding.) We have considered it in the past (#26) and would be fine with supporting it. However, since the version of critical-section is considered a public API (matklad/once_cell#190 (comment)), we may need to take an approach like "unsafe cfg to enable the implementation based on critical-section" + "feature to select the version of critical-section". |
My concerns boil down to "we have two crates implementing the same functionality in two different ways, and the crates ecosystem is not converging on either of them." Which crate gets chosen seems to depend on who you know :P. This leads to code duplication that is probably sound and or doesn't break1, such as you and I maintaining different versions of Additionally, when making changes to either of our interrupt enable/disable code, we have to make sure our two versions are semantically equivalent even if we have different codegen (see #40 (comment)). I think having the interrupt enable/disable code in one place, such as you depending on the
This would also solve my concern if I enabled the unsafe Footnotes
|
IIUC the problem occurs when this crate and another crate are disabling interrupts in incompatible ways. Examples of this are M-mode vs S-mode on RISC-V, disabling only irq vs disabling both irq & fiq on pre-v6 ARM, etc. Is there such a case with MSP430? (No as far as I know, but I'm not an expert on MSP430.) FYI #44 has somewhat improved the situation on this, and the
I basically agree with you on this. However, rust-embedded crates do not always generate the code I expect or support the older compilers that portable-atomic supports for historical reasons. Some problems can be solved by contributions such as rust-embedded/msp430#12, but I don't want to make requests that clearly burden the maintainers of rust-embedded crates, such as support for older compilers. (Also, as mentioned in #40 (comment), it may allow for optimizations that are not possible with rust-embedded crates, which need to consider a variety of use cases.) Therefore, there are no plans to change the current style of using our own implementation by default. |
Indeed, this is another problem. However, I was approaching it from the "what happens if the implementations accidentally diverge in two or more crates and how do we efficiently make them all correct wrt each other?" angle. More implementations == more things can go wrong. But...
This is also true, and compelling. I think I've changed my mind about "only one place to maintain the code" since I wrote that comment.
No, not right now. The I have considered making an
|
Like it or not,
atomic-polyfill
andportable-atomic
both exist as crates solving the same problem of "providing atomic primitives to targets that don't have them" in different ways. The major difference between the two crates is that:atomic-polyfill
depends oncritical-section
, and expects another crate to defineextern
functionsacquire
andrelease
. Thecritical-section
crate usesacquire
andrelease
to implement critical sections. Ifacquire
andrelease
aren't defined by an external crate, a link error will occur. In other words, the critical section implementation can be swapped out with another.portable-atomic
implements critical sections for all targets within theportable-atomic
crate, and does not defer to an external crate.According to reverse dependencies on crates.io, these two crates don't have any shared reverse dependencies, and some of these reverse deps have 10 million+ downloads. This means it's plausible to have both crates in the same dependency graph. And this means it's also plausible that these two crates in the same dependency graph implement critical sections in different ways.
Is this a soundness problem in practice? I can't visualize one, since types from this crate won't share memory locations with types from
atomic-polyfill
. But it's enough to get me thinking and open an issue. If it is a soundness issue as opposed to simply "two crates doing the same thing in different ways are in the same dependency graph", is it possible to fail the build if both crates get pulled in, or automatically haveportable-atomic
be a shim foratomic-polyfill
(or vice-versa)?The text was updated successfully, but these errors were encountered: