Skip to content

Commit edcef3b

Browse files
committed
zephyr: Remove stale doc references to futures
Now that the work-q based futures have been removed, remove lingering documentation references to this functionality. Signed-off-by: David Brown <[email protected]>
1 parent 4096ad7 commit edcef3b

File tree

4 files changed

+5
-100
lines changed

4 files changed

+5
-100
lines changed

Diff for: zephyr/src/embassy.rs

-10
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@
6262
//! It is perfectly permissible to use the `executor-thread` feature from embassy-executor on
6363
//! Zephyr, within the following guidelines:
6464
//!
65-
//! - The executor is incompatible with the async executor provided within [`crate::kio`], and
66-
//! because there are no features to enable this, this functions will still be accessible. Be
67-
//! careful. You should enable `no-kio` in the zephyr crate to hide these functions.
6865
//! - This executor does not coordinate with the scheduler on Zephyr, but uses an
6966
//! architecture-specific mechanism when there is no work. On Cortex-M, this is the 'wfe'
7067
//! instruction, on riscv32, the 'wfi' instruction. This means that no tasks of lower priority
@@ -74,13 +71,6 @@
7471
//!
7572
//! ## Caveats
7673
//!
77-
//! The executor provided by Embassy is fundamentally incompatible with the executor provided by
78-
//! this crate's [`crate::kio`] and [`crate::work::futures`]. Trying to use the functionality
79-
//! provided by operations, such as [`Semaphore::take_async`], will generally result in a panic.
80-
//! These routines are conditionally compiled out when `executor-zephyr` is enabled, but there is no
81-
//! way for this crate to detect the use of embassy's `executor-threaded`. Combining these will
82-
//! result in undefined behavior, likely difficult to debug crashes.
83-
//!
8474
//! [`Semaphore::take_async`]: crate::sys::sync::Semaphore::take_async
8575
8676
#[cfg(feature = "time-driver")]

Diff for: zephyr/src/lib.rs

-8
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,13 @@
4343
//! [`work::WorkQueue`] allow creation of Zephyr work queues to be used from Rust. The
4444
//! [`work::Work`] item had an action that will be invoked by the work queue, and can be manually
4545
//! submitted when needed.
46-
//! - [`kio`]: An implementation of an async executor built around triggerable work queues in
47-
//! Zephyr. Although there is a bit more overhead to this executor, it is compatible with many of
48-
//! the Zephyr synchronization types, and many of these [`sys::sync::Semaphore`], and
49-
//! [`sync::channel`] will provide `_async` variants of most of the blocking operations. These
50-
//! will return a `Future`, and can be used from async code started by the [`spawn`] function.
51-
//! In addition, because Zephyr's work queues do not work well with Zephyr's Mutex type, this is
52-
//! also a [`kio::sync::Mutex`] type that works with async.
5346
//! - [`logging`]: A logging backend for Rust on Zephyr. This will log to either `printk` or
5447
//! through Zephyr's logging framework.
5548
//!
5649
//! [`Instant`]: time::Instant
5750
//! [`Duration`]: time::Duration
5851
//! [`std::sync::atomic`]: https://doc.rust-lang.org/std/sync/atomic/
5952
//! [`std::sync::Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
60-
//! [`spawn`]: kio::spawn
6153
//!
6254
//! In addition to the above, the [`kconfig`] and [`devicetree`] provide a reflection of the kconfig
6355
//! settings and device tree that were used for a specific build. As such, the documentation

Diff for: zephyr/src/sync.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ mod pinweak {
3333

3434
/// Safe Pinned Weak references.
3535
///
36-
/// Pin<Arc<T>> can't be converted to/from Weak safely, because there is know way to know if a given
36+
/// `Pin<Arc<T>>` can't be converted to/from Weak safely, because there is know way to know if a given
3737
/// weak reference came from a pinned Arc. This wraps the weak reference in a new type so we know
3838
/// that it came from a pinned Arc.
3939
///

Diff for: zephyr/src/work.rs

+4-81
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
//! having the `k_work` embedded in their structure, and Zephyr schedules the work when the given
1818
//! reason happens.
1919
//!
20+
//! At this time, only the basic work queue type is supported.
21+
//!
2022
//! Zephyr's work queues can be used in different ways:
2123
//!
2224
//! - Work can be scheduled as needed. For example, an IRQ handler can queue a work item to process
@@ -27,102 +29,25 @@
2729
//! when the work is complete. The work queue scheduling functions are designed, and intended, for
2830
//! a given work item to be able to reschedule itself, and such usage is common.
2931
//!
30-
//! ## Waitable events
31-
//!
32-
//! The triggerable work items can be triggered to wake on a set of any of the following:
33-
//!
34-
//! - A signal. `k_poll_signal` is a type used just for waking work items. This works similar to a
35-
//! binary semaphore, but is lighter weight for use just by this mechanism.
36-
//! - A semaphore. Work can be scheduled to run when a `k_sem` is available. Since
37-
//! [`sys::sync::Semaphore`] is built on top of `k_sem`, the "take" operation for these semaphores
38-
//! can be a trigger source.
39-
//! - A queue/FIFO/LIFO. The queue is used to implement [`sync::channel`] and thus any blocking
40-
//! operation on queues can be a trigger source.
41-
//! - Message Queues, and Pipes. Although not yet provided in Rust, these can also be a source of
42-
//! triggering.
43-
//!
44-
//! It is important to note that the trigger source may not necessarily still be available by the
45-
//! time the work item is actually run. This depends on the design of the system. If there is only
46-
//! a single waiter, then it will still be available (the mechanism does not have false triggers,
47-
//! like CondVar).
48-
//!
49-
//! Also, note, specifically, that Zephyr Mutexes cannot be used as a trigger source. That means
50-
//! that locking a [`sync::Mutex`] shouldn't be use within work items. There is another
51-
//! [`kio::sync::Mutex`], which is a simplified Mutex that is implemented with a Semaphore that can
52-
//! be used from work-queue based code.
53-
//!
54-
//! # Rust `Future`
55-
//!
56-
//! The rust language, also has built-in support for something rather similar to Zephyr work queues.
57-
//! The main user-visible type behind this is [`Future`]. The rust compiler has support for
58-
//! functions, as well as code blocks to be declared as `async`. For this code, instead of directly
59-
//! returning the given data, returns a `Future` that has as its output type the data. What this
60-
//! does is essentially capture what would be stored on the stack to maintain the state of that code
61-
//! into the data of the `Future` itself. For rust code running on a typical OS, a crate such as
62-
//! [Tokio](https://tokio.rs/) provides what is known as an executor, which implements the schedule
63-
//! for these `Futures` as well as provides equivalent primitives for Mutex, Semaphores and channels
64-
//! for this code to use for synchronization.
65-
//!
66-
//! It is notable that the Zephyr implementation of `Future` operations under a fairly simple
67-
//! assumption of how this scheduling will work. Each future is invoked with a Context, which
68-
//! contains a dynamic `Waker` that can be invoked to schedule this Future to run again. This means
69-
//! that the primitives are typically implemented above OS primitives, where each manages wake
70-
//! queues to determine the work that needs to be woken.
71-
//!
72-
//! # Bringing it together.
73-
//!
74-
//! There are a couple of issues that need to be addressed to bring work-queue support to Rust.
75-
//! First is the question of how they will be used. On the one hand, there are users that will
76-
//! definitely want to make use of `async` in rust, and it is important to implement a executor,
77-
//! similar to Tokio, that will schedule this `async` code. On the other hand, it will likely be
78-
//! common for others to want to make more direct use of the work queues themselves. As such, these
79-
//! users will want more direct access to scheduling and triggering of work.
80-
//!
81-
//! ## Future erasure
82-
//!
83-
//! One challenge with using `Future` for work is that the `Future` type intentionally erases the
84-
//! details of scheduling work, reducing it down to a single `Waker`, which similar to a trait, has
85-
//! a `wake` method to cause the executor to schedule this work. Unfortunately, this simple
86-
//! mechanism makes it challenging to take advantage of Zephyr's existing mechanisms to be able to
87-
//! automatically trigger work based on primitives.
88-
//!
89-
//! As such, what we do is have a structure `Work` that contains both a `k_work_poll` as well as
90-
//! `Context` from Rust. Our handler can use a mechanism similar to C's `CONTAINER_OF` macro to
91-
//! recover this outer structure.
92-
//!
93-
//! There is some extra complexity to this process, as the `Future` we are storing associated with
94-
//! the work is `?Sized`, since each particular Future will have a different size. As such, it is
95-
//! not possible to recover the full work type. To work around this, we have a Sized struct at the
96-
//! beginning of this structure, that along with judicious use of `#[repr(C)]` allows us to recover
97-
//! this fixed data. This structure contains the information needed to re-schedule the work, based
98-
//! on what is needed.
99-
//!
10032
//! ## Ownership
10133
//!
10234
//! The remaining challenge with implementing `k_work` for Rust is that of ownership. The model
10335
//! taken here is that the work items are held in a `Box` that is effectively owned by the work
10436
//! itself. When the work item is scheduled to Zephyr, ownership of that box is effectively handed
10537
//! off to C, and then when the work item is called, the Box re-constructed. This repeats until the
106-
//! work is no longer needed (e.g. when a [`Future::poll`] returns `Ready`), at which point the work
107-
//! will be dropped.
38+
//! work is no longer needed, at which point the work will be dropped.
10839
//!
10940
//! There are two common ways the lifecycle of work can be managed in an embedded system:
11041
//!
11142
//! - A set of `Future`'s are allocated once at the start, and these never return a value. Work
11243
//! Futures inside of this (which correspond to `.await` in async code) can have lives and return
11344
//! values, but the main loops will not return values, or be dropped. Embedded Futures will
11445
//! typically not be boxed.
115-
//! - Work will be dynamically created based on system need, with threads using [`kio::spawn`] to
116-
//! create additional work (or creating the `Work` items directly). These can use [`join`] or
117-
//! [`join_async`] to wait for the results.
11846
//!
11947
//! One consequence of the ownership being passed through to C code is that if the work cancellation
12048
//! mechanism is used on a work queue, the work items themselves will be leaked.
12149
//!
122-
//! The Future mechanism in Rust relies on the use of [`Pin`] to ensure that work items are not
123-
//! moved. We have the same requirements here, although currently, the pin is only applied while
124-
//! the future is run, and we do not expose the `Box` that we use, thus preventing moves of the work
125-
//! items.
50+
//! These work items are also `Pin`, to ensure that the work actions are not moved.
12651
//!
12752
//! ## The work queues themselves
12853
//!
@@ -170,8 +95,6 @@
17095
//! [`sys::sync::Semaphore`]: crate::sys::sync::Semaphore
17196
//! [`sync::channel`]: crate::sync::channel
17297
//! [`sync::Mutex`]: crate::sync::Mutex
173-
//! [`kio::sync::Mutex`]: crate::kio::sync::Mutex
174-
//! [`kio::spawn`]: crate::kio::spawn
17598
//! [`join`]: futures::JoinHandle::join
17699
//! [`join_async`]: futures::JoinHandle::join_async
177100

0 commit comments

Comments
 (0)