Skip to main content

ThrottleState

Struct ThrottleState 

Source
pub struct ThrottleState { /* private fields */ }
Expand description

Per-call-site throttle window.

Declare one static per site — the nros_*_throttle! macros do this for you.

§Why not an AtomicU64

There isn’t one to use. portable_atomic::AtomicU64 does not exist on 32-bit bare-metal targets under this crate’s dependency spelling (default-features = false, so no lock-based fallback), and the features that would conjure one are exactly the ones CLAUDE.md records as hard-conflicting with the critical-section the zephyr crate enables on thumbv7m. A plain non-atomic u64 would TEAR on those targets — a half-old, half-new timestamp is a window of arbitrary length.

So: a one-bit guard around a u64 — the same state word the C storage holds, decoded by the same throttle_decide. The critical section is a load, a comparison and a store, with no call inside it, and a thread that finds the guard taken does NOT spin — it treats the record as suppressed and returns. That is what makes this safe to reach from an ISR on a single core, where spinning on another context’s progress would be a deadlock rather than a delay.

The cost is that two threads deciding the SAME call site at the same instant resolve to one record rather than two. rclcpp’s state is not synchronised at all, so this is the tighter of the two.

Implementations§

Source§

impl ThrottleState

Source

pub const fn new() -> Self

A window that has never emitted.

Source

pub fn should_log(&self, now_ns: u64, interval_ns: u64) -> bool

Whether a record raised at now_ns should emit, updating the window if it does.

Source

pub fn last_emitted_ns(&self) -> Option<u64>

Timestamp of the last emitted record, or None if none.

Reduced mod 2^63 (see throttle_decide), so a reading at or above 2^63 ns comes back with its top bit cleared. Also None if a decision is in flight — this is an observability accessor, and blocking on it would give the guard the property the type docs say it must not have.

Source

pub fn reset(&self)

Re-arm: the next record emits whatever the window says.

Trait Implementations§

Source§

impl Default for ThrottleState

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Sync for ThrottleState

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.