F´ Flight Software - C/C++ Documentation  NASA-v1.6.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 <new>
14 #include <cstdio>
15 
16 namespace 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)) {
52  return QUEUE_UNINITIALIZED;
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:
149  status = Queue::QUEUE_NO_MORE_MSGS;
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
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
Os::Queue::getMsgSize
NATIVE_INT_TYPE getMsgSize() const
get the message size (maximum message size queue can hold)
Definition: Queue.cpp:244
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::getMaxMsgs
NATIVE_INT_TYPE getMaxMsgs() const
get the maximum number of messages (high watermark)
Definition: Queue.cpp:222
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
Os::Queue::getNumMsgs
NATIVE_INT_TYPE getNumMsgs() const
get the number of messages in the queue
Definition: Queue.cpp:211
Assert.hpp
Os::BareQueueHandle::m_init
bool m_init
Actual queue used to store.
Definition: Queue.cpp:33
Os::BareQueueHandle::m_queue
BufferQueue m_queue
Definition: Queue.cpp:35
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:38
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:128
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:159
Os::BareQueueHandle::create
bool create(NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
Definition: Queue.cpp:28
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:8
Os::BufferQueue::isFull
bool isFull()
check if the queue is full
Definition: BufferQueueCommon.cpp:91
Os::Queue::QUEUE_OK
@ QUEUE_OK
message sent/received okay
Definition: Queue.hpp:28
Os::BareQueueHandle
Definition: Queue.cpp:21
Os::BufferQueue::getMsgSize
NATIVE_UINT_TYPE getMsgSize()
Get the maximum message size.
Definition: BufferQueueCommon.cpp:108
Os::Queue::getQueueSize
NATIVE_INT_TYPE getQueueSize() const
get the queue depth (maximum number of messages queue can hold)
Definition: Queue.cpp:233
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:86
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:74
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::createInternal
QueueStatus createInternal(const Fw::StringBase &name, NATIVE_INT_TYPE depth, NATIVE_INT_TYPE msgSize)
create a message queue
Definition: Queue.cpp:42
BasicTypes.hpp
Declares ISF basic types.
Os::Queue::~Queue
virtual ~Queue()
Definition: Queue.cpp:65
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Queue.hpp
Os::BareQueueHandle::BareQueueHandle
BareQueueHandle()
Definition: Queue.cpp:23