Add only_once!() macro that panics if run a second time#4891
Conversation
This causes a panic if "called" twice. Can be used to ensure the same object isn't constructed twice.
| pub unsafe fn only_once_check_used(used: &mut bool) { | ||
| // Check if this bool has already been declared and initialized. If it | ||
| // has, then this is a call which is an error. | ||
| if *used { |
There was a problem hiding this comment.
This as written is unsound: it can enable unsynchronized (racing) read/writes to the static memory location. The update itself is also not atomic. As this is a static, there's no good way to make it single-threaded only. And even an AtomicBool won't work for any of our platforms that don't have CAS-like operations.
|
To make sure this doesn't get lost, I want to point to the conversation on Matrix. I believe there is a platform-specific way to build "only-once" on platforms that don't have CAS-style atomics, something like this: fn hart0_do_once(loc: *mut u8) {
let mhartid = asm!(...);
if mhartid != 0 { return false; }
with_interrupts_disabled(|| {
if *loc == 1 {
false
} else {
*loc = 1;
true
}
})
}However, for various reasons, I think it's better and more truthful if we make the chain of driver construction unsafe, up to the |
My stance is the opposite: the benefits of having a chip crate with abstraction is to encapsulate the inherit unsafety in working with HW. Our job as OS designers is to figure out how to encapsulate the unsafe operations, and Tock kernel users shouldn't have to reason about low-level details of chip safety. Additionally, the blunt tool that the |
Pull Request Overview
This allows us to do something like this:
This is useful for DMA managers that must only be created once so that two different DMA managers can't conflict when trying to ensure memory is safely shared with DMA hardware.
This works much like
static_init!()macro.Testing Strategy
I tried this by putting this in a capsule constructor and creating a capsule twice in a board. This caused a panic.
TODO or Help Wanted
I just kinda made this up as a way to avoid needing to mark DMA manager constructors as unsafe. Is there a better way? Does this actually solve the safety issue?
Documentation Updated
/docs, or no updates are required.Maybe we could document this somewhere, but I'm not sure where.
Formatting
make prepush.AI Use
code in this PR, if any, and I have manually checked and
personally certify the entire contents of this PR.
Just me.