-
Notifications
You must be signed in to change notification settings - Fork 42
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
Support for statically allocating tasks (no_alloc usage) #7
Comments
Hmm, this looks like a really really difficult problem to solve. I kind of believe that even if we managed to somehow change the API like this, in the end it would be so restrictive that it wouldn't be all that useful for embedded systems. :/ It might be easier to build a new crate that is similar to |
Not necessarily, what needs to be parametrized is the
I've built a proof of concept of the "statically allocate tasks" idea here: https://github.com/Dirbaio/static-executor . My Unfortunately it's not as powerful as async_task since there's no Out of curiosity, what's the reason async_task does the Task layout manually instead of using unions? I was going to implement JoinHandles in async_executor as an union of the future and the result, and I'm curious if there's some scary pitfall I'm not seeing. |
Interesting -- the
It's for performance - the idea was to have the best possible performance with as few atomic operations as possible and using as little memory as possible. But, I'm doubting whether it was worth it. I'm considering rewriting I don't have much more to add right now... will need to think about this a bit more. |
Ok thank you, @Dirbaio I got it. |
Probably could be solved via #24 |
Motivation
It is currently possible to use
async_task
withno_std
, but it requires havingalloc
available because tasks are dynamically allocated.In memory-constrained environments, such as embedded microcontroller devices, it's often useful to statically declare everything and not have any dynamic allocator. The main advantage is that you have compile-time guarantees that your program will never run out of RAM (The linker knows how much RAM the target device has, and will error if all the static variables won't fit).
Generally in an embedded device the following kinds of tasks are present:
It is very rare that you want an arbitrary number of tasks of arbitrary types mixed together. You rarely have enough RAM for it, and it tends to cause fragmentation problems and unpredictable out of RAM errors.
It would be a huge boon for embedded if async_task allowed statically pre-allocating tasks.
Aditionally, this would be especially useful combined with
#![feature(type_alias_impl_trait)]
(rust-lang/rust#63063), which makes it possible to name the future types of async fns. (naming the type is needed so the user can declare the static variable containing the task)API proposal
The API could be something like this
This would be used like this
When the task is no longer running (ie when it would be freed if it was dynamically allocated), the StaticTask is returned to "free" state, so it can be used by
.spawn()
again.This would make it possible to mix statically-allocated and dynamically-allocated tasks in the same executor.
Having so many generic arguments in StaticTask is somewhat ugly because the user has to manually specify them, but this is something executor libraries could abstract (ie export a newtype so you only have to set F). A higher-level executor API could be like this:
Alternatives
Add an API where the user can specify a custom allocator for spawning, via some trait. Still, th library would still have to export a type so that user code can know what's the size required for a RawTask of a given future, so they can statically allocate buffers of the right size.
The text was updated successfully, but these errors were encountered: