Conversation
This allows using the constants in match arms.
Member
Author
|
As for interesting mbox user applications: Seems that TCP is using it internally, and gnrc_netapi_mbox is available (but then again, that also has a callback style way of using it). CAN is using it, but I have no hardware to play with that. |
Member
Author
|
gcoap client-side also goes onto the list of easy targets for async support. |
With the complex feature gating of Delay, this is essential for docs usability.
Member
Author
|
Main merged in once more to get updated tests. Two things are missing yet:
|
1b903bf to
ab262b6
Compare
This is required (at least) by newer versions of embassy.
ab262b6 to
d517415
Compare
Member
Author
|
The two stoppers are addressed: There is now an async ztimer test, and thanks to embassy updates, the tests can run on the stable image. APIs don't need to be complete for this to go in, so next plan is to merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This sketch PR adds async building blocks -- wrappers around RIOT APIs that produce futures and can be
.awaited.It does not add an executor (the branch async-experiments-1 contains one, but it's not very good). The embassy-executor-riot module in the riot-module-examples contains an implementation of an embassy based executor in less than 50 lines of code.
This suffices for simple examples, in particular any UDP echo tests. I'd love to add more APIs, but many are tricky:
TCP (through embedded-nal-async), UART (through embedded-io-async) and GPIO (through embedded-hal-async) should be straightforward enough (but are also not super exciting).
Mutex and message (including msg_bus, which is currently the only way to be notified of IP address changes) are tricky, as for neither, you can get a callback in the originating context. As callbacks are how wakers are triggered, implementing them will need cooperation from the executor. (This is in contrast to what is implemented now: There, the embassy-executor-riot knows nothing of what is implemented on top). The fundamental issues are:
A thread can only wait for one mutex at a time. An executor may have different tasks that wait for different mutexes. (Similarly, an application may find itself in a situation where it needs to wait for either of two mutexes).
As long as mutexes are only used like lightweight critical sections (preventing simultaneous access to any given data structure, eg. while inserting into a linked list), that's all not too bad: For those, even an async environment may just block on them. (Maybe the Rust lint for holding a mutex across await points is even user configurable and could apply to our Mutex locks). However, our use of mutexes in RIOT is mixed (for example, SUIT has a worker lock that's held for full a full firmware update).
Messages are queued or even delivered only on wait. Even if a task could make the executor wait for its requested message when it is idle, unlike a thread a task can't guarantee that its executor is always idle when the task is idle -- so tasks will practically need queues more often than not. But they're accessible only in the sequence they come in (except responses to sent messages -- sending a message and getting the response might be straightforward to implement async'ly). So when one task is awaiting to process messages of type A, and task B has generally ordered messages of type B (but is currently doing some stuff inbetween, like working off the last message), then when a new message of the type that B ordered arrives, followed by one for A, the executor either needs to drop the one for B (in the model of B not having a queue) or needs to delay what is there for A.
We might introduce some per-task queues where the executor dispatches messages as soon as they arrive (and that can probably be done without changes to RIOT), but this feels a lot like just reimplementing mboxes.
(Which also means mboxes are probably on the easy list; gotta look through what can be used with mboxes these days.)