PropWare  3.0.0.229
C++ objects and CMake build system for Parallax Propeller
queue.h
Go to the documentation of this file.
1 
26 #pragma once
27 
28 #include <cstddef>
29 #include <propeller.h>
30 
31 // Need to include this since PropWare.h is not imported
32 #ifdef __PROPELLER_COG__
33 #define PropWare PropWare_cog
34 #define virtual
35 #endif
36 
37 namespace PropWare {
38 
43 template<typename T>
44 class Queue {
45  public:
51  template<size_t N>
52  Queue (T (&array)[N], const int lockNumber = locknew())
53  : m_array(array),
54  m_arrayLength(N),
55  m_lockNumber(lockNumber),
56  m_size(0),
57  m_head(0),
58  m_tail(0) {
59  lockclr(this->m_lockNumber);
60  }
61 
71  Queue (T *array, const size_t length, const int lockNumber)
72  : m_array(array),
73  m_arrayLength(length),
74  m_lockNumber(locknew()),
75  m_size(0),
76  m_head(0),
77  m_tail(0) {
78  lockclr(this->m_lockNumber);
79  }
80 
81  ~Queue () {
82  lockclr(this->m_lockNumber);
83  lockret(this->m_lockNumber);
84  }
85 
91  size_t size () const {
92  return this->m_size;
93  }
94 
100  bool is_empty () const {
101  return 0 == this->size();
102  }
103 
109  bool is_full () const {
110  return this->m_arrayLength == this->size();
111  }
112 
116  void clear () {
117  this->m_size = 0;
118  }
119 
129  virtual Queue &enqueue (const T &value) {
130  // Lock the state and save off these volatile variables into local memory
131  while (lockset(this->m_lockNumber));
132  unsigned int head = this->m_head;
133  unsigned int tail = this->m_tail;
134  size_t size = this->m_size;
135 
136  // Move the head pointer
137  if (0 == size)
138  head = tail = 0;
139  else {
140  ++head;
141  // If the head has reached the end of the memory block, rollover
142  if (head == this->m_arrayLength)
143  head = 0;
144  }
145 
146  this->m_array[head] = value;
147 
148  // If the buffer wasn't full, increment the size
149  if (size == this->m_arrayLength) {
150  // Move the tail forward and roll over if necessary
151  ++tail;
152  if (tail == this->m_arrayLength)
153  tail = 0;
154  } else {
155  ++size;
156  }
157 
158  // Unlock the state and upload these variables back to volatile memory
159  this->m_head = head;
160  this->m_tail = tail;
161  this->m_size = size;
162  lockclr(this->m_lockNumber);
163 
164  return *this;
165  }
166 
170  Queue &insert (const T &value) {
171  return this->enqueue(value);
172  }
173 
181  virtual T dequeue () {
182  // Lock the state and save off these volatile variables into local memory
183  while (lockset(this->m_lockNumber));
184  unsigned int head = this->m_head;
185  unsigned int tail = this->m_tail;
186  size_t size = this->m_size;
187 
188  T *retVal;
189  if (size) {
190  retVal = &this->m_array[tail];
191 
192  --size;
193 
194  if (size) {
195  // Move the tail forward and roll over if necessary
196  ++tail;
197  if (tail == this->m_arrayLength)
198  tail = 0;
199  }
200  } else
201  retVal = NULL;
202 
203  // Unlock the state and upload these variables back to volatile memory
204  this->m_head = head;
205  this->m_tail = tail;
206  this->m_size = size;
207  lockclr(this->m_lockNumber);
208 
209  return *retVal;
210  }
211 
219  T peek () const {
220  return this->m_array[this->m_tail];
221  }
222 
234  bool check (const T &value) const {
235  const bool valid = &value == NULL;
236  return valid;
237  }
238 
239  protected:
240  T *m_array;
241  const size_t m_arrayLength;
242  const int m_lockNumber;
243 
244  volatile size_t m_size;
245  volatile unsigned int m_head;
246  volatile unsigned int m_tail;
247 };
248 
249 }
250 
251 #ifdef __PROPELLER_COG__
252 #undef virtual
253 #endif
PropWare::Queue
A basic first-in, first-out queue implementation. The queue will overwrite itself when the maximum si...
Definition: queue.h:44
PropWare::Queue::Queue
Queue(T *array, const size_t length, const int lockNumber)
Construct a queue using the given dynamically allocated array (i.e., with new or malloc)
Definition: queue.h:71
PropWare::Queue::is_empty
bool is_empty() const
Determine if any elements exist.
Definition: queue.h:100
PropWare::Queue::is_full
bool is_full() const
Determine if inserting another element would overwrite data.
Definition: queue.h:109
PropWare::Queue::size
size_t size() const
Obtain the number of elements in the queue.
Definition: queue.h:91
PropWare::Queue::peek
T peek() const
Return the oldest value in the buffer without removing it from the buffer.
Definition: queue.h:219
PropWare::Queue::Queue
Queue(T(&array)[N], const int lockNumber=locknew())
Construct a queue using the given statically-allocated array.
Definition: queue.h:52
lockset
#define lockset(lockid)
Set a lock.
Definition: propeller.h:163
PropWare::Queue::dequeue
virtual T dequeue()
Return and remove the oldest value in the buffer.
Definition: queue.h:181
lockret
#define lockret(lockid)
Return lock to pool.
Definition: propeller.h:155
lockclr
#define lockclr(lockid)
Clear lock.
Definition: propeller.h:170
PropWare::Queue::enqueue
virtual Queue & enqueue(const T &value)
Insert an element to the buffer.
Definition: queue.h:129
locknew
#define locknew()
Get a new lock from the pool of Propeller hardware locks.
Definition: propeller.h:147
PropWare::Queue::insert
Queue & insert(const T &value)
Definition: queue.h:170
PropWare
Generic definitions and functions for the Parallax Propeller.
Definition: runnable.h:33
PropWare::Queue::clear
void clear()
Remove all data from the queue.
Definition: queue.h:116
PropWare::Queue::check
bool check(const T &value) const
Determine if a value is valid.
Definition: queue.h:234