-
Notifications
You must be signed in to change notification settings - Fork 87
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
Panic on irq_handler overwrite #53
Conversation
That's simple solution that works. From my perspective, however, a person working on embedded systems it's 1024/2048 bytes in cache (larger on 64 bit systems¹) just to mark if we already assigned interrupt handler - quite a waste IMVHO. Some static bit array, but none of crates delivering this datatype stabilized for const generics yet. My idea (sorry, I didn't have time to work on it) was to check, if the pointer in the The alternative method is to hold array of references to trait (that way we remove the need for
Interrupt vectors have to be maximally short and fit into cache, so any interrupt handler is dispatched without delay. ¹ While Rust's size of |
Hi @michalfita, I was thinking about a static bit array, but then we will need to warp it in the SpinLock, right? I don`t know why I did not tried this before: type Callback = Box<dyn FnMut()>;
fn cmp(left: &Callback, right: &Callback) -> bool {
return left.as_ref() as *const _ == right.as_ref() as *const _;
}
fn callback() {}
fn main() {
let box1_with_callback1: Callback = Box::new(callback);
let box2_with_callback1: Callback = Box::new(callback);
let box1_with_callback2: Callback = Box::new(|| {});
let box1_with_callback3: Callback = Box::new(|| {});
assert!(cmp(&box1_with_callback1, &box2_with_callback1));
assert!(!cmp(&box1_with_callback1, &box1_with_callback2));
assert!(!cmp(&box1_with_callback2, &box1_with_callback3));
} But this works perfectly. I kind of get the Box removal idea, but just kind of :) |
This just rough idea, not exercised yet. Thanks, for checking the idea about comparing addresses. |
Okay, on the second thought this: let box1_with_callback1: Box<dyn FnMut()> = Box::new(callback);
let box2_with_callback1: Box<dyn FnMut()> = Box::new(callback); are not the same callbacks anymore because each Box::new is creating a new copy on the heap. And addresses of those copies are not the same. so this: box1_with_callback1.as_ref() as *const _ == box2_with_callback1.as_ref() as *const _ It should never be true. But it is, and I do not understand how :) UPDSo, error: comparing trait object pointers compares a non-unique vtable address
--> src/main.rs:22:5
|
22 | box1_with_callback1.as_ref() as *const _ == box2_with_callback1.as_ref() as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider extracting and comparing data pointers only
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons We can do one more conversion and get a pointer to the function If you have any idea where I should look - I am all ears :) |
Thanks for the detailed explanation! I think comparing pointers is no longer a good way. How about using static ATTACHED_IRQS: SpinLock<BitMap<32 /* = 256 / 8 */>> = SpinLock::new(BitMap::zeroed()); |
My understanding of
According to https://stackoverflow.com/questions/66673989/how-to-get-raw-pointer-of-box-without-consuming-it the box have to be explicitly dereferenced first - makes sense to me.
That approach is seem to be good as well. |
It will return a reference to T but not the "original" one. According to the docs, Box::new is
Since Box does not store information about the value, just the copy of a value, we will get a copy, not the original value, when we dereference that Box. fn test(){}
fn main() {
let a = Box::new(test as fn());
let b = Box::new(test as fn());
println!("pointer to a {:p}", &a);
println!("pointer to b {:p}", &b);
println!("derefernced a {:p}", &*a);
println!("derefernced b {:p}", &*b);
} produces: pointer to a 0x7ffc87094128
pointer to b 0x7ffc87094130
derefernced a 0x55fa220919d0
derefernced b 0x55fa220919f0 I do not see how we can check callback equality while boxing it.
it looks like this is the only way for now that everybody agrees :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:+1
Thanks for the improvement, @Lurk! |
Fixes #50
In this PR we introduce struct IrqHandler.
Right now there is only one ancillary field - attached, which allows an "overwrite" check. But potentially opens the way to build something like /proc/interrupts.