-
Notifications
You must be signed in to change notification settings - Fork 290
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
Support atomic-polyfill
for targets without native atomics
#573
base: master
Are you sure you want to change the base?
Conversation
There is also a |
See #461 for previous discussions. |
Not sure if there are any blockers, but that PR is marked as a draft, so I haven't reviewed it. |
The situation has changed since that PR was opened and I'm wondering about how to update it. The main issue is how targets without CAS are handled with default features.
Perhaps it would be preferable to start with the third and then select the first or second in the future if necessary? |
On
It's not feasible to add support for every single piece of hardware out there to |
Yeah, the ability to support different platforms and environments is a big advantage of As for comparing |
I don't agree with your argument on the use of Cargo features. The argument is: with Cargo features any library could incorrectly enable it, leading to unsoundness in the final binary, while
Also note that neither |
If the cargo feature is enabled somewhere in the dependency tree, it will be enabled in the entire dependency tree.1 However, due to this property, in my opinion, features that may affect soundness and stability should be cfg, not cargo features. This is also the approach actually adopted by some of the very popular crates in the ecosystem. For example: https://docs.rs/time/0.3.4/time/#feature-flags:
https://docs.rs/proc-macro2/1.0.45/proc_macro2/index.html#unstable-features:
If a crate is platform-specific, I think it is reasonable to enable the feature by default, since it is clear that the user intends the code to be platform-specific when depending on that crate.
That section says:
I often see such caveats in libraries with mutually exclusive features, but I have seen many cases where the library has enabled one of them... In critical-section's case, I think direct users are aware of this, but I question whether users who indirectly depend on critical-section are aware of it. For example, cortex-m provides the critical-section implementation as an optional feature, but it does not seem to inherit the caveat that the library should not enable it, and users may not be aware of that caveat unless they go read the critical-section documentation. (And it would be unrealistic to expect all libraries that provide critical-section implementations to inherit that caveat. And when using cfg, you can force that only the end user can enable the feature, regardless of whether or not the user has read and followed the indirect dependency documentation.) Footnotes
|
IIUC, the The
My point is, if enabling the critical-section impl in
It's implied by "you should only enable this if the target is single-core". If the lib doesn't know the target is single-core, it is a logic error in the lib's part to enable it. I agree the docs could be improved though. Also, in practice, it's not likely lib authors end up enabling a CS impl without fully knowing the consequences to workaround build failures. This is because CS impls don't add any public API. A lib using Compare with |
I gave one example of each of cfg affecting soundness and stability, and did not intend to compare them to ours.
I'm not sure if making the affected API unsafe would have solved the problem. unsafe API usually has a way to use the API in a sound way, but in local_offset's case, it seems that whether SIGSEGV occurs depends on linked c/c++ dependencies, etc., and it is doubtful that the direct caller of the API can guarantee safety.
Even if the library's API did not have the CS API, I believe CS would always be considered a public dependency of the library, since updating the CS version or removing CS impls or dependency on CS could break downstream builds.1
I ofen see cases where a feature used only in testing is declared in a dependency rather than a dev-dependency, so I would not be surprised if someone accidentally enables it in a library.
When using portable-atomic, cfg is indeed required for builds on such targets, but there is no risk that how the cfg is set up will affect the downstream. Footnotes
|
This is orthogonal to the "feature vs cfg" decision.
The readme says pretty clearly what one should do in that case. Also, it's very unlikely a lib author could do that mistake. For example, enabling
My argument was: if enabling the "dangerous" feature adds methods/structs to the public API it's more likely that lib authors might be tempted to enable it. Critical section impls add no methods/structs to the public API, so it's much less likely that lib authors will be tempted to. ... anyway, my opinion overall is the argument in favor of cfg's is a very theoretical "lib authors might make a mistake", which a) the likelihood is very low IMO and b) lib authors can already make other mistakes that cause unsoundness anyway. while the argument against |
Adopt the third idea of tokio-rs#573 (comment).
Adopt the third idea of tokio-rs#573 (comment).
Adopt the third idea of tokio-rs#573 (comment).
Adopt the third idea of tokio-rs#573 (comment).
Remove uses of unstable feature(cfg_target_has_atomic) fix setup codegen ci add comment update list Use portable-atomic and remove our own logic for now Adopt the third idea of tokio-rs#573 (comment). Enable portable-atomic's require-cas feature This provides a better error message if the end user forgets to use the cfg or feature.
Hi!
It's awesome that this crate is
no-std
(it's actually being used in some firmware!) -- but we've found that when compiling for architectures without native atomics support such asthumbv6m-none-eabi
(i.e., Cortex-M0 such as in the Atmel ATSAMD21 and Raspberry Pi RP2040), well, we can't compile...While the
core::sync::atomic
modules/types exist in those targets, they don't actually support compare_exchange/fetch_add/fetch_sub as are used by this crate.The awesome folks working on Embassy actually have an
atomic-polyfill
crate for this exact scenario, this PR adds a feature gate to use it, allowing one to build this crate for even moreno-std
targets.