RAUL  0.5.1
SRSWQueue.hpp
1 /* This file is part of Raul.
2  * Copyright (C) 2007 Dave 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 #include <cstdlib>
23 #include <boost/utility.hpp>
24 #include <raul/AtomicInt.hpp>
25 
26 namespace Raul {
27 
28 
38 template <typename T>
39 class SRSWQueue : boost::noncopyable
40 {
41 public:
42  SRSWQueue(size_t size);
43  ~SRSWQueue();
44 
45  // Any thread:
46 
47  inline size_t capacity() const { return _size-1; }
48 
49 
50  // Write thread(s):
51 
52  inline bool full() const;
53  inline bool push(const T& obj);
54 
55 
56  // Read thread:
57 
58  inline bool empty() const;
59  inline T& front() const;
60  inline void pop();
61 
62 private:
63  AtomicInt _front;
64  AtomicInt _back;
65  const size_t _size;
66  T* const _objects;
67 };
68 
69 
70 template<typename T>
71 SRSWQueue<T>::SRSWQueue(size_t size)
72  : _front(0)
73  , _back(0)
74  , _size(size+1)
75  , _objects((T*)calloc(_size, sizeof(T)))
76 {
77  assert(size > 1);
78 }
79 
80 
81 template <typename T>
82 SRSWQueue<T>::~SRSWQueue()
83 {
84  free(_objects);
85 }
86 
87 
90 template <typename T>
91 inline bool
93 {
94  return (_back.get() == _front.get());
95 }
96 
97 
100 template <typename T>
101 inline bool
103 {
104  return (((_front.get() - _back.get() + _size) % _size) == 1);
105 }
106 
107 
110 template <typename T>
111 inline T&
113 {
114  return _objects[_front.get()];
115 }
116 
117 
123 template <typename T>
124 inline bool
125 SRSWQueue<T>::push(const T& elem)
126 {
127  if (full()) {
128  return false;
129  } else {
130  unsigned back = _back.get();
131  _objects[back] = elem;
132  _back = (back + 1) % _size;
133  return true;
134  }
135 }
136 
137 
144 template <typename T>
145 inline void
147 {
148  assert(!empty());
149  assert(_size > 0);
150 
151  _front = (_front.get() + 1) % (_size);
152 }
153 
154 
155 } // namespace Raul
156 
157 #endif // RAUL_SRSW_QUEUE_HPP
bool push(const T &obj)
Push an item onto the back of the SRSWQueue - realtime-safe, not thread-safe.
Definition: SRSWQueue.hpp:125
bool full() const
Return whether or not the queue is full.
Definition: SRSWQueue.hpp:102
void pop()
Pop an item off the front of the queue - realtime-safe, not thread-safe.
Definition: SRSWQueue.hpp:146
Definition: Array.hpp:26
bool empty() const
Return whether or not the queue is empty.
Definition: SRSWQueue.hpp:92
T & front() const
Return the element at the front of the queue without removing it.
Definition: SRSWQueue.hpp:112
Realtime-safe single-reader single-writer queue (aka lock-free ringbuffer)
Definition: SRSWQueue.hpp:39