-
Notifications
You must be signed in to change notification settings - Fork 14
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
New Proc-macro thread declaration #67
Draft
d3zd3z
wants to merge
20
commits into
main
Choose a base branch
from
tasks
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains 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
Implement a proc macro that allows a declaration like: ```rust fn mythread(arg: usize, arg2: &'static Thing) { .. } ``` With this change, creation of threads, with arbitrary "Send" arguments can be done without needing allocation. The macros reserves a static area alongside the `k_thread` structure to use for handing the threads over. This creates a function `mythread` with the given args that returns a ReadyThread. This has a `start()` method which will begin execution of the thread. This results in a RunningThread, which has a join method that can be used to wait for termination. Signed-off-by: David Brown <[email protected]>
Move away from the `kobj_define` task declaration to use the new `#[zephyr::thread]` to define these. This allows for a more natural declaration where the thread just looks like an attribute added to a regular function declaration. This also eliminates the static Mutex, as the Mutex now has a constructor that avoids allocation (it is still put in an Arc, though). Signed-off-by: David Brown <[email protected]>
Change this declaration from a dynamic allocated type that must never be dropped to a static declaration. This is in preparation for a macro to help with the declaration. Signed-off-by: David Brown <[email protected]>
There is a fairly fundamental incompatibility between Zephyr spin locks and the Critical Section specification. Zephyr spin locks do not allow nesting from within a single spin lock. The critical section API only has an `acquire` and `release` entry, and provides no way (such as a stack frame) to have a unique context for different invocation places. Unfortunately, this means we cannot use spin locks for critical sections. Instead, this change implements critical sections using irq locking. The implementation of these macros on Zephyr does try to make them SMP safe, with a simple atomic lock, but this hasn't yet been tested, so there is a compile-time assertion against SMP. Also, these entries cannot be called from user mode. There are various other reasons we don't support usermode, so at this time, just have a compile time assertion that usermode is not enabled in the build. If it is needed, we will have to come up with another way to implement this. Signed-off-by: David Brown <[email protected]>
To help with debugging, try to give created Zephyr threads a readable name. Currently, this is based off of the name of the function used in the declaration of the thread. Signed-off-by: David Brown <[email protected]>
These are macros in Zephyr, so write explicit wrappers for them, that bindgen will be able to directly use. Signed-off-by: David Brown <[email protected]>
Ensure the atomic is set before waking the other thread to prevent a race where the other thread is able to run through the queue, but not sleep before we have a chance to wake it. Signed-off-by: David Brown <[email protected]>
Remove the sample that depended on the old non-standard executor built around work queues, and use the zephyr-executor. Signed-off-by: David Brown <[email protected]>
Add this to the device spec. This allows the `myra_sip_baseboard` to run Rust code. Signed-off-by: David Brown <[email protected]>
The pin-weak provides a weak pointer that is compatible with `Pin<Arc>`. Unfortunately, these are not compatible with the Arc that we use from portable-atomic-utils. Provide a simplified implementation of this until the pin-weak is able to gain this functionality. Signed-off-by: David Brown <[email protected]>
This reverts commit 9714921. The SMP errors were being caused by our critical section implementation incorrectly using spinlocks. Signed-off-by: David Brown <[email protected]>
After some analysis and testing, remove the compile-failure check for CONFIG_SMP. An earlier commit replaced the spinlock-based critical section code with one that uses `irq_lock()/unlock()` Although a bit unclear from both the docs and the name of these macros, the implementation on SMP definitely does have a spinlock to coordinate between CPUs on SMP. This doesn't work on some unusual platforms, such as the rp2040, but those platforms won't work with the rest of Zephyr yet for the same reason. Presumably adding support for SMP on this target will also require fixing irq_lock/unlock. The main difference between using irq_lock/unlock is that it supports nested calls, without needing a per-nest-level variable. The critical-section API doesn't provide a place to have this variable, so this allows us to have a critical-section implementation that should also work on SMP. Signed-off-by: David Brown <[email protected]>
Change this to be more general about the async executor used, instead of the zephyr-specific workq-based one. This doesn't change the sample itself, just the name. Signed-off-by: David Brown <[email protected]>
The work-queue-based executor was an attempt to implement a Rust executor that worked with Zephyr work queues. Although it was possible to make something that kind of worked, and did have the advantage of being able to use a few Zephyr primitives, it suffers from several problems: - It isn't very efficient, basically combining the overhead of async scheduling, triggered work, and the Zephyr thread scheduler. - It plays poorly with any other use of async. Since it is useful to be able to use external crates for async utilities, this normally just results in undefined-behavior. Now that we have another executor (built from Embassy), this code is also mostly unneeded. Signed-off-by: David Brown <[email protected]>
Convert away from the Zephyr-specific async to standard Rust async. This uses the Embassy crates for time and synchronization. All tasks are spawned within a single executor that runs in the main thread. Signed-off-by: David Brown <[email protected]>
Import the embassy crates, but not by path. Also, remove the specific time instance. Although and specific application will likely want to use a non-default tick rate, leaving at the 1us tick will allow the time to be used (with a slight performance cost) with any time base. Signed-off-by: David Brown <[email protected]>
Import the embassy crates, but not by path. Also remove the specific time instance. Signed-off-by: David Brown <[email protected]>
Don't require that the two time bases be the same. This allows applications to work using the default embassy-time base of 1Mhz. There is a performance cost to the conversion (which depends on the exact ratios). If the time bases are the same (which would be common for an application built for a single target), then no conversion is needed. Signed-off-by: David Brown <[email protected]>
Instead of a Struct that has to be carefully used, and requires alloc, create a macro to statically declare work queues. Signed-off-by: David Brown <[email protected]>
Update formatting from `cargo fmt`. Signed-off-by: David Brown <[email protected]>
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.
Create a new proc-macro-based way of declaring threads in Zephyr. Instead of the weird
kobj_define
macro, provide azephyr::thread
macro that can decorate an ordinary Rust function to become a builder for aReadyThread
that can just be started. Threads can also now be reused after they exit.This allows something like:
and somewhere in the code, you just call it, which returns a handle that can be used to start the thread.
There is still some things to clean up, hence the draft, but I wanted to get some exposure.