libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::LatestSnapshot< T > Class Template Reference

SPSC mailbox retaining only the latest fully published value. More...

#include <latest_snapshot.hpp>

Public Member Functions

 LatestSnapshot (const T &initial) noexcept(std::is_nothrow_copy_constructible_v< T >)
 
void Store (const T &value) noexcept(std::is_nothrow_copy_assignable_v< T >)
 Publish one complete value.
 
bool LoadLatest (T &output) noexcept(std::is_nothrow_copy_assignable_v< T >)
 Copy the latest complete value into output.
 
 LatestSnapshot (const LatestSnapshot &)=delete
 
LatestSnapshotoperator= (const LatestSnapshot &)=delete
 
 LatestSnapshot (LatestSnapshot &&)=delete
 
LatestSnapshotoperator= (LatestSnapshot &&)=delete
 

Static Private Member Functions

static constexpr uint32_t Pack (uint32_t index, bool has_new)
 
static constexpr uint32_t Index (uint32_t state)
 
static constexpr bool HasNew (uint32_t state)
 

Private Attributes

slots_ [3]
 
std::atomic< uint32_t > state_ {Pack(1U, false)}
 
uint32_t front_ = 0U
 
uint32_t back_ = 2U
 

Static Private Attributes

static constexpr uint32_t INDEX_MASK = 0x3U
 
static constexpr uint32_t HAS_NEW_BIT = 1U << 2U
 

Detailed Description

template<typename T>
class LibXR::LatestSnapshot< T >

SPSC mailbox retaining only the latest fully published value.

The producer owns one back slot, the consumer owns one front slot, and an atomic middle slot carries the latest completed publication. Repeated stores may overwrite an unconsumed middle value, but never the value currently being copied by the consumer.

Template Parameters
TCopy-assignable snapshot type.
Warning
Exactly one producer may call Store(), and exactly one serialized consumer may call LoadLatest(). Producer and consumer calls may overlap on different cores or in thread/ISR contexts.

Definition at line 24 of file latest_snapshot.hpp.

Constructor & Destructor Documentation

◆ LatestSnapshot()

template<typename T >
LibXR::LatestSnapshot< T >::LatestSnapshot ( const T & initial)
inlineexplicitnoexcept

Construct all three slots with the same initial value.

Definition at line 33 of file latest_snapshot.hpp.

35 : slots_{initial, initial, initial}
36 {
37 }

Member Function Documentation

◆ HasNew()

template<typename T >
static constexpr bool LibXR::LatestSnapshot< T >::HasNew ( uint32_t state)
inlinestaticconstexprprivate

Definition at line 96 of file latest_snapshot.hpp.

96{ return (state & HAS_NEW_BIT) != 0U; }

◆ Index()

template<typename T >
static constexpr uint32_t LibXR::LatestSnapshot< T >::Index ( uint32_t state)
inlinestaticconstexprprivate

Definition at line 94 of file latest_snapshot.hpp.

94{ return state & INDEX_MASK; }

◆ LoadLatest()

template<typename T >
bool LibXR::LatestSnapshot< T >::LoadLatest ( T & output)
inlinenoexcept

Copy the latest complete value into output.

Returns
true when this call acquired a newer publication; false when output was copied from the consumer's previously acquired snapshot.

Definition at line 59 of file latest_snapshot.hpp.

60 {
61 bool updated = false;
62 uint32_t observed = state_.load(std::memory_order_acquire);
63
64 while (HasNew(observed))
65 {
66 const uint32_t desired = Pack(front_, false);
67 if (state_.compare_exchange_weak(observed, desired, std::memory_order_acq_rel,
68 std::memory_order_acquire))
69 {
70 front_ = Index(observed);
71 updated = true;
72 break;
73 }
74 }
75
76 output = slots_[front_];
77 return updated;
78 }

◆ Pack()

template<typename T >
static constexpr uint32_t LibXR::LatestSnapshot< T >::Pack ( uint32_t index,
bool has_new )
inlinestaticconstexprprivate

Definition at line 89 of file latest_snapshot.hpp.

90 {
91 return index | (has_new ? HAS_NEW_BIT : 0U);
92 }

◆ Store()

template<typename T >
void LibXR::LatestSnapshot< T >::Store ( const T & value)
inlinenoexcept

Publish one complete value.

The value is copied into the producer-owned back slot before that slot is released to the consumer as the newest middle slot.

Definition at line 45 of file latest_snapshot.hpp.

46 {
47 slots_[back_] = value;
48
49 const uint32_t previous =
50 state_.exchange(Pack(back_, true), std::memory_order_acq_rel);
51 back_ = Index(previous);
52 }

Field Documentation

◆ back_

template<typename T >
uint32_t LibXR::LatestSnapshot< T >::back_ = 2U
private

Definition at line 101 of file latest_snapshot.hpp.

◆ front_

template<typename T >
uint32_t LibXR::LatestSnapshot< T >::front_ = 0U
private

Definition at line 100 of file latest_snapshot.hpp.

◆ HAS_NEW_BIT

template<typename T >
uint32_t LibXR::LatestSnapshot< T >::HAS_NEW_BIT = 1U << 2U
staticconstexprprivate

Definition at line 87 of file latest_snapshot.hpp.

◆ INDEX_MASK

template<typename T >
uint32_t LibXR::LatestSnapshot< T >::INDEX_MASK = 0x3U
staticconstexprprivate

Definition at line 86 of file latest_snapshot.hpp.

◆ slots_

template<typename T >
T LibXR::LatestSnapshot< T >::slots_[3]
private

Definition at line 98 of file latest_snapshot.hpp.

◆ state_

template<typename T >
std::atomic<uint32_t> LibXR::LatestSnapshot< T >::state_ {Pack(1U, false)}
private

Definition at line 99 of file latest_snapshot.hpp.

99{Pack(1U, false)};

The documentation for this class was generated from the following file: