aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy/src/blocking_mutex/mod.rs9
-rw-r--r--embassy/src/blocking_mutex/raw.rs3
-rw-r--r--embassy/src/channel/mpmc.rs4
-rw-r--r--embassy/src/channel/signal.rs22
-rw-r--r--embassy/src/lib.rs1
-rw-r--r--embassy/src/util/forever.rs21
-rw-r--r--embassy/src/util/select.rs12
-rw-r--r--embassy/src/waitqueue/waker.rs2
-rw-r--r--embassy/src/waitqueue/waker_agnostic.rs2
9 files changed, 66 insertions, 10 deletions
diff --git a/embassy/src/blocking_mutex/mod.rs b/embassy/src/blocking_mutex/mod.rs
index 602ec8a07..c9db89f01 100644
--- a/embassy/src/blocking_mutex/mod.rs
+++ b/embassy/src/blocking_mutex/mod.rs
@@ -160,11 +160,20 @@ mod thread_mode_mutex {
160 } 160 }
161 161
162 impl<T: ?Sized> ThreadModeMutex<T> { 162 impl<T: ?Sized> ThreadModeMutex<T> {
163 /// Lock the `ThreadModeMutex`, granting access to the data.
164 ///
165 /// # Panics
166 ///
167 /// This will panic if not currently running in thread mode.
163 pub fn lock<R>(&self, f: impl FnOnce(&T) -> R) -> R { 168 pub fn lock<R>(&self, f: impl FnOnce(&T) -> R) -> R {
164 f(self.borrow()) 169 f(self.borrow())
165 } 170 }
166 171
167 /// Borrows the data 172 /// Borrows the data
173 ///
174 /// # Panics
175 ///
176 /// This will panic if not currently running in thread mode.
168 pub fn borrow(&self) -> &T { 177 pub fn borrow(&self) -> &T {
169 assert!( 178 assert!(
170 raw::in_thread_mode(), 179 raw::in_thread_mode(),
diff --git a/embassy/src/blocking_mutex/raw.rs b/embassy/src/blocking_mutex/raw.rs
index cbd00c565..669a23e31 100644
--- a/embassy/src/blocking_mutex/raw.rs
+++ b/embassy/src/blocking_mutex/raw.rs
@@ -44,6 +44,7 @@ unsafe impl Send for CriticalSectionRawMutex {}
44unsafe impl Sync for CriticalSectionRawMutex {} 44unsafe impl Sync for CriticalSectionRawMutex {}
45 45
46impl CriticalSectionRawMutex { 46impl CriticalSectionRawMutex {
47 /// Create a new `CriticalSectionRawMutex`.
47 pub const fn new() -> Self { 48 pub const fn new() -> Self {
48 Self { _phantom: PhantomData } 49 Self { _phantom: PhantomData }
49 } 50 }
@@ -71,6 +72,7 @@ pub struct NoopRawMutex {
71unsafe impl Send for NoopRawMutex {} 72unsafe impl Send for NoopRawMutex {}
72 73
73impl NoopRawMutex { 74impl NoopRawMutex {
75 /// Create a new `NoopRawMutex`.
74 pub const fn new() -> Self { 76 pub const fn new() -> Self {
75 Self { _phantom: PhantomData } 77 Self { _phantom: PhantomData }
76 } 78 }
@@ -104,6 +106,7 @@ mod thread_mode {
104 unsafe impl Sync for ThreadModeRawMutex {} 106 unsafe impl Sync for ThreadModeRawMutex {}
105 107
106 impl ThreadModeRawMutex { 108 impl ThreadModeRawMutex {
109 /// Create a new `ThreadModeRawMutex`.
107 pub const fn new() -> Self { 110 pub const fn new() -> Self {
108 Self { _phantom: PhantomData } 111 Self { _phantom: PhantomData }
109 } 112 }
diff --git a/embassy/src/channel/mpmc.rs b/embassy/src/channel/mpmc.rs
index 1d03eef19..ca2214bb5 100644
--- a/embassy/src/channel/mpmc.rs
+++ b/embassy/src/channel/mpmc.rs
@@ -180,6 +180,7 @@ where
180 } 180 }
181} 181}
182 182
183/// Future returned by [`Channel::recv`] and [`Receiver::recv`].
183pub struct RecvFuture<'ch, M, T, const N: usize> 184pub struct RecvFuture<'ch, M, T, const N: usize>
184where 185where
185 M: RawMutex, 186 M: RawMutex,
@@ -201,6 +202,7 @@ where
201 } 202 }
202} 203}
203 204
205/// Future returned by [`DynamicReceiver::recv`].
204pub struct DynamicRecvFuture<'ch, T> { 206pub struct DynamicRecvFuture<'ch, T> {
205 channel: &'ch dyn DynamicChannel<T>, 207 channel: &'ch dyn DynamicChannel<T>,
206} 208}
@@ -216,6 +218,7 @@ impl<'ch, T> Future for DynamicRecvFuture<'ch, T> {
216 } 218 }
217} 219}
218 220
221/// Future returned by [`Channel::send`] and [`Sender::send`].
219pub struct SendFuture<'ch, M, T, const N: usize> 222pub struct SendFuture<'ch, M, T, const N: usize>
220where 223where
221 M: RawMutex, 224 M: RawMutex,
@@ -246,6 +249,7 @@ where
246 249
247impl<'ch, M, T, const N: usize> Unpin for SendFuture<'ch, M, T, N> where M: RawMutex {} 250impl<'ch, M, T, const N: usize> Unpin for SendFuture<'ch, M, T, N> where M: RawMutex {}
248 251
252/// Future returned by [`DynamicSender::send`].
249pub struct DynamicSendFuture<'ch, T> { 253pub struct DynamicSendFuture<'ch, T> {
250 channel: &'ch dyn DynamicChannel<T>, 254 channel: &'ch dyn DynamicChannel<T>,
251 message: Option<T>, 255 message: Option<T>,
diff --git a/embassy/src/channel/signal.rs b/embassy/src/channel/signal.rs
index cf78dad8b..3f3c482fb 100644
--- a/embassy/src/channel/signal.rs
+++ b/embassy/src/channel/signal.rs
@@ -4,11 +4,19 @@ use core::future::Future;
4use core::mem; 4use core::mem;
5use core::task::{Context, Poll, Waker}; 5use core::task::{Context, Poll, Waker};
6 6
7/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks. 7/// Single-slot signaling primitive.
8/// For a simple use-case where the receiver is only ever interested in the latest value of
9/// something, Signals work well. For more advanced use cases, you might want to use [`Channel`](crate::channel::mpmc::Channel) instead..
10/// 8///
11/// Signals are generally declared as being a static const and then borrowed as required. 9/// This is similar to a [`Channel`](crate::channel::mpmc::Channel) with a buffer size of 1, except
10/// "sending" to it (calling [`Signal::signal`]) when full will overwrite the previous value instead
11/// of waiting for the receiver to pop the previous value.
12///
13/// It is useful for sending data between tasks when the receiver only cares about
14/// the latest data, and therefore it's fine to "lose" messages. This is often the case for "state"
15/// updates.
16///
17/// For more advanced use cases, you might want to use [`Channel`](crate::channel::mpmc::Channel) instead.
18///
19/// Signals are generally declared as `static`s and then borrowed as required.
12/// 20///
13/// ``` 21/// ```
14/// use embassy::channel::signal::Signal; 22/// use embassy::channel::signal::Signal;
@@ -34,6 +42,7 @@ unsafe impl<T: Send> Send for Signal<T> {}
34unsafe impl<T: Send> Sync for Signal<T> {} 42unsafe impl<T: Send> Sync for Signal<T> {}
35 43
36impl<T> Signal<T> { 44impl<T> Signal<T> {
45 /// Create a new `Signal`.
37 pub const fn new() -> Self { 46 pub const fn new() -> Self {
38 Self { 47 Self {
39 state: UnsafeCell::new(State::None), 48 state: UnsafeCell::new(State::None),
@@ -42,7 +51,7 @@ impl<T> Signal<T> {
42} 51}
43 52
44impl<T: Send> Signal<T> { 53impl<T: Send> Signal<T> {
45 /// Mark this Signal as completed. 54 /// Mark this Signal as signaled.
46 pub fn signal(&self, val: T) { 55 pub fn signal(&self, val: T) {
47 critical_section::with(|_| unsafe { 56 critical_section::with(|_| unsafe {
48 let state = &mut *self.state.get(); 57 let state = &mut *self.state.get();
@@ -52,6 +61,7 @@ impl<T: Send> Signal<T> {
52 }) 61 })
53 } 62 }
54 63
64 /// Remove the queued value in this `Signal`, if any.
55 pub fn reset(&self) { 65 pub fn reset(&self) {
56 critical_section::with(|_| unsafe { 66 critical_section::with(|_| unsafe {
57 let state = &mut *self.state.get(); 67 let state = &mut *self.state.get();
@@ -59,7 +69,7 @@ impl<T: Send> Signal<T> {
59 }) 69 })
60 } 70 }
61 71
62 pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> { 72 fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<T> {
63 critical_section::with(|_| unsafe { 73 critical_section::with(|_| unsafe {
64 let state = &mut *self.state.get(); 74 let state = &mut *self.state.get();
65 match state { 75 match state {
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index c0a0deabf..b7be8b34c 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -3,6 +3,7 @@
3#![cfg_attr(all(feature = "nightly", target_arch = "xtensa"), feature(asm_experimental_arch))] 3#![cfg_attr(all(feature = "nightly", target_arch = "xtensa"), feature(asm_experimental_arch))]
4#![allow(clippy::new_without_default)] 4#![allow(clippy::new_without_default)]
5#![doc = include_str!("../../README.md")] 5#![doc = include_str!("../../README.md")]
6#![warn(missing_docs)]
6 7
7// This mod MUST go first, so that the others see its macros. 8// This mod MUST go first, so that the others see its macros.
8pub(crate) mod fmt; 9pub(crate) mod fmt;
diff --git a/embassy/src/util/forever.rs b/embassy/src/util/forever.rs
index 0e0fee596..ba3c66a91 100644
--- a/embassy/src/util/forever.rs
+++ b/embassy/src/util/forever.rs
@@ -31,6 +31,7 @@ unsafe impl<T> Send for Forever<T> {}
31unsafe impl<T> Sync for Forever<T> {} 31unsafe impl<T> Sync for Forever<T> {}
32 32
33impl<T> Forever<T> { 33impl<T> Forever<T> {
34 /// Create a new `Forever`.
34 #[inline(always)] 35 #[inline(always)]
35 pub const fn new() -> Self { 36 pub const fn new() -> Self {
36 Self { 37 Self {
@@ -39,11 +40,15 @@ impl<T> Forever<T> {
39 } 40 }
40 } 41 }
41 42
42 /// Gives this `Forever` a value. 43 /// Store a value in this `Forever`, returning a mutable reference to it.
43 /// 44 ///
44 /// Panics if this `Forever` already has a value. 45 /// Using this method, the compiler usually constructs `val` in the stack and then moves
46 /// it into the `Forever`. If `T` is big, this is likely to cause stack overflows.
47 /// Considering using [`Signal::put_with`] instead, which will construct it in-place inside the `Forever`.
45 /// 48 ///
46 /// Returns a mutable reference to the stored value. 49 /// # Panics
50 ///
51 /// Panics if this `Forever` already has a value stored in it.
47 #[inline(always)] 52 #[inline(always)]
48 #[allow(clippy::mut_from_ref)] 53 #[allow(clippy::mut_from_ref)]
49 pub fn put(&'static self, val: T) -> &'static mut T { 54 pub fn put(&'static self, val: T) -> &'static mut T {
@@ -52,7 +57,7 @@ impl<T> Forever<T> {
52 .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) 57 .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
53 .is_err() 58 .is_err()
54 { 59 {
55 panic!("Forever.put() called multiple times"); 60 panic!("Forever::put() called multiple times");
56 } 61 }
57 62
58 unsafe { 63 unsafe {
@@ -63,6 +68,14 @@ impl<T> Forever<T> {
63 } 68 }
64 } 69 }
65 70
71 /// Store the closure return value in this `Forever`, returning a mutable reference to it.
72 ///
73 /// The advantage over [`Forever::put`] is that this method allows the closure to construct
74 /// the `T` value in-place directly inside the `Forever`, saving stack space.
75 ///
76 /// # Panics
77 ///
78 /// Panics if this `Forever` already has a value stored in it.
66 #[inline(always)] 79 #[inline(always)]
67 #[allow(clippy::mut_from_ref)] 80 #[allow(clippy::mut_from_ref)]
68 pub fn put_with(&'static self, val: impl FnOnce() -> T) -> &'static mut T { 81 pub fn put_with(&'static self, val: impl FnOnce() -> T) -> &'static mut T {
diff --git a/embassy/src/util/select.rs b/embassy/src/util/select.rs
index ccc50f117..8cecb7fa0 100644
--- a/embassy/src/util/select.rs
+++ b/embassy/src/util/select.rs
@@ -2,9 +2,12 @@ use core::future::Future;
2use core::pin::Pin; 2use core::pin::Pin;
3use core::task::{Context, Poll}; 3use core::task::{Context, Poll};
4 4
5/// Result for [`select`].
5#[derive(Debug, Clone)] 6#[derive(Debug, Clone)]
6pub enum Either<A, B> { 7pub enum Either<A, B> {
8 /// First future finished first.
7 First(A), 9 First(A),
10 /// Second future finished first.
8 Second(B), 11 Second(B),
9} 12}
10 13
@@ -55,10 +58,14 @@ where
55 58
56// ==================================================================== 59// ====================================================================
57 60
61/// Result for [`select3`].
58#[derive(Debug, Clone)] 62#[derive(Debug, Clone)]
59pub enum Either3<A, B, C> { 63pub enum Either3<A, B, C> {
64 /// First future finished first.
60 First(A), 65 First(A),
66 /// Second future finished first.
61 Second(B), 67 Second(B),
68 /// Third future finished first.
62 Third(C), 69 Third(C),
63} 70}
64 71
@@ -109,11 +116,16 @@ where
109 116
110// ==================================================================== 117// ====================================================================
111 118
119/// Result for [`select4`].
112#[derive(Debug, Clone)] 120#[derive(Debug, Clone)]
113pub enum Either4<A, B, C, D> { 121pub enum Either4<A, B, C, D> {
122 /// First future finished first.
114 First(A), 123 First(A),
124 /// Second future finished first.
115 Second(B), 125 Second(B),
126 /// Third future finished first.
116 Third(C), 127 Third(C),
128 /// Fourth future finished first.
117 Fourth(D), 129 Fourth(D),
118} 130}
119 131
diff --git a/embassy/src/waitqueue/waker.rs b/embassy/src/waitqueue/waker.rs
index d7151e300..cdc96507f 100644
--- a/embassy/src/waitqueue/waker.rs
+++ b/embassy/src/waitqueue/waker.rs
@@ -16,6 +16,7 @@ pub struct WakerRegistration {
16} 16}
17 17
18impl WakerRegistration { 18impl WakerRegistration {
19 /// Create a new `WakerRegistration`.
19 pub const fn new() -> Self { 20 pub const fn new() -> Self {
20 Self { waker: None } 21 Self { waker: None }
21 } 22 }
@@ -72,6 +73,7 @@ pub struct AtomicWaker {
72} 73}
73 74
74impl AtomicWaker { 75impl AtomicWaker {
76 /// Create a new `AtomicWaker`.
75 pub const fn new() -> Self { 77 pub const fn new() -> Self {
76 Self { 78 Self {
77 waker: AtomicPtr::new(ptr::null_mut()), 79 waker: AtomicPtr::new(ptr::null_mut()),
diff --git a/embassy/src/waitqueue/waker_agnostic.rs b/embassy/src/waitqueue/waker_agnostic.rs
index 62e3adb79..64e300eb8 100644
--- a/embassy/src/waitqueue/waker_agnostic.rs
+++ b/embassy/src/waitqueue/waker_agnostic.rs
@@ -12,6 +12,7 @@ pub struct WakerRegistration {
12} 12}
13 13
14impl WakerRegistration { 14impl WakerRegistration {
15 /// Create a new `WakerRegistration`.
15 pub const fn new() -> Self { 16 pub const fn new() -> Self {
16 Self { waker: None } 17 Self { waker: None }
17 } 18 }
@@ -60,6 +61,7 @@ pub struct AtomicWaker {
60} 61}
61 62
62impl AtomicWaker { 63impl AtomicWaker {
64 /// Create a new `AtomicWaker`.
63 pub const fn new() -> Self { 65 pub const fn new() -> Self {
64 Self { 66 Self {
65 waker: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), 67 waker: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)),