F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
AtomicQueue.hpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title AtomicQueue.hpp
3 // \author B. Duckett
4 // \brief A lock-free FIFO queue using atomics for thread/ISR safety
5 //
6 // \copyright
7 // Copyright 2026, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #ifndef OS_GENERIC_TYPES_ATOMIC_QUEUE_HPP
14 #define OS_GENERIC_TYPES_ATOMIC_QUEUE_HPP
15 
16 #include <Fw/FPrimeBasicTypes.hpp>
17 #include <Fw/Types/Assert.hpp>
18 #include <Fw/Types/ByteArray.hpp>
20 #include <Os/CountingSemaphore.hpp>
21 #include <atomic>
22 
23 // Forward declaration for test-only friend access
24 class AtomicQueueWrapAroundTest;
25 
26 namespace Types {
27 
52 class AtomicQueue {
53  friend class ::AtomicQueueWrapAroundTest; // Test-only accessor for counter manipulation
54  public:
56  AtomicQueue();
57 
59  ~AtomicQueue();
60 
61  // Rule of Five: prevent accidental copy/move of resource-managing class
62  AtomicQueue(const AtomicQueue&) = delete;
63  AtomicQueue& operator=(const AtomicQueue&) = delete;
64  AtomicQueue(AtomicQueue&&) = delete;
65  AtomicQueue& operator=(AtomicQueue&&) = delete;
66 
75  void create(FwSizeType numBuffers, FwSizeType bufferSize, Fw::MemAllocator& allocator, FwEnumStoreType allocatorId);
76 
78  void teardown();
79 
92  bool enqueue(const U8* buffer, FwSizeType size);
93 
113  bool enqueueBlocking(const U8* buffer, FwSizeType size, bool blockIfFull);
114 
130  bool dequeue(U8* buffer, FwSizeType capacity, FwSizeType& actualSize);
131 
135  bool isFull() const;
136 
140  bool isEmpty() const;
141 
145  FwSizeType getSize() const;
146 
150  FwSizeType getCapacity() const;
151 
155  FwSizeType getBufferSize() const;
156 
160  bool isCreated() const { return this->m_slots != nullptr && this->m_capacity > 0; }
161 
162  private:
164  static constexpr FwSizeType MAX_CAS_RETRIES = 100;
165 
176  struct Slot {
177  U8* buffer; // Embedded message buffer
178  FwSizeType size; // Actual message size stored
179  std::atomic<FwSizeType> sequence; // Coordination sequence number
180  };
181 
187  inline FwSizeType getIndex(FwSizeType pos) const {
188  FW_ASSERT(this->m_capacity > 0);
189  return (this->m_mask != 0) ? (pos & this->m_mask) : (pos % this->m_capacity);
190  }
191 
193  static U32 computeChecksum(const U8* buffer, FwSizeType size);
194 
203  bool enqueueInternal(const U8* buffer, FwSizeType size);
204 
205  // Private members:
206  Slot* m_slots; // Circular slot array
207  U8* m_bufferMemory; // Contiguous buffer memory block
208  FwSizeType m_capacity; // Number of message buffers
209  FwSizeType m_bufferSize; // Size of each message buffer
210  FwSizeType m_mask; // Bitmask if power-of-2, else 0
211  std::atomic<FwSizeType> m_enqueuePos; // Next enqueue position (producer cursor)
212  std::atomic<FwSizeType> m_dequeuePos; // Next dequeue position (consumer cursor)
213  Fw::MemAllocator* m_allocator; // Memory allocator (nullptr if not using allocator)
214  FwEnumStoreType m_allocatorId; // Allocator identifier for deallocation (also used to identify asserts)
215  Os::CountingSemaphore* m_notFullSem; // Semaphore for blocking enqueue (all platforms)
216 };
217 
218 } // namespace Types
219 
220 #endif // OS_GENERIC_TYPES_ATOMIC_QUEUE_HPP
AtomicQueue & operator=(const AtomicQueue &)=delete
PlatformSizeType FwSizeType
I32 FwEnumStoreType
~AtomicQueue()
AtomicQueue destructor.
Definition: AtomicQueue.cpp:43
AtomicQueue()
AtomicQueue constructor.
Definition: AtomicQueue.cpp:31
FwSizeType getSize() const
Get the current number of elements in the queue.
bool enqueueBlocking(const U8 *buffer, FwSizeType size, bool blockIfFull)
Enqueue with optional blocking (multi-producer safe, O(1))
A lock-free MPMC FIFO circular buffer with fixed-size buffer storage.
Definition: AtomicQueue.hpp:52
bool isEmpty() const
Check if the queue is empty.
bool isFull() const
Check if the queue is full.
bool isCreated() const
Check if queue has been successfully created.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
Memory Allocation base class.
void teardown()
Teardown the queue and free allocated memory.
FwSizeType getBufferSize() const
Get the buffer size for each message.
bool enqueue(const U8 *buffer, FwSizeType size)
Enqueue a message (multi-producer safe, non-blocking, O(1))
FwSizeType getCapacity() const
Get the maximum capacity of the queue.
Defines a base class for a memory allocator for classes.
void create(FwSizeType numBuffers, FwSizeType bufferSize, Fw::MemAllocator &allocator, FwEnumStoreType allocatorId)
Create the queue with embedded buffer storage.
Definition: AtomicQueue.cpp:47
bool dequeue(U8 *buffer, FwSizeType capacity, FwSizeType &actualSize)
Dequeue a message (multi-consumer safe, non-blocking, O(1))
#define FW_ASSERT(...)
Definition: Assert.hpp:14