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/ByteArray.hpp>
19 #include <Os/CountingSemaphore.hpp>
20 #include <atomic>
21 
22 // Forward declaration for test-only friend access
23 class AtomicQueueWrapAroundTest;
24 
25 namespace Types {
26 
51 class AtomicQueue {
52  friend class ::AtomicQueueWrapAroundTest; // Test-only accessor for counter manipulation
53  public:
55  AtomicQueue();
56 
58  ~AtomicQueue();
59 
60  // Rule of Five: prevent accidental copy/move of resource-managing class
61  AtomicQueue(const AtomicQueue&) = delete;
62  AtomicQueue& operator=(const AtomicQueue&) = delete;
63  AtomicQueue(AtomicQueue&&) = delete;
64  AtomicQueue& operator=(AtomicQueue&&) = delete;
65 
74  void create(FwSizeType numBuffers, FwSizeType bufferSize, Fw::MemAllocator& allocator, FwEnumStoreType allocatorId);
75 
77  void teardown();
78 
91  bool enqueue(const U8* buffer, FwSizeType size);
92 
105  bool enqueueBlocking(const U8* buffer, FwSizeType size, bool blockIfFull);
106 
122  bool dequeue(U8* buffer, FwSizeType capacity, FwSizeType& actualSize);
123 
127  bool isFull() const;
128 
132  bool isEmpty() const;
133 
137  FwSizeType getSize() const;
138 
142  FwSizeType getCapacity() const;
143 
147  FwSizeType getBufferSize() const;
148 
152  bool isCreated() const { return this->m_slots != nullptr && this->m_capacity > 0; }
153 
154  private:
156  static constexpr FwSizeType MAX_CAS_RETRIES = 100;
157 
168  struct Slot {
169  U8* buffer; // Embedded message buffer
170  FwSizeType size; // Actual message size stored
171  std::atomic<FwSizeType> sequence; // Coordination sequence number
172  };
173 
179  inline FwSizeType getIndex(FwSizeType pos) const {
180  return (this->m_mask != 0) ? (pos & this->m_mask) : (pos % this->m_capacity);
181  }
182 
184  static U32 computeChecksum(const U8* buffer, FwSizeType size);
185 
194  bool enqueueInternal(const U8* buffer, FwSizeType size);
195 
196  // Private members:
197  Slot* m_slots; // Circular slot array
198  U8* m_bufferMemory; // Contiguous buffer memory block
199  FwSizeType m_capacity; // Number of message buffers
200  FwSizeType m_bufferSize; // Size of each message buffer
201  FwSizeType m_mask; // Bitmask if power-of-2, else 0
202  std::atomic<FwSizeType> m_enqueuePos; // Next enqueue position (producer cursor)
203  std::atomic<FwSizeType> m_dequeuePos; // Next dequeue position (consumer cursor)
204  Fw::MemAllocator* m_allocator; // Memory allocator (nullptr if not using allocator)
205  FwEnumStoreType m_allocatorId; // Allocator identifier for deallocation (also used to identify asserts)
206  Os::CountingSemaphore* m_notFullSem; // Semaphore for blocking enqueue (all platforms)
207 };
208 
209 } // namespace Types
210 
211 #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:51
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))