Skip to content

Conversation

ithinuel
Copy link
Member

I didn’t get time to test this on rp235x yet. If anyone has the bandwidth please try it and let me know <3

An example use case:

($t:ident, $doc:expr, $offset:expr) => {
impl<S: ValidStateMachine, W: TransferSize> Wakeable for $t<S, W> {
fn waker() -> &'static IrqWaker {
static WAKER: IrqWaker = IrqWaker::new();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First: I may be completely wrong, feel free to just tell me that I'm writing nonsense. I don't understand the internals of async rust well enough to confidently state that there is an issue with this code. I just don't understand how it is supposed to work.

If I understand this correctly, there is an issue with this static: It is shared with all instances of Rx (or Tx). There are no separate instances per monomorphization (https://doc.rust-lang.org/reference/items/static-items.html#r-items.static.generics). Therefore, if there are multiple state machines running in parallel, and one tries to await the Rx (or Tx) of more than one state machine at the same time, the second one to be polled will overwrite the waker of the first one.

Of course, this only matters if there actually are multiple wakers. With the trivial mock-executor used in the on-target-tests, where a single futures is called to completion from a single task, this wouldn't make a difference.

But if, for example, the two Rx are awaited from different CPU cores, this code may wake the wrong one, and the other one might stall.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you got it right >< I thought there would be 1 instance per monomorphisation. I'll fix this !!

ithinuel added 5 commits July 12, 2025 11:55
This change saves us from reading ic_raw_intr_stat twice in the same loop.
One case is on read operations for 10bit I2C.
First a write is issued with the address, then a restart and a the msb of
the address is resent with this time the read flag.
Because there is no data phase, the peripheral entered the active state but
never switched to either Read or Write.
@ithinuel ithinuel force-pushed the async-pio branch 2 times, most recently from 4fff5fb to 8039ffb Compare July 13, 2025 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants