Skip to content
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 Zephyr kernel objects #5

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open

Support for Zephyr kernel objects #5

wants to merge 15 commits into from

Conversation

d3zd3z
Copy link
Collaborator

@d3zd3z d3zd3z commented Sep 17, 2024

This PR adds a Rust abstraction around Zephy's kernel objects. This includes a mechanism to use statically declared kernel objects, as well as the possibility of dynamically allocated objects, managed as a pool for each type.

The initial kernel object supported is the k_mutex, which is managed by the rust type sys::Mutex. This is a thin wrapper around k_mutex, and can be used for simple coordination. It, however, does not manage Send/Sync aspects that are handled by std::sync::Mutex, which functionality will be provided in a later PR.

Closes #16, Closes #17, Closes #18, Closes #19, Closes #20, Closes #21

@d3zd3z d3zd3z marked this pull request as ready for review October 8, 2024 17:35
@d3zd3z d3zd3z self-assigned this Oct 8, 2024
Kconfig Outdated Show resolved Hide resolved
zephyr/src/alloc_impl.rs Outdated Show resolved Hide resolved
@hakehuang
Copy link

hakehuang commented Oct 9, 2024

any hints on build? I get below error

error: RUST (defined at modules/Kconfig.rust:4) is assigned in a configuration file, but is not
directly user-configurable (has no prompt). It gets its value indirectly from other symbols. See
http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_RUST and/or look up RUST in the
menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration Values,
and Kconfig - Tips and Best Practices sections of the manual might be helpful too.

Copy link
Collaborator

@teburd teburd left a comment

Choose a reason for hiding this comment

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

I think some further thought needs to go into initialization or wrapping various zephyr primitives.

It's likely undefined behavior to reinitialize/respawn a running thread, or reinitialize a synchronization object. The Rust wrapper here doesn't seem to signal that with unsafe markers and likely should.

samples/philosophers/src/lib.rs Outdated Show resolved Hide resolved
samples/philosophers/src/lib.rs Outdated Show resolved Hide resolved
zephyr/src/sys/thread.rs Outdated Show resolved Hide resolved
zephyr/src/sys/sync.rs Outdated Show resolved Hide resolved
@d3zd3z d3zd3z marked this pull request as draft October 11, 2024 16:14
@d3zd3z
Copy link
Collaborator Author

d3zd3z commented Oct 11, 2024

Converting this to a draft, so that I can make this in to some smaller PRs for better review.

@d3zd3z
Copy link
Collaborator Author

d3zd3z commented Oct 15, 2024

Rewrote this on top of #12. Missing is the stats implementation in the philosopher demo.

@cfriedt
Copy link
Member

cfriedt commented Oct 16, 2024

Oh man - malloc stats? I should probably push that PR over the finish line :-/

In preparation for adding more synchronization primitives, move the
Semaphore implementation into its own module.  There is enough stuff
associated with each primitive that it can be confusing if they are not
in their own modules.

Signed-off-by: David Brown <[email protected]>
Add support for declaring static instances and arrays of the sys Mutex
and sys Condvar.

Signed-off-by: David Brown <[email protected]>
Although it is tradition in Rust to have types such as Semaphores and
Mutexes not implement Sync, these primitives, built as thing wrappers
become fairly useless.  Sharing them would require `Arc`, which requires
alloc. Presumably someone wanting to use lower level primitives would
also not likely be wanting to use allocation.

For the most part, these primtives have as their real purpose to be used
in the implementation of the higher level synchronization primtives,
such as sync::Mutex.

unlock is unsafe because it is required to only call unlock on the same
thread that locked.

Signed-off-by: David Brown <[email protected]>
Add a version of the philosopher's demo that is built around sys::Mutex,
in it's simplest use case.

Signed-off-by: David Brown <[email protected]>
Create higher-level Mutex and Condvar types that are similar to
std::sync::Mutex and std::sync::Condvar.

The main difference is that the only current constructor for this
requires the sys Mutex and sys Condvar from the sys versions that are
statically allocated.

Signed-off-by: David Brown <[email protected]>
Build a syncer that coordinates the forks using a single Mutex/Condvar
pair, where the Mutex protects the data, and Condvar is used to
coordinate.  This is a common paradigm for shared synchronization.

Signed-off-by: David Brown <[email protected]>
A simple wrapper around Zephyr's k_queue.

Signed-off-by: David Brown <[email protected]>
Create an implementation of bounded channels, in the spirit of
crossbeam-channel.  Currently, only the bounded channels are supported,
an as we don't yet support recovery from panic, ther is no poisoning.

As the underlying Zephyr queues don't support deallocation, drop is also
a no-op.

Signed-off-by: David Brown <[email protected]>
Add a synchronizer for forks based on sending messages over channels to
a worker thread.

Signed-off-by: David Brown <[email protected]>
Rather than just printing a bunch of information out as the various
philosopher threads dine, use some data protected within a Mutex to
collect statistics, and print those out periodically.

Signed-off-by: David Brown <[email protected]>
Although this function has constraints on how it can be used (the thread
that calls unlock must also have called lock).  However, according to
the documentation, it detects this, and returns an error.  As such, the
wrapper in Rust does not need to be `unsafe` but can merely reflect that
error code in the `Result` that it returns.

Signed-off-by: David Brown <[email protected]>
Now that `sys::Mutex::unlock` has lost its `unsafe`, we don't need an
unsafe block for it.

Signed-off-by: David Brown <[email protected]>
This function returns initialized memory, and is therefore inherently
unsafe.  Added some commentary about how it is used safely.

Signed-off-by: David Brown <[email protected]>
Move the Wrapped trait above the StaticKernelObject so that the traits
are immediately declared after the type the apply to.

Signed-off-by: David Brown <[email protected]>
Although these, in their current state, are safe to Clone, having these
semantics will make it difficult for us to later add these types that
are allocated from a pool.

Uses that currently expect to clone can generally wrap these in an Arc,
to allow for the sharing.

Signed-off-by: David Brown <[email protected]>
@d3zd3z
Copy link
Collaborator Author

d3zd3z commented Oct 22, 2024

Nothing new, just a rebase on top of the thread fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

simple log to printk sync::channel, unbounded sync::Mutex/Condvar sys Queue interface sys Mutex/Condvar
5 participants