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
impl ThrottleState
Sourcepub const fn new() -> ThrottleState
pub const fn new() -> ThrottleState
A window that has never emitted.
Sourcepub fn should_log(&self, now_ns: u64, interval_ns: u64) -> bool
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.
Sourcepub fn last_emitted_ns(&self) -> Option<u64>
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.