F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 };
36 
38  m_handle(static_cast<POINTER_CAST>(NULL))
39 { }
40 
42  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
43  // Queue has already been created... remove it and try again:
44  if (NULL != handle) {
45  delete handle;
46  handle = NULL;
47  }
48  //New queue handle, check for success or return error
49  handle = new BareQueueHandle;
50  if (NULL == handle || !handle->create(depth, msgSize)) {
51  return QUEUE_UNINITIALIZED;
52  }
53  //Set handle member variable
54  this->m_handle = reinterpret_cast<POINTER_CAST>(handle);
55  //Register the queue
56  #if FW_QUEUE_REGISTRATION
57  if (this->s_queueRegistry) {
58  this->s_queueRegistry->regQueue(this);
59  }
60  #endif
61  return QUEUE_OK;
62 }
63 
65  // Clean up the queue handle:
66  BareQueueHandle* handle = reinterpret_cast<BareQueueHandle*>(this->m_handle);
67  if (NULL != handle) {
68  delete handle;
69  }
70  this->m_handle = static_cast<POINTER_CAST>(NULL);
71 }
72 
74  FW_ASSERT(handle.m_init);
75  BufferQueue& queue = handle.m_queue;
77  // Push item onto queue:
78  bool success = queue.push(buffer, size, priority);
79  if(!success) {
80  status = Queue::QUEUE_FULL;
81  }
82  return status;
83 }
84 
86  FW_ASSERT(handle.m_init);
87  BufferQueue& queue = handle.m_queue;
88  // If the queue is full, wait until a message is taken off the queue.
89  while(queue.isFull()) {
90  //Forced to assert, as blocking would destroy timely-ness
91  FW_ASSERT(false);
92  }
93  // Push item onto queue:
94  bool success = queue.push(buffer, size, priority);
95  // The only reason push would not succeed is if the queue
96  // was full. Since we waited for the queue to NOT be full
97  // before sending on the queue, the push must have succeeded
98  // unless there was a programming error or a bit flip.
99  FW_ASSERT(success, success);
100  return Queue::QUEUE_OK;
101 }
102 
104  //Check if the handle is null or check the underlying queue is null
105  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
106  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
107  return QUEUE_UNINITIALIZED;
108  }
109  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
110  BufferQueue& queue = handle.m_queue;
111  //Check that the buffer is non-null
112  if (NULL == buffer) {
113  return QUEUE_EMPTY_BUFFER;
114  }
115  //Fail if there is a size miss-match
116  if (size < 0 || (NATIVE_UINT_TYPE) size > queue.getMsgSize()) {
117  return QUEUE_SIZE_MISMATCH;
118  }
119  //Send to the queue
120  if( QUEUE_NONBLOCKING == block ) {
121  return bareSendNonBlock(handle, buffer, size, priority);
122  }
123 
124  return bareSendBlock(handle, buffer, size, priority);
125 }
126 
128  FW_ASSERT(handle.m_init);
129  BufferQueue& queue = handle.m_queue;
130  NATIVE_UINT_TYPE size = capacity;
131  NATIVE_INT_TYPE pri = 0;
133  // Get an item off of the queue:
134  bool success = queue.pop(buffer, size, pri);
135  if(success) {
136  // Pop worked - set the return size and priority:
137  actualSize = (NATIVE_INT_TYPE) size;
138  priority = pri;
139  }
140  else {
141  actualSize = 0;
142  if( size > (NATIVE_UINT_TYPE) capacity ) {
143  // The buffer capacity was too small!
145  }
146  else if( size == 0 ) {
147  // The queue is empty:
148  status = Queue::QUEUE_NO_MORE_MSGS;
149  }
150  else {
151  // If this happens, a programming error or bit flip occurred:
152  FW_ASSERT(0);
153  }
154  }
155  return status;
156 }
157 
159  FW_ASSERT(handle.m_init);
160  BufferQueue& queue = handle.m_queue;
161  NATIVE_UINT_TYPE size = capacity;
162  NATIVE_INT_TYPE pri = 0;
164  // If the queue is full, wait until a message is taken off the queue.
165  while(queue.isEmpty()) {
166  //Forced to assert, as blocking would destroy timely-ness
167  FW_ASSERT(false);
168  }
169  // Get an item off of the queue:
170  bool success = queue.pop(buffer, size, pri);
171  if(success) {
172  // Pop worked - set the return size and priority:
173  actualSize = (NATIVE_INT_TYPE) size;
174  priority = pri;
175  }
176  else {
177  actualSize = 0;
178  if( size > (NATIVE_UINT_TYPE) capacity ) {
179  // The buffer capacity was too small!
181  }
182  else {
183  // If this happens, a programming error or bit flip occurred:
184  // The only reason a pop should fail is if the user's buffer
185  // was too small.
186  FW_ASSERT(0);
187  }
188  }
189  return status;
190 }
191 
193  //Check if the handle is null or check the underlying queue is null
194  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
195  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
196  return QUEUE_UNINITIALIZED;
197  }
198  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
199  //Check the buffer can hold the out-going message
200  if (capacity < this->getMsgSize()) {
201  return QUEUE_SIZE_MISMATCH;
202  }
203  //Receive either non-blocking or blocking
204  if(QUEUE_NONBLOCKING == block) {
205  return bareReceiveNonBlock(handle, buffer, capacity, actualSize, priority);
206  }
207  return bareReceiveBlock(handle, buffer, capacity, actualSize, priority);
208 }
209 
211  //Check if the handle is null or check the underlying queue is null
212  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
213  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
214  return 0;
215  }
216  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
217  BufferQueue& queue = handle.m_queue;
218  return queue.getCount();
219 }
220 
222  //Check if the handle is null or check the underlying queue is null
223  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
224  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
225  return 0;
226  }
227  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
228  BufferQueue& queue = handle.m_queue;
229  return queue.getMaxCount();
230 }
231 
233  //Check if the handle is null or check the underlying queue is null
234  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
235  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
236  return 0;
237  }
238  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
239  BufferQueue& queue = handle.m_queue;
240  return queue.getDepth();
241  }
242 
244  //Check if the handle is null or check the underlying queue is null
245  if ((NULL == reinterpret_cast<BareQueueHandle*>(this->m_handle)) ||
246  (!reinterpret_cast<BareQueueHandle*>(this->m_handle)->m_init)) {
247  return 0;
248  }
249  BareQueueHandle& handle = *reinterpret_cast<BareQueueHandle*>(this->m_handle);
250  BufferQueue& queue = handle.m_queue;
251  return queue.getMsgSize();
252 }
253 }//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:232
Os::Queue::m_handle
POINTER_CAST m_handle
handle for implementation specific queue
Definition: Queue.hpp:75
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:37
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:127
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:158
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:243
Os::Queue::getNumMsgs
NATIVE_INT_TYPE getNumMsgs(void) const
get the number of messages in the queue
Definition: Queue.cpp:210
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:85
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:73
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:221
Os::Queue::createInternal
QueueStatus createInternal(const Fw::StringBase &name, NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
create a message queue
Definition: Queue.cpp:41
BasicTypes.hpp
Declares ISF basic types.
Os::Queue::~Queue
virtual ~Queue()
Definition: Queue.cpp:64
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