RAUL  0.8.0
SRSWQueue.hpp
1 /* This file is part of Raul.
2  * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
3  *
4  * Raul is free software; you can redistribute it and/or modify it under the
5  * terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16  */
17 
18 #ifndef RAUL_SRSW_QUEUE_HPP
19 #define RAUL_SRSW_QUEUE_HPP
20 
21 #include <cassert>
22 
23 #include <boost/utility.hpp>
24 
25 #include "raul/AtomicInt.hpp"
26 
27 namespace Raul {
28 
29 
42 template <typename T>
43 class SRSWQueue : boost::noncopyable
44 {
45 public:
47  explicit SRSWQueue(size_t size);
48  ~SRSWQueue();
49 
50  // Any thread:
51 
52  inline size_t capacity() const { return _size-1; }
53 
54 
55  // Write thread(s):
56 
57  inline bool full() const;
58  inline bool push(const T& obj);
59 
60 
61  // Read thread:
62 
63  inline bool empty() const;
64  inline T& front() const;
65  inline void pop();
66 
67 private:
68  AtomicInt _front;
69  AtomicInt _back;
70  const size_t _size;
71  T* const _objects;
72 };
73 
74 
75 template<typename T>
77  : _front(0)
78  , _back(0)
79  , _size(size + 1)
80  , _objects(new T[_size])
81 {
82  assert(size > 1);
83 }
84 
85 
86 template <typename T>
88 {
89  delete[] _objects;
90 }
91 
92 
95 template <typename T>
96 inline bool
98 {
99  return (_back.get() == _front.get());
100 }
101 
102 
105 template <typename T>
106 inline bool
108 {
109  return (((_front.get() - _back.get() + _size) % _size) == 1);
110 }
111 
112 
115 template <typename T>
116 inline T&
118 {
119  return _objects[_front.get()];
120 }
121 
122 
128 template <typename T>
129 inline bool
130 SRSWQueue<T>::push(const T& elem)
131 {
132  if (full()) {
133  return false;
134  } else {
135  unsigned back = _back.get();
136  _objects[back] = elem;
137  _back = (back + 1) % _size;
138  return true;
139  }
140 }
141 
142 
149 template <typename T>
150 inline void
152 {
153  assert(!empty());
154  assert(_size > 0);
155 
156  _front = (_front.get() + 1) % (_size);
157 }
158 
159 
160 } // namespace Raul
161 
162 #endif // RAUL_SRSW_QUEUE_HPP
Raul::SRSWQueue::push
bool push(const T &obj)
Push an item onto the back of the SRSWQueue - realtime-safe, not thread-safe.
Definition: SRSWQueue.hpp:130
Raul::SRSWQueue::SRSWQueue
SRSWQueue(size_t size)
Definition: SRSWQueue.hpp:76
Raul::SRSWQueue::pop
void pop()
Pop an item off the front of the queue - realtime-safe, not thread-safe.
Definition: SRSWQueue.hpp:151
Raul::SRSWQueue
Realtime-safe single-reader single-writer queue (aka lock-free ringbuffer)
Definition: SRSWQueue.hpp:43
Raul::SRSWQueue::empty
bool empty() const
Return whether or not the queue is empty.
Definition: SRSWQueue.hpp:97
Raul::AtomicInt
Atomic integer.
Definition: AtomicInt.hpp:29
Raul::SRSWQueue::full
bool full() const
Return whether or not the queue is full.
Definition: SRSWQueue.hpp:107
Raul::SRSWQueue::front
T & front() const
Return the element at the front of the queue without removing it.
Definition: SRSWQueue.hpp:117