Well simply put - monkey patching code. Oh boy, I can feel the raised eyebrows already.
I am working on an embedded project. Worked on Cortex-M3 until now (thumbv7v-m), and recently switched to Cortex-M (thumbv6-m), and all hell broke lose.
The main issue is that the instruction set for the M0 does not contain ldrex
/ strex
, so atomics cannot be implemented in a general case. This results in AtomicUSize
and the like not being implemented which results in sync
being left out of the alloc
crate. Which results in a bunch of nasty stuff, such as missing Arc
and Weak
, without which it is extremely difficult to share stuff between multiple threads when running above say FreeRTOS
.
But there are a lot of other crates that would normally work, but won't compile because they are using Arc
or Weak
.
The atomics CAN be implemented in most cases by disabling interrupts (if allowed by the processor state) for the duration of the operation, and taking EXTRA care in the non maskable interrupts. Neither that the processor allows interrupts to be disabled nor that no atomics are accessed from the NMI can be verified by the compiler, but in many if not most cases holds true. And even if the processor state doesn't allow interrupts to be disabled the functionality could be implemented using a syscall (yeah that's slow - but it will help putting the processor in a state where it can disable interrupts).
This means that I could supply an implementation of atomics that I KNOW that works in my particular use-case, I am aware of it's drawbacks, and I accept them. Issue a few fat warnings for whoever works on the project after myself, and SHOULD be able to use Arc
and Weak
, and anything else that depends on atomic operations.
But that would mean I would need to create the implementation of atomics inside the core
crate and allow the alloc
crate to inlcude the alloc::sync
module, which I cannot do.
Alternatively I can write my own hackyatomics::alloc::sync
module, which would simply pub use
the alloc::sync
on targets that support it, and use my hacky way otherwise, but that means that every dependency would need to be changed to use hackyatomics::alloc::sync::Arc
instead of alloc::sync::Arc
in all cases. Which is a PIA.
So. The question: Is there a way to basically monkey-patch a module into another crate? This is probably not the best solution for the use-case above, but is this something that would be worth having a discussion about? Obviously this would be restricted to binary crates (only binary crates would be allowed to define overrides / monkey-patches, otherwise all hell would brake loose. But binary crates are leaf crates, and if you do something stupid, only your own code will stop compiling, and you KNOW you did something that could end up doing that sooner or later. (Exactly the reason why I think orphan rules should be relaxed for binary crates, but that's another discussion).