From 5903e08f4b3e5cdf61a80a5dd658104ab03dd4aa Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 26 Jun 2022 00:53:35 +0200 Subject: [PATCH] embassy: add missing docs, add warn(missing_docs). --- embassy/src/blocking_mutex/mod.rs | 9 +++++++++ embassy/src/blocking_mutex/raw.rs | 3 +++ embassy/src/channel/mpmc.rs | 4 ++++ embassy/src/channel/signal.rs | 22 ++++++++++++++++------ embassy/src/lib.rs | 1 + embassy/src/util/forever.rs | 21 +++++++++++++++++---- embassy/src/util/select.rs | 12 ++++++++++++ embassy/src/waitqueue/waker.rs | 2 ++ embassy/src/waitqueue/waker_agnostic.rs | 2 ++ 9 files changed, 66 insertions(+), 10 deletions(-) diff --git a/embassy/src/blocking_mutex/mod.rs b/embassy/src/blocking_mutex/mod.rs index 602ec8a0..c9db89f0 100644 --- a/embassy/src/blocking_mutex/mod.rs +++ b/embassy/src/blocking_mutex/mod.rs @@ -160,11 +160,20 @@ mod thread_mode_mutex { } impl ThreadModeMutex { + /// Lock the `ThreadModeMutex`, granting access to the data. + /// + /// # Panics + /// + /// This will panic if not currently running in thread mode. pub fn lock(&self, f: impl FnOnce(&T) -> R) -> R { f(self.borrow()) } /// Borrows the data + /// + /// # Panics + /// + /// This will panic if not currently running in thread mode. pub fn borrow(&self) -> &T { assert!( raw::in_thread_mode(), diff --git a/embassy/src/blocking_mutex/raw.rs b/embassy/src/blocking_mutex/raw.rs index cbd00c56..669a23e3 100644 --- a/embassy/src/blocking_mutex/raw.rs +++ b/embassy/src/blocking_mutex/raw.rs @@ -44,6 +44,7 @@ unsafe impl Send for CriticalSectionRawMutex {} unsafe impl Sync for CriticalSectionRawMutex {} impl CriticalSectionRawMutex { + /// Create a new `CriticalSectionRawMutex`. pub const fn new() -> Self { Self { _phantom: PhantomData } } @@ -71,6 +72,7 @@ pub struct NoopRawMutex { unsafe impl Send for NoopRawMutex {} impl NoopRawMutex { + /// Create a new `NoopRawMutex`. pub const fn new() -> Self { Self { _phantom: PhantomData } } @@ -104,6 +106,7 @@ mod thread_mode { unsafe impl Sync for ThreadModeRawMutex {} impl ThreadModeRawMutex { + /// Create a new `ThreadModeRawMutex`. pub const fn new() -> Self { Self { _phantom: PhantomData } } diff --git a/embassy/src/channel/mpmc.rs b/embassy/src/channel/mpmc.rs index 1d03eef1..ca2214bb 100644 --- a/embassy/src/channel/mpmc.rs +++ b/embassy/src/channel/mpmc.rs @@ -180,6 +180,7 @@ where } } +/// Future returned by [`Channel::recv`] and [`Receiver::recv`]. pub struct RecvFuture<'ch, M, T, const N: usize> where M: RawMutex, @@ -201,6 +202,7 @@ where } } +/// Future returned by [`DynamicReceiver::recv`]. pub struct DynamicRecvFuture<'ch, T> { channel: &'ch dyn DynamicChannel, } @@ -216,6 +218,7 @@ impl<'ch, T> Future for DynamicRecvFuture<'ch, T> { } } +/// Future returned by [`Channel::send`] and [`Sender::send`]. pub struct SendFuture<'ch, M, T, const N: usize> where M: RawMutex, @@ -246,6 +249,7 @@ where impl<'ch, M, T, const N: usize> Unpin for SendFuture<'ch, M, T, N> where M: RawMutex {} +/// Future returned by [`DynamicSender::send`]. pub struct DynamicSendFuture<'ch, T> { channel: &'ch dyn DynamicChannel, message: Option, diff --git a/embassy/src/channel/signal.rs b/embassy/src/channel/signal.rs index cf78dad8..3f3c482f 100644 --- a/embassy/src/channel/signal.rs +++ b/embassy/src/channel/signal.rs @@ -4,11 +4,19 @@ use core::future::Future; use core::mem; use core::task::{Context, Poll, Waker}; -/// Synchronization primitive. Allows creating awaitable signals that may be passed between tasks. -/// For a simple use-case where the receiver is only ever interested in the latest value of -/// something, Signals work well. For more advanced use cases, you might want to use [`Channel`](crate::channel::mpmc::Channel) instead.. +/// Single-slot signaling primitive. /// -/// Signals are generally declared as being a static const and then borrowed as required. +/// This is similar to a [`Channel`](crate::channel::mpmc::Channel) with a buffer size of 1, except +/// "sending" to it (calling [`Signal::signal`]) when full will overwrite the previous value instead +/// of waiting for the receiver to pop the previous value. +/// +/// It is useful for sending data between tasks when the receiver only cares about +/// the latest data, and therefore it's fine to "lose" messages. This is often the case for "state" +/// updates. +/// +/// For more advanced use cases, you might want to use [`Channel`](crate::channel::mpmc::Channel) instead. +/// +/// Signals are generally declared as `static`s and then borrowed as required. /// /// ``` /// use embassy::channel::signal::Signal; @@ -34,6 +42,7 @@ unsafe impl Send for Signal {} unsafe impl Sync for Signal {} impl Signal { + /// Create a new `Signal`. pub const fn new() -> Self { Self { state: UnsafeCell::new(State::None), @@ -42,7 +51,7 @@ impl Signal { } impl Signal { - /// Mark this Signal as completed. + /// Mark this Signal as signaled. pub fn signal(&self, val: T) { critical_section::with(|_| unsafe { let state = &mut *self.state.get(); @@ -52,6 +61,7 @@ impl Signal { }) } + /// Remove the queued value in this `Signal`, if any. pub fn reset(&self) { critical_section::with(|_| unsafe { let state = &mut *self.state.get(); @@ -59,7 +69,7 @@ impl Signal { }) } - pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll { + fn poll_wait(&self, cx: &mut Context<'_>) -> Poll { critical_section::with(|_| unsafe { let state = &mut *self.state.get(); match state { diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index c0a0deab..b7be8b34 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs @@ -3,6 +3,7 @@ #![cfg_attr(all(feature = "nightly", target_arch = "xtensa"), feature(asm_experimental_arch))] #![allow(clippy::new_without_default)] #![doc = include_str!("../../README.md")] +#![warn(missing_docs)] // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; diff --git a/embassy/src/util/forever.rs b/embassy/src/util/forever.rs index 0e0fee59..ba3c66a9 100644 --- a/embassy/src/util/forever.rs +++ b/embassy/src/util/forever.rs @@ -31,6 +31,7 @@ unsafe impl Send for Forever {} unsafe impl Sync for Forever {} impl Forever { + /// Create a new `Forever`. #[inline(always)] pub const fn new() -> Self { Self { @@ -39,11 +40,15 @@ impl Forever { } } - /// Gives this `Forever` a value. + /// Store a value in this `Forever`, returning a mutable reference to it. /// - /// Panics if this `Forever` already has a value. + /// Using this method, the compiler usually constructs `val` in the stack and then moves + /// it into the `Forever`. If `T` is big, this is likely to cause stack overflows. + /// Considering using [`Signal::put_with`] instead, which will construct it in-place inside the `Forever`. /// - /// Returns a mutable reference to the stored value. + /// # Panics + /// + /// Panics if this `Forever` already has a value stored in it. #[inline(always)] #[allow(clippy::mut_from_ref)] pub fn put(&'static self, val: T) -> &'static mut T { @@ -52,7 +57,7 @@ impl Forever { .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) .is_err() { - panic!("Forever.put() called multiple times"); + panic!("Forever::put() called multiple times"); } unsafe { @@ -63,6 +68,14 @@ impl Forever { } } + /// Store the closure return value in this `Forever`, returning a mutable reference to it. + /// + /// The advantage over [`Forever::put`] is that this method allows the closure to construct + /// the `T` value in-place directly inside the `Forever`, saving stack space. + /// + /// # Panics + /// + /// Panics if this `Forever` already has a value stored in it. #[inline(always)] #[allow(clippy::mut_from_ref)] 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 ccc50f11..8cecb7fa 100644 --- a/embassy/src/util/select.rs +++ b/embassy/src/util/select.rs @@ -2,9 +2,12 @@ use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; +/// Result for [`select`]. #[derive(Debug, Clone)] pub enum Either { + /// First future finished first. First(A), + /// Second future finished first. Second(B), } @@ -55,10 +58,14 @@ where // ==================================================================== +/// Result for [`select3`]. #[derive(Debug, Clone)] pub enum Either3 { + /// First future finished first. First(A), + /// Second future finished first. Second(B), + /// Third future finished first. Third(C), } @@ -109,11 +116,16 @@ where // ==================================================================== +/// Result for [`select4`]. #[derive(Debug, Clone)] pub enum Either4 { + /// First future finished first. First(A), + /// Second future finished first. Second(B), + /// Third future finished first. Third(C), + /// Fourth future finished first. Fourth(D), } diff --git a/embassy/src/waitqueue/waker.rs b/embassy/src/waitqueue/waker.rs index d7151e30..cdc96507 100644 --- a/embassy/src/waitqueue/waker.rs +++ b/embassy/src/waitqueue/waker.rs @@ -16,6 +16,7 @@ pub struct WakerRegistration { } impl WakerRegistration { + /// Create a new `WakerRegistration`. pub const fn new() -> Self { Self { waker: None } } @@ -72,6 +73,7 @@ pub struct AtomicWaker { } impl AtomicWaker { + /// Create a new `AtomicWaker`. pub const fn new() -> Self { Self { waker: AtomicPtr::new(ptr::null_mut()), diff --git a/embassy/src/waitqueue/waker_agnostic.rs b/embassy/src/waitqueue/waker_agnostic.rs index 62e3adb7..64e300eb 100644 --- a/embassy/src/waitqueue/waker_agnostic.rs +++ b/embassy/src/waitqueue/waker_agnostic.rs @@ -12,6 +12,7 @@ pub struct WakerRegistration { } impl WakerRegistration { + /// Create a new `WakerRegistration`. pub const fn new() -> Self { Self { waker: None } } @@ -60,6 +61,7 @@ pub struct AtomicWaker { } impl AtomicWaker { + /// Create a new `AtomicWaker`. pub const fn new() -> Self { Self { waker: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)),