F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
PriorityMemQueue.hpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Os/Generic/PriorityMemQueue.hpp
3 // \author B. Duckett
4 // \brief hpp file for AtomicQueue-based priority queue implementation for Os::Queue
5 //
6 // \copyright
7 // Copyright 2026, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 // ======================================================================
11 #ifndef OS_GENERIC_PRIORITYMEMQUEUE_HPP
12 #define OS_GENERIC_PRIORITYMEMQUEUE_HPP
13 
14 #include <atomic>
16 #include "Os/CountingSemaphore.hpp"
18 #include "Os/Queue.hpp"
19 
20 namespace Os {
21 namespace Generic {
22 
23 // Constants
24 namespace Queue {
25 // Maximum number of priority levels supported per queue (0-31).
26 // Limited to 32 to:
27 // - Fit priority bitmask in a 32-bit atomic for efficient lock-free operations
28 // - Meet typical F' component needs (most use 2-4 priorities)
29 // WARNING: Standard F' components may use priorities outside this range.
30 // Ensure FPP priority assignments are within [0, MAX_PRIORITIES-1].
31 constexpr static FwSizeType MAX_PRIORITIES = 32;
32 constexpr static FwSizeType DEFAULT_PRIORITY = 0;
33 } // namespace Queue
34 
35 // Forward declarations
36 class PriorityMemQueue;
37 
44  // Sparse priority support: map priority→index into m_atomicQueues
45  // Reduces memory waste when using non-consecutive priorities (e.g., {0, 15, 31})
46  I8 m_priorityMap[Queue::MAX_PRIORITIES]; // Priority→index mapping (-1 = unused)
47  Types::AtomicQueue* m_atomicQueues = nullptr; // Array sized to actual configured priorities
48 
49  // Rule of Five: prevent accidental copy/move of resource-owning handle
54  FwQueuePriorityType m_maxPriority = 0; // Highest priority value (for iteration)
55  FwSizeType m_numActivePriorities = 0; // Number of configured priorities
56  Os::CountingSemaphore* m_notEmptySem = nullptr; // Counting semaphore signaling messages available
57  FwEnumStoreType m_id = 0; // Queue identifier
58  FwEnumStoreType m_allocatorId = 0; // Allocator ID for memory operations
59  std::atomic<U32> m_priorityMask{0}; // Bit mask of enabled priorities
60  std::atomic<U32>* m_highWaterMarks = nullptr; // Array indexed by priority map
61 
64  // Initialize priority map to all -1 (unused)
65  for (FwSizeType i = 0; i < Queue::MAX_PRIORITIES; ++i) {
66  m_priorityMap[i] = -1;
67  }
68  }
69 
71  void init();
72 
78  bool allocateArrays(Fw::MemAllocator& allocator, FwEnumStoreType allocatorId);
79 
83  void deallocateArrays(Fw::MemAllocator& allocator, FwEnumStoreType allocatorId);
84 
88  void enablePriority(FwQueuePriorityType priority);
89 
93  void disablePriority(FwQueuePriorityType priority);
94 
99  // Bounds check before array access (buffer overflow protection)
100  FW_ASSERT(priority < Queue::MAX_PRIORITIES, priority);
101  return this->m_priorityMap[priority];
102  }
103 };
112 
114  public:
120  };
121 
123  struct QueueConfig {
124  FwEnumStoreType instanceId; // Per component creates pass in instance ID
125  FwSizeType numPriorities; // Number of priorities
126  QueuePriorityConfig* priorityConfigs; // Array of priority configurations
127  };
137  static void configure(QueueConfig* queueConfigs,
138  FwSizeType numQueueConfigs,
139  bool required,
140  FwEnumStoreType allocatorId);
141 
146  static void resetConfig();
147 
148  public:
151 
153  virtual ~PriorityMemQueue();
154 
156  explicit PriorityMemQueue(const QueueInterface& other) = delete;
157 
159  explicit PriorityMemQueue(const QueueInterface* other) = delete;
160 
162  PriorityMemQueue& operator=(const QueueInterface& other) override = delete;
163 
176  const Fw::ConstStringBase& name,
177  FwSizeType depth,
178  FwSizeType messageSize) override;
179 
184  void teardown() override;
185 
192  void teardownInternal();
193 
208  Status send(const U8* buffer, FwSizeType size, FwQueuePriorityType priority, BlockingType blockType) override;
209 
225  Status receive(U8* destination,
226  FwSizeType capacity,
227  BlockingType blockType,
228  FwSizeType& actualSize,
229  FwQueuePriorityType& priority) override;
230 
234  FwSizeType getMessagesAvailable() const override;
235 
241  FwSizeType getMessageHighWaterMark() const override;
242 
243  QueueHandle* getHandle() override;
244 
246 
247  private:
250  static QueueConfig* s_configs;
251  static FwSizeType s_numConfigs;
252  static bool s_requirePrioritySizing;
253  static std::atomic<bool>* s_configsUsed;
254  static bool s_configured;
255  static FwEnumStoreType s_allocatorId;
256 
257  private:
260  FwQueuePriorityType findHighestPriority(U32 priorities = 0);
261 
265  bool isPriorityEnabled(FwQueuePriorityType priority);
266 
270  void setPriorityEnabled(FwQueuePriorityType priority, bool enabled);
271 
274  Fw::MemAllocator& getAllocator();
275 
276  private:
281  QueueConfig* findMatchingConfig(FwEnumStoreType id);
282 
289  QueueInterface::Status createConfiguredQueues(QueueConfig* queueConfig,
290  Fw::MemAllocator& allocator,
291  FwEnumStoreType allocatorId);
292 
300  QueueInterface::Status createDefaultQueue(FwSizeType depth,
301  FwSizeType messageSize,
302  Fw::MemAllocator& allocator,
303  FwEnumStoreType allocatorId);
304 
313  QueueInterface::Status createPriorityQueue(FwQueuePriorityType priority,
314  FwSizeType maxMsgSize,
315  FwSizeType numMsgs,
316  Fw::MemAllocator& allocator,
317  FwEnumStoreType allocatorId);
318 };
319 } // namespace Generic
320 } // namespace Os
321 
322 #endif // OS_GENERIC_PRIORITYMEMQUEUE_HPP
PriorityMemQueue & operator=(const QueueInterface &other) override=delete
assignment operator is forbidden
I8 m_priorityMap[Queue::MAX_PRIORITIES]
void enablePriority(FwQueuePriorityType priority)
Enable a specific priority (in the handle )
PlatformSizeType FwSizeType
I32 FwEnumStoreType
void teardown() override
teardown the queue
Status
status returned from the queue send function
Definition: Queue.hpp:30
static constexpr FwSizeType MAX_PRIORITIES
AtomicQueue-based priority queue implementation.
QueueHandle parent class.
Definition: Queue.hpp:19
int8_t I8
8-bit signed integer
Definition: BasicTypes.h:51
static void configure(QueueConfig *queueConfigs, FwSizeType numQueueConfigs, bool required, FwEnumStoreType allocatorId)
Register per-priority sizes for component instances which do queueing with multiple priorities...
static constexpr FwSizeType DEFAULT_PRIORITY
base queue interface
Definition: Queue.hpp:27
QueueHandle * getHandle() override
return the underlying queue handle (implementation specific)
virtual ~PriorityMemQueue()
default queue destructor
PriorityMemQueueHandle m_handle
A lock-free MPMC FIFO circular buffer with fixed-size buffer storage.
Definition: AtomicQueue.hpp:51
Status receive(U8 *destination, FwSizeType capacity, BlockingType blockType, FwSizeType &actualSize, FwQueuePriorityType &priority) override
receive a message from the queue
static void resetConfig()
Reset static configuration (test environments only)
FwSizeType getMessagesAvailable() const override
get number of messages available
void init()
Initialize the handle.
void deallocateArrays(Fw::MemAllocator &allocator, FwEnumStoreType allocatorId)
Deallocate arrays for priority data.
Status create(FwEnumStoreType id, const Fw::ConstStringBase &name, FwSizeType depth, FwSizeType messageSize) override
create queue storage
PriorityMemQueueHandle & operator=(const PriorityMemQueueHandle &)=delete
bool allocateArrays(Fw::MemAllocator &allocator, FwEnumStoreType allocatorId)
Allocate arrays for priority data (sparse allocation) Uses m_priorityMap to determine which prioritie...
Os::CountingSemaphore * m_notEmptySem
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
Configuration for a queue with multiple priorities.
BlockingType
message type
Definition: Queue.hpp:46
PlatformQueuePriorityType FwQueuePriorityType
The type of queue priorities used.
critical data stored for priority queue
Memory Allocation base class.
I8 getPriorityIndex(FwQueuePriorityType priority) const
Get array index for a priority (inline for performance)
A read-only abstract superclass for StringBase.
void disablePriority(FwQueuePriorityType priority)
Disable a specific priority.
void teardownInternal()
teardown the queue
Defines a base class for a memory allocator for classes.
Status send(const U8 *buffer, FwSizeType size, FwQueuePriorityType priority, BlockingType blockType) override
send a message into the queue
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PriorityMemQueue()
queue interface constructor - initializes handle
FwSizeType getMessageHighWaterMark() const override
get maximum messages stored at any given time