F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 // ======================================================================
10 #include <Fw/Types/Assert.hpp>
11 #include <Os/Queue.hpp>
12 
13 #include <stdio.h>
14 
15 namespace Os {
21  public:
22  BareQueueHandle() : m_init(false) {}
27  bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize) {
28  bool ret = m_queue.create(depth, msgSize);
29  m_init = ret;
30  return ret;
31  }
32  bool m_init;
35 };
40  m_handle(static_cast<POINTER_CAST>(NULL))
41 { }
42 
52  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
53  // Queue has already been created... remove it and try again:
54  if (NULL != handle) {
55  delete handle;
56  handle = NULL;
57  }
58  //New queue handle, check for success or return error
59  handle = new BareQueueHandle;
60  if (NULL == handle || !handle->create(depth, msgSize)) {
61  return QUEUE_UNINITIALIZED;
62  }
63  //Set handle member variable
64  this->m_handle = reinterpret_cast<POINTER_CAST>(handle);
65  //Register the queue
66  #if FW_QUEUE_REGISTRATION
67  if (this->s_queueRegistry) {
68  this->s_queueRegistry->regQueue(this);
69  }
70  #endif
71  return QUEUE_OK;
72 }
77  // Clean up the queue handle:
78  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
79  if (NULL != handle) {
80  delete handle;
81  }
82  this->m_handle = static_cast<POINTER_CAST>(NULL);
83 }
88  FW_ASSERT(handle.m_init);
89  BufferQueue& queue = handle.m_queue;
91  // Push item onto queue:
92  bool success = queue.push(buffer, size, priority);
93  if(!success) {
94  status = Queue::QUEUE_FULL;
95  }
96  return status;
97 }
103  FW_ASSERT(handle.m_init);
104  BufferQueue& queue = handle.m_queue;
105  // If the queue is full, wait until a message is taken off the queue.
106  while(queue.isFull()) {
107  //Forced to assert, as blocking would destroy timely-ness
108  FW_ASSERT(false);
109  }
110  // Push item onto queue:
111  bool success = queue.push(buffer, size, priority);
112  // The only reason push would not succeed is if the queue
113  // was full. Since we waited for the queue to NOT be full
114  // before sending on the queue, the push must have succeeded
115  // unless there was a programming error or a bit flip.
116  FW_ASSERT(success, success);
117  return Queue::QUEUE_OK;
118 }
119 
121  //Check if the handle is null or check the underlying queue is null
122  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
123  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
124  return QUEUE_UNINITIALIZED;
125  }
126  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
127  BufferQueue& queue = handle.m_queue;
128  //Check that the buffer is non-null
129  if (NULL == buffer) {
130  return QUEUE_EMPTY_BUFFER;
131  }
132  //Fail if there is a size miss-match
133  if (size < 0 || (NATIVE_UINT_TYPE) size > queue.getMsgSize()) {
134  return QUEUE_SIZE_MISMATCH;
135  }
136  //Send to the queue
137  if( QUEUE_NONBLOCKING == block ) {
138  return bareSendNonBlock(handle, buffer, size, priority);
139  }
140 
141  return bareSendBlock(handle, buffer, size, priority);
142 }
143 
145  FW_ASSERT(handle.m_init);
146  BufferQueue& queue = handle.m_queue;
147  NATIVE_UINT_TYPE size = capacity;
148  NATIVE_INT_TYPE pri = 0;
150  // Get an item off of the queue:
151  bool success = queue.pop(buffer, size, pri);
152  if(success) {
153  // Pop worked - set the return size and priority:
154  actualSize = (NATIVE_INT_TYPE) size;
155  priority = pri;
156  }
157  else {
158  actualSize = 0;
159  if( size > (NATIVE_UINT_TYPE) capacity ) {
160  // The buffer capacity was too small!
162  }
163  else if( size == 0 ) {
164  // The queue is empty:
165  status = Queue::QUEUE_NO_MORE_MSGS;
166  }
167  else {
168  // If this happens, a programming error or bit flip occured:
169  FW_ASSERT(0);
170  }
171  }
172  return status;
173 }
174 
176  FW_ASSERT(handle.m_init);
177  BufferQueue& queue = handle.m_queue;
178  NATIVE_UINT_TYPE size = capacity;
179  NATIVE_INT_TYPE pri = 0;
181  // If the queue is full, wait until a message is taken off the queue.
182  while(queue.isEmpty()) {
183  //Forced to assert, as blocking would destroy timely-ness
184  FW_ASSERT(false);
185  }
186  // Get an item off of the queue:
187  bool success = queue.pop(buffer, size, pri);
188  if(success) {
189  // Pop worked - set the return size and priority:
190  actualSize = (NATIVE_INT_TYPE) size;
191  priority = pri;
192  }
193  else {
194  actualSize = 0;
195  if( size > (NATIVE_UINT_TYPE) capacity ) {
196  // The buffer capacity was too small!
198  }
199  else {
200  // If this happens, a programming error or bit flip occurred:
201  // The only reason a pop should fail is if the user's buffer
202  // was too small.
203  FW_ASSERT(0);
204  }
205  }
206  return status;
207 }
208 
210  //Check if the handle is null or check the underlying queue is null
211  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
212  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
213  return QUEUE_UNINITIALIZED;
214  }
215  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
216  //Check the buffer can hold the out-going message
217  if (capacity < this->getMsgSize()) {
218  return QUEUE_SIZE_MISMATCH;
219  }
220  //Receive either non-blocking or blocking
221  if(QUEUE_NONBLOCKING == block) {
222  return bareReceiveNonBlock(handle, buffer, capacity, actualSize, priority);
223  }
224  return bareReceiveBlock(handle, buffer, capacity, actualSize, priority);
225 }
226 
228  //Check if the handle is null or check the underlying queue is null
229  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
230  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
231  return 0;
232  }
233  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
234  BufferQueue& queue = handle.m_queue;
235  return queue.getCount();
236 }
237 
239  //Check if the handle is null or check the underlying queue is null
240  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
241  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
242  return 0;
243  }
244  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
245  BufferQueue& queue = handle.m_queue;
246  return queue.getMaxCount();
247 }
248 
250  //Check if the handle is null or check the underlying queue is null
251  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
252  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
253  return 0;
254  }
255  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
256  BufferQueue& queue = handle.m_queue;
257  return queue.getDepth();
258  }
259 
261  //Check if the handle is null or check the underlying queue is null
262  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
263  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
264  return 0;
265  }
266  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
267  BufferQueue& queue = handle.m_queue;
268  return queue.getMsgSize();
269 }
270 }//Namespace Os
Os
Definition: File.cpp:7
Os::BufferQueue::getDepth
NATIVE_UINT_TYPE getDepth()
Get the queue depths.
Definition: BufferQueueCommon.cpp:112
Os::Queue::QUEUE_FULL
@ QUEUE_FULL
queue was full when attempting to send a message
Definition: Queue.hpp:36
Fw::StringBase
Definition: StringType.hpp:23
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Os::BufferQueue::getCount
NATIVE_UINT_TYPE getCount()
Get the current number of items on the queue.
Definition: BufferQueueCommon.cpp:99
Os::Queue::QueueStatus
QueueStatus
Definition: Queue.hpp:27
Os::Queue::getQueueSize
NATIVE_INT_TYPE getQueueSize(void) const
get the queue depth (maximum number of messages queue can hold)
Definition: Queue.cpp:249
Os::Queue::m_handle
POINTER_CAST m_handle
handle for implementation specific queue
Definition: Queue.hpp:69
Os::BufferQueue::push
bool push(const U8 *buffer, NATIVE_UINT_TYPE size, NATIVE_INT_TYPE priority)
push an item onto the queue
Definition: BufferQueueCommon.cpp:51
Os::BufferQueue
A generic buffer queue data structure.
Definition: BufferQueue.hpp:26
Os::Queue::QUEUE_EMPTY_BUFFER
@ QUEUE_EMPTY_BUFFER
supplied buffer is empty
Definition: Queue.hpp:35
Assert.hpp
Os::BareQueueHandle::m_init
bool m_init
Actual queue used to store.
Definition: Queue.cpp:32
Os::BareQueueHandle::m_queue
BufferQueue m_queue
Definition: Queue.cpp:34
Os::Queue::send
QueueStatus send(const Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE priority, QueueBlocking block)
send a message
Definition: QueueCommon.cpp:13
Os::Queue::Queue
Queue()
Definition: Queue.cpp:39
Os::Queue::QUEUE_SIZE_MISMATCH
@ QUEUE_SIZE_MISMATCH
attempted to send or receive with buffer too large, too small
Definition: Queue.hpp:31
Os::bareReceiveNonBlock
Queue::QueueStatus bareReceiveNonBlock(BareQueueHandle &handle, U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &actualSize, NATIVE_INT_TYPE &priority)
Definition: Queue.cpp:144
Os::Queue::QueueBlocking
QueueBlocking
Definition: Queue.hpp:40
Os::BufferQueue::getMaxCount
NATIVE_UINT_TYPE getMaxCount()
Get the maximum number of items seen on the queue.
Definition: BufferQueueCommon.cpp:103
Os::Queue::receive
QueueStatus receive(Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE &priority, QueueBlocking block)
receive a message
Definition: QueueCommon.cpp:22
Os::Queue::QUEUE_UNINITIALIZED
@ QUEUE_UNINITIALIZED
Queue wasn't initialized successfully.
Definition: Queue.hpp:30
BufferQueue.hpp
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Os::bareReceiveBlock
Queue::QueueStatus bareReceiveBlock(BareQueueHandle &handle, U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &actualSize, NATIVE_INT_TYPE &priority)
Definition: Queue.cpp:175
Os::BareQueueHandle::create
bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
Definition: Queue.cpp:27
Os::BufferQueue::isEmpty
bool isEmpty()
check if the queue is empty
Definition: BufferQueueCommon.cpp:95
Os::Queue::QUEUE_NO_MORE_MSGS
@ QUEUE_NO_MORE_MSGS
If non-blocking, all the messages have been drained.
Definition: Queue.hpp:29
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Os::BufferQueue::isFull
bool isFull()
check if the queue is full
Definition: BufferQueueCommon.cpp:91
Os::Queue::getMsgSize
NATIVE_INT_TYPE getMsgSize(void) const
get the message size (maximum message size queue can hold)
Definition: Queue.cpp:260
Os::Queue::getNumMsgs
NATIVE_INT_TYPE getNumMsgs(void) const
get the number of messages in the queue
Definition: Queue.cpp:227
Os::Queue::QUEUE_OK
@ QUEUE_OK
message sent/received okay
Definition: Queue.hpp:28
Os::BareQueueHandle
Definition: Queue.cpp:20
Os::BufferQueue::getMsgSize
NATIVE_UINT_TYPE getMsgSize()
Get the maximum message size.
Definition: BufferQueueCommon.cpp:108
Os::BufferQueue::create
bool create(NATIVE_UINT_TYPE depth, NATIVE_UINT_TYPE msgSize)
BufferQueue creation.
Definition: BufferQueueCommon.cpp:38
Os::bareSendBlock
Queue::QueueStatus bareSendBlock(BareQueueHandle &handle, const U8 *buffer, NATIVE_INT_TYPE size, NATIVE_INT_TYPE priority)
Definition: Queue.cpp:102
Os::Queue::QUEUE_NONBLOCKING
@ QUEUE_NONBLOCKING
Queue receive always returns even if there is no message.
Definition: Queue.hpp:42
Os::bareSendNonBlock
Queue::QueueStatus bareSendNonBlock(BareQueueHandle &handle, const U8 *buffer, NATIVE_INT_TYPE size, NATIVE_INT_TYPE priority)
Definition: Queue.cpp:87
Os::BufferQueue::pop
bool pop(U8 *buffer, NATIVE_UINT_TYPE &size, NATIVE_INT_TYPE &priority)
pop an item off the queue
Definition: BufferQueueCommon.cpp:72
Os::Queue::getMaxMsgs
NATIVE_INT_TYPE getMaxMsgs(void) const
get the maximum number of messages (high watermark)
Definition: Queue.cpp:238
Os::Queue::createInternal
QueueStatus createInternal(const Fw::StringBase &name, NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
create a message queue
Definition: Queue.cpp:51
BasicTypes.hpp
Declares ISF basic types.
Os::Queue::~Queue
virtual ~Queue()
Definition: Queue.cpp:76
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
NULL
#define NULL
NULL.
Definition: BasicTypes.hpp:100
Queue.hpp
Os::BareQueueHandle::BareQueueHandle
BareQueueHandle()
Definition: Queue.cpp:22