F´ Flight Software - C/C++ Documentation devel
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
Queue.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title Queue.cpp
3// \author mstarch, borrowed from @dinkel
4// \brief Queue implementation for Baremetal devices. No IPC nor thread
5// safety is implemented as this intended for baremetal devices.
6// Based on Os/Pthreads/Queue.cpp from @dinkel
7// ======================================================================
8#include <FpConfig.hpp>
10#include <Fw/Types/Assert.hpp>
11#include <Os/Queue.hpp>
12
13#include <new>
14#include <cstdio>
15
16namespace Os {
22 public:
23 BareQueueHandle() : m_init(false) {}
28 bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize) {
29 bool ret = m_queue.create(depth, msgSize);
30 m_init = ret;
31 return ret;
32 }
33 bool m_init;
36};
37
39 m_handle(reinterpret_cast<POINTER_CAST>(nullptr))
40{ }
41
43 BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
44 // Queue has already been created... remove it and try again:
45 if (nullptr != handle) {
46 delete handle;
47 handle = nullptr;
48 }
49 //New queue handle, check for success or return error
50 handle = new(std::nothrow) BareQueueHandle;
51 if (nullptr == handle || !handle->create(depth, msgSize)) {
53 }
54 //Set handle member variable
55 this->m_handle = reinterpret_cast<POINTER_CAST>(handle);
56 //Register the queue
57 #if FW_QUEUE_REGISTRATION
58 if (this->s_queueRegistry) {
59 this->s_queueRegistry->regQueue(this);
60 }
61 #endif
62 return QUEUE_OK;
63}
64
66 // Clean up the queue handle:
67 BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
68 if (nullptr != handle) {
69 delete handle;
70 }
71 this->m_handle = reinterpret_cast<POINTER_CAST>(nullptr);
72}
73
75 FW_ASSERT(handle.m_init);
76 BufferQueue& queue = handle.m_queue;
78 // Push item onto queue:
79 bool success = queue.push(buffer, size, priority);
80 if(!success) {
81 status = Queue::QUEUE_FULL;
82 }
83 return status;
84}
85
87 FW_ASSERT(handle.m_init);
88 BufferQueue& queue = handle.m_queue;
89 // If the queue is full, wait until a message is taken off the queue.
90 while(queue.isFull()) {
91 //Forced to assert, as blocking would destroy timely-ness
92 FW_ASSERT(false);
93 }
94 // Push item onto queue:
95 bool success = queue.push(buffer, size, priority);
96 // The only reason push would not succeed is if the queue
97 // was full. Since we waited for the queue to NOT be full
98 // before sending on the queue, the push must have succeeded
99 // unless there was a programming error or a bit flip.
100 FW_ASSERT(success, success);
101 return Queue::QUEUE_OK;
102}
103
105 //Check if the handle is null or check the underlying queue is null
106 if ((nullptr == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
107 (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
108 return QUEUE_UNINITIALIZED;
109 }
110 BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
111 BufferQueue& queue = handle.m_queue;
112 //Check that the buffer is non-null
113 if (nullptr == buffer) {
114 return QUEUE_EMPTY_BUFFER;
115 }
116 //Fail if there is a size miss-match
117 if (size < 0 || static_cast<NATIVE_UINT_TYPE>(size) > queue.getMsgSize()) {
118 return QUEUE_SIZE_MISMATCH;
119 }
120 //Send to the queue
121 if( QUEUE_NONBLOCKING == block ) {
122 return bareSendNonBlock(handle, buffer, size, priority);
123 }
124
125 return bareSendBlock(handle, buffer, size, priority);
126}
127
129 FW_ASSERT(handle.m_init);
130 BufferQueue& queue = handle.m_queue;
131 NATIVE_UINT_TYPE size = static_cast<NATIVE_UINT_TYPE>(capacity);
132 NATIVE_INT_TYPE pri = 0;
134 // Get an item off of the queue:
135 bool success = queue.pop(buffer, size, pri);
136 if(success) {
137 // Pop worked - set the return size and priority:
138 actualSize = static_cast<NATIVE_INT_TYPE>(size);
139 priority = pri;
140 }
141 else {
142 actualSize = 0;
143 if( size > static_cast<NATIVE_UINT_TYPE>(capacity) ) {
144 // The buffer capacity was too small!
146 }
147 else if( size == 0 ) {
148 // The queue is empty:
150 }
151 else {
152 // If this happens, a programming error or bit flip occurred:
153 FW_ASSERT(0);
154 }
155 }
156 return status;
157}
158
160 FW_ASSERT(handle.m_init);
161 BufferQueue& queue = handle.m_queue;
162 NATIVE_UINT_TYPE size = static_cast<NATIVE_UINT_TYPE>(capacity);
163 NATIVE_INT_TYPE pri = 0;
165 // If the queue is full, wait until a message is taken off the queue.
166 while(queue.isEmpty()) {
167 //Forced to assert, as blocking would destroy timely-ness
168 FW_ASSERT(false);
169 }
170 // Get an item off of the queue:
171 bool success = queue.pop(buffer, size, pri);
172 if(success) {
173 // Pop worked - set the return size and priority:
174 actualSize = static_cast<NATIVE_INT_TYPE>(size);
175 priority = pri;
176 }
177 else {
178 actualSize = 0;
179 if( size > (static_cast<NATIVE_UINT_TYPE>(capacity)) ) {
180 // The buffer capacity was too small!
182 }
183 else {
184 // If this happens, a programming error or bit flip occurred:
185 // The only reason a pop should fail is if the user's buffer
186 // was too small.
187 FW_ASSERT(0);
188 }
189 }
190 return status;
191}
192
194 //Check if the handle is null or check the underlying queue is null
195 if ((nullptr == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
196 (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
197 return QUEUE_UNINITIALIZED;
198 }
199 BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
200 //Check the buffer can hold the out-going message
201 if (capacity < this->getMsgSize()) {
202 return QUEUE_SIZE_MISMATCH;
203 }
204 //Receive either non-blocking or blocking
205 if(QUEUE_NONBLOCKING == block) {
206 return bareReceiveNonBlock(handle, buffer, capacity, actualSize, priority);
207 }
208 return bareReceiveBlock(handle, buffer, capacity, actualSize, priority);
209}
210
212 //Check if the handle is null or check the underlying queue is null
213 if ((nullptr == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
214 (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
215 return 0;
216 }
217 BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
218 BufferQueue& queue = handle.m_queue;
219 return queue.getCount();
220}
221
223 //Check if the handle is null or check the underlying queue is null
224 if ((nullptr == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
225 (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
226 return 0;
227 }
228 BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
229 BufferQueue& queue = handle.m_queue;
230 return queue.getMaxCount();
231}
232
234 //Check if the handle is null or check the underlying queue is null
235 if ((nullptr == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
236 (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
237 return 0;
238 }
239 BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
240 BufferQueue& queue = handle.m_queue;
241 return queue.getDepth();
242 }
243
245 //Check if the handle is null or check the underlying queue is null
246 if ((nullptr == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
247 (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
248 return 0;
249 }
250 BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
251 BufferQueue& queue = handle.m_queue;
252 return queue.getMsgSize();
253}
254}//Namespace Os
#define FW_ASSERT(...)
Definition Assert.hpp:14
PlatformPointerCastType POINTER_CAST
Definition BasicTypes.h:53
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
PlatformUIntType NATIVE_UINT_TYPE
Definition BasicTypes.h:52
C++-compatible configuration header for fprime configuration.
bool m_init
Actual queue used to store.
Definition Queue.cpp:33
BufferQueue m_queue
Definition Queue.cpp:35
bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
Definition Queue.cpp:28
A generic buffer queue data structure.
bool create(NATIVE_UINT_TYPE depth, NATIVE_UINT_TYPE msgSize)
BufferQueue creation.
NATIVE_UINT_TYPE getCount()
Get the current number of items on the queue.
NATIVE_UINT_TYPE getMsgSize()
Get the maximum message size.
bool pop(U8 *buffer, NATIVE_UINT_TYPE &size, NATIVE_INT_TYPE &priority)
pop an item off the queue
NATIVE_UINT_TYPE getDepth()
Get the queue depths.
bool isEmpty()
check if the queue is empty
bool push(const U8 *buffer, NATIVE_UINT_TYPE size, NATIVE_INT_TYPE priority)
push an item onto the queue
bool isFull()
check if the queue is full
NATIVE_UINT_TYPE getMaxCount()
Get the maximum number of items seen on the queue.
NATIVE_INT_TYPE getMsgSize() const
get the message size (maximum message size queue can hold)
Definition Queue.cpp:244
@ QUEUE_SIZE_MISMATCH
attempted to send or receive with buffer too large, too small
Definition Queue.hpp:31
@ QUEUE_UNINITIALIZED
Queue wasn't initialized successfully.
Definition Queue.hpp:30
@ QUEUE_NO_MORE_MSGS
If non-blocking, all the messages have been drained.
Definition Queue.hpp:29
@ QUEUE_EMPTY_BUFFER
supplied buffer is empty
Definition Queue.hpp:35
@ QUEUE_OK
message sent/received okay
Definition Queue.hpp:28
@ QUEUE_FULL
queue was full when attempting to send a message
Definition Queue.hpp:36
QueueStatus send(const Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE priority, QueueBlocking block)
send a message
QueueStatus createInternal(const Fw::StringBase &name, NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
create a message queue
Definition Queue.cpp:42
QueueStatus receive(Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE &priority, QueueBlocking block)
receive a message
NATIVE_INT_TYPE getQueueSize() const
get the queue depth (maximum number of messages queue can hold)
Definition Queue.cpp:233
NATIVE_INT_TYPE getMaxMsgs() const
get the maximum number of messages (high watermark)
Definition Queue.cpp:222
QueueBlocking
Definition Queue.hpp:40
@ QUEUE_NONBLOCKING
Queue receive always returns even if there is no message.
Definition Queue.hpp:42
NATIVE_INT_TYPE getNumMsgs() const
get the number of messages in the queue
Definition Queue.cpp:211
virtual ~Queue()
Definition Queue.cpp:65
POINTER_CAST m_handle
handle for implementation specific queue
Definition Queue.hpp:75
Definition File.cpp:6
Queue::QueueStatus bareReceiveBlock(BareQueueHandle &handle, U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &actualSize, NATIVE_INT_TYPE &priority)
Definition Queue.cpp:159
Queue::QueueStatus bareSendNonBlock(BareQueueHandle &handle, const U8 *buffer, NATIVE_INT_TYPE size, NATIVE_INT_TYPE priority)
Definition Queue.cpp:74
Queue::QueueStatus bareSendBlock(BareQueueHandle &handle, const U8 *buffer, NATIVE_INT_TYPE size, NATIVE_INT_TYPE priority)
Definition Queue.cpp:86
Queue::QueueStatus bareReceiveNonBlock(BareQueueHandle &handle, U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &actualSize, NATIVE_INT_TYPE &priority)
Definition Queue.cpp:128