-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Disabling hardware atomic instructions / providing custom implementation? #707
Comments
Found a way to disable the atomics, needed to add this in the target json file (no quotes around the number is apparently important).
Now need to figure out how to provide my own version of those core::sync::atomic structs, as spin no longer compiles, pretty much expected that through. Kinda curious if I could get it to believe it has atomic load/store but not compare-and-swap (via a "xchg" instruction, which asserts exclusivity over the bus). (rust-lang/rust#51953) |
I don't think that you have to disable atomics entirely. Instead, you could tell LLVM to compile for a i386 instead of the default generic x86 CPU, which uses more recent CPU features including |
Here's my current target specification file. If I take out "max-atomic-width", it generates the compare and swap instructions.
(it's set to code16 as I don't have my switch to protected mode quite setup yet, need to implement writing to the serial port for debugging as I don't have video output on this board). |
Have you tried to additionally pass |
You could also try adding |
Doesn't look like they have a flag to disable it (that's the 8 byte version, the one that's getting generated for me is the original "CMPXCHG" instruction, the 4 byte / 32 bit one). |
Ah ok. Still, LLVM should not create a
|
Have you tried disabling the Edit: Seems like the PR you linked in #707 (comment) uses exactly this flag instead of setting |
Ah, I spelled it wrong. had "atomic_cas", needed "atomic-cas". Thanks for that. That does in fact disable compare and swap. Looks like the spin crate explicitly uses compare and swap, so I have some work to do.
Oddly, the every x86 processor does sort of support the fetch_{sub,and,add} operations, but it doesn't return the value, but it will add/sub/and to the memory location atomically. |
According to the documentation linked in #707 (comment), LLVM should be able to emulate compare and swap instructions using mutexes. The question is whether the Rust compiler supports this. |
Regarding the spin issues: I think it's easier to write a custom version of Wikipedia lists a number of software solutions to the mutual exclusion problem, which all work without special hardware instructions. There is also an example spinlock implementation in x86 assembly that uses only |
Thanks! |
This is more of a question than an issue.
I'm wondering if anyone knows of a way to provide an alternative implementation of the atomic operations used within the alloc crate.
For my own amusement, I've been following along with this series and porting it to a really old single board computer that has an 80386EX in it. Figured, well, it's the first x86 cpu with an MMU, so what might go wrong? Turns out, quite a bit, as the 386 did not support atomic instructions, cmpxchg didn't show up until the 486. The compiler is emitting "lock cmpxchg %dl, (%ecx)", which crashes the system.
(this particular single board computer is super neat because it has a debugger built straight into the bios, although it doesn't understand 32-bit instructions very well)
rustc --print cfg --target 80386.json (a modified version of yours, but 32 bit) shows supports for atomic instructions (target_has_atomic="32", etc.), but I still haven't found a way to disable them. I realize doing so would probably break the alloc crate, which is why I'm wondering if there is a way to provide a custom implementation of atomics and sync, following the implementation that old operating systems used (disabling interrupts because there wasn't SMP support on those operating systems and doing so would prevent things such as your DMA controller from poking you in the middle of your operation).
This could also be useful for more embedded CPUs which may not have them.
(for fun, this is what I'm trying to run it on: https://wiki.embeddedarm.com/wiki/TS-3100)
The text was updated successfully, but these errors were encountered: