RAUL
0.7.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 #include <boost/utility.hpp> 00023 #include "raul/AtomicInt.hpp" 00024 00025 namespace Raul { 00026 00027 00040 template <typename T> 00041 class SRSWQueue : boost::noncopyable 00042 { 00043 public: 00045 SRSWQueue(size_t size); 00046 ~SRSWQueue(); 00047 00048 // Any thread: 00049 00050 inline size_t capacity() const { return _size-1; } 00051 00052 00053 // Write thread(s): 00054 00055 inline bool full() const; 00056 inline bool push(const T& obj); 00057 00058 00059 // Read thread: 00060 00061 inline bool empty() const; 00062 inline T& front() const; 00063 inline void pop(); 00064 00065 private: 00066 AtomicInt _front; 00067 AtomicInt _back; 00068 const size_t _size; 00069 T* const _objects; 00070 }; 00071 00072 00073 template<typename T> 00074 SRSWQueue<T>::SRSWQueue(size_t size) 00075 : _front(0) 00076 , _back(0) 00077 , _size(size + 1) 00078 , _objects(new T[_size]) 00079 { 00080 assert(size > 1); 00081 } 00082 00083 00084 template <typename T> 00085 SRSWQueue<T>::~SRSWQueue() 00086 { 00087 delete[] _objects; 00088 } 00089 00090 00093 template <typename T> 00094 inline bool 00095 SRSWQueue<T>::empty() const 00096 { 00097 return (_back.get() == _front.get()); 00098 } 00099 00100 00103 template <typename T> 00104 inline bool 00105 SRSWQueue<T>::full() const 00106 { 00107 return (((_front.get() - _back.get() + _size) % _size) == 1); 00108 } 00109 00110 00113 template <typename T> 00114 inline T& 00115 SRSWQueue<T>::front() const 00116 { 00117 return _objects[_front.get()]; 00118 } 00119 00120 00126 template <typename T> 00127 inline bool 00128 SRSWQueue<T>::push(const T& elem) 00129 { 00130 if (full()) { 00131 return false; 00132 } else { 00133 unsigned back = _back.get(); 00134 _objects[back] = elem; 00135 _back = (back + 1) % _size; 00136 return true; 00137 } 00138 } 00139 00140 00147 template <typename T> 00148 inline void 00149 SRSWQueue<T>::pop() 00150 { 00151 assert(!empty()); 00152 assert(_size > 0); 00153 00154 _front = (_front.get() + 1) % (_size); 00155 } 00156 00157 00158 } // namespace Raul 00159 00160 #endif // RAUL_SRSW_QUEUE_HPP