RAUL 0.8.0
|
00001 /* This file is part of Raul. 00002 * Copyright (C) 2007-2009 David Robillard <http://drobilla.net> 00003 * 00004 * Raul is free software; you can redistribute it and/or modify it under the 00005 * terms of the GNU General Public License as published by the Free Software 00006 * Foundation; either version 2 of the License, or (at your option) any later 00007 * version. 00008 * 00009 * Raul is distributed in the hope that it will be useful, but WITHOUT ANY 00010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. 00012 * 00013 * You should have received a copy of the GNU General Public License along 00014 * with this program; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00016 */ 00017 00018 #ifndef RAUL_SRSW_QUEUE_HPP 00019 #define RAUL_SRSW_QUEUE_HPP 00020 00021 #include <cassert> 00022 00023 #include <boost/utility.hpp> 00024 00025 #include "raul/AtomicInt.hpp" 00026 00027 namespace Raul { 00028 00029 00042 template <typename T> 00043 class SRSWQueue : boost::noncopyable 00044 { 00045 public: 00047 explicit SRSWQueue(size_t size); 00048 ~SRSWQueue(); 00049 00050 // Any thread: 00051 00052 inline size_t capacity() const { return _size-1; } 00053 00054 00055 // Write thread(s): 00056 00057 inline bool full() const; 00058 inline bool push(const T& obj); 00059 00060 00061 // Read thread: 00062 00063 inline bool empty() const; 00064 inline T& front() const; 00065 inline void pop(); 00066 00067 private: 00068 AtomicInt _front; 00069 AtomicInt _back; 00070 const size_t _size; 00071 T* const _objects; 00072 }; 00073 00074 00075 template<typename T> 00076 SRSWQueue<T>::SRSWQueue(size_t size) 00077 : _front(0) 00078 , _back(0) 00079 , _size(size + 1) 00080 , _objects(new T[_size]) 00081 { 00082 assert(size > 1); 00083 } 00084 00085 00086 template <typename T> 00087 SRSWQueue<T>::~SRSWQueue() 00088 { 00089 delete[] _objects; 00090 } 00091 00092 00095 template <typename T> 00096 inline bool 00097 SRSWQueue<T>::empty() const 00098 { 00099 return (_back.get() == _front.get()); 00100 } 00101 00102 00105 template <typename T> 00106 inline bool 00107 SRSWQueue<T>::full() const 00108 { 00109 return (((_front.get() - _back.get() + _size) % _size) == 1); 00110 } 00111 00112 00115 template <typename T> 00116 inline T& 00117 SRSWQueue<T>::front() const 00118 { 00119 return _objects[_front.get()]; 00120 } 00121 00122 00128 template <typename T> 00129 inline bool 00130 SRSWQueue<T>::push(const T& elem) 00131 { 00132 if (full()) { 00133 return false; 00134 } else { 00135 unsigned back = _back.get(); 00136 _objects[back] = elem; 00137 _back = (back + 1) % _size; 00138 return true; 00139 } 00140 } 00141 00142 00149 template <typename T> 00150 inline void 00151 SRSWQueue<T>::pop() 00152 { 00153 assert(!empty()); 00154 assert(_size > 0); 00155 00156 _front = (_front.get() + 1) % (_size); 00157 } 00158 00159 00160 } // namespace Raul 00161 00162 #endif // RAUL_SRSW_QUEUE_HPP