20 #ifndef ESSENTIA_PHANTOMBUFFER_IMPL_H
21 #define ESSENTIA_PHANTOMBUFFER_IMPL_H
39 w.
end = w.
begin = _writeWindow.begin;
41 _readWindow.push_back(w);
43 ReaderID id = _readWindow.size() - 1;
53 _readView.erase(_readView.begin() +
id);
54 _readWindow.erase(_readWindow.begin() +
id);
60 return _readWindow.size();
77 if (requested > (_phantomSize + 1)) {
79 std::ostringstream msg;
80 msg <<
"acquireForRead: Requested number of tokens (" << requested <<
") > phantom size (" << _phantomSize <<
")";
81 msg <<
" in " << _parent->fullName() <<
" → " << _parent->sinks()[id]->fullName();
86 if (availableForRead(
id) < requested)
return false;
88 _readWindow[id].end = _readWindow[id].begin + requested;
100 template <
typename T>
105 if (requested > (_phantomSize + 1)) {
107 std::ostringstream msg;
108 msg <<
"acquireForWrite: Requested number of tokens (" << requested <<
") > phantom size (" << _phantomSize <<
")";
109 msg <<
" in " << _parent->fullName();
114 if (availableForWrite() < requested)
return false;
116 _writeWindow.end = _writeWindow.begin + requested;
122 template <
typename T>
127 if (released > _writeWindow.end - _writeWindow.begin) {
128 std::ostringstream msg;
129 msg << _parent->fullName() <<
": releasing too many tokens (write access): "
130 << released <<
" instead of " << _writeWindow.end - _writeWindow.begin <<
" max allowed";
135 if (_writeWindow.begin < _phantomSize) {
136 T* first = &_buffer[_writeWindow.begin];
137 T* last = &_buffer[(std::min)(_writeWindow.begin + released, _phantomSize)];
138 T* result = &_buffer[_writeWindow.begin + _bufferSize];
139 fastcopy(result, first, last-first);
142 else if (_writeWindow.end > _bufferSize) {
143 int beginIdx = (std::max)(_writeWindow.begin, (
int)_bufferSize);
144 T* first = &_buffer[beginIdx];
145 T* last = &_buffer[_writeWindow.end];
146 T* result = &_buffer[beginIdx - _bufferSize];
147 fastcopy(result, first, last-first);
150 _writeWindow.begin += released;
151 relocateWriteWindow();
157 template <
typename T>
160 Window& w = _readWindow[id];
164 std::ostringstream msg;
165 msg << _parent->fullName() <<
": releasing too many tokens (read access): "
166 << released <<
" instead of " << w.
end - w.
begin <<
" max allowed";
171 relocateReadWindow(
id);
181 template <
typename T>
184 if (_writeWindow.turn < 1000000)
188 int m = _writeWindow.turn;
190 for (
uint i=0; i<_readWindow.size(); i++) {
191 m = (std::min)(m, _readWindow[i].turn);
194 _writeWindow.turn -= m;
195 for (
uint i=0; i<_readWindow.size(); i++) {
196 _readWindow[i].turn -= m;
200 template <
typename T>
204 v.
setData(&_buffer[0] + _readWindow[
id].begin);
205 v.
setSize(_readWindow[
id].end - _readWindow[
id].begin);
208 template <
typename T>
210 _writeView.setData(&_buffer[0] + _writeWindow.begin);
211 _writeView.setSize(_writeWindow.end - _writeWindow.begin);
224 template <
typename T>
228 int theoretical = _writeWindow.total(_bufferSize) - _readWindow[id].total(_bufferSize);
229 int contiguous = _bufferSize + _phantomSize - _readWindow[id].begin;
237 return (std::min)(theoretical, contiguous);
247 template <
typename T>
251 int minTotal = _bufferSize;
252 if (!_readWindow.empty()) {
253 minTotal = _readWindow.begin()->total(_bufferSize);
260 for (
uint i=0; i<_readWindow.size(); i++) {
261 const Window& w = _readWindow[i];
262 minTotal = (std::min)(minTotal, w.
total(_bufferSize));
265 int theoretical = minTotal - _writeWindow.
total(_bufferSize) + _bufferSize;
270 int ncontiguous = _bufferSize + _phantomSize - _writeWindow.begin;
271 return (std::min)(theoretical, ncontiguous);
275 template <
typename T>
277 if (_writeWindow.begin >= _bufferSize) {
278 _writeWindow.begin -= _bufferSize;
279 _writeWindow.end -= _bufferSize;
286 template <
typename T>
288 Window& w = _readWindow[id];
289 if (w.
begin >= _bufferSize) {
290 w.
begin -= _bufferSize;
291 w.
end -= _bufferSize;
297 template <
typename T>
304 for (
int i=0; i<(int)_readWindow.size(); i++) {
305 _readWindow[i] =
Window();
Definition: threading.h:51
Definition: roguevector.h:30
void setSize(size_t size)
Definition: roguevector.h:82
void setData(T *data)
Definition: roguevector.h:79
void removeReader(ReaderID id)
Definition: phantombuffer_impl.h:52
bool acquireForRead(ReaderID id, int requested)
Definition: phantombuffer_impl.h:69
int availableForRead(ReaderID id) const
Definition: phantombuffer_impl.h:225
bool acquireForWrite(int requested)
Definition: phantombuffer_impl.h:101
void updateReadView(ReaderID id)
Definition: phantombuffer_impl.h:201
void resetTurns()
Definition: phantombuffer_impl.h:182
void relocateReadWindow(ReaderID id)
Definition: phantombuffer_impl.h:287
int numberReaders() const
Definition: phantombuffer_impl.h:59
const std::vector< T > & readView(ReaderID id) const
Definition: phantombuffer_impl.h:29
ReaderID addReader(bool startFromZero=false)
Definition: phantombuffer_impl.h:35
int availableForWrite(bool contiguous=true) const
Definition: phantombuffer_impl.h:248
void relocateWriteWindow()
Definition: phantombuffer_impl.h:276
void updateWriteView()
Definition: phantombuffer_impl.h:209
void reset()
Definition: phantombuffer_impl.h:298
void releaseForWrite(int released)
Definition: phantombuffer_impl.h:123
void releaseForRead(ReaderID id, int released)
Definition: phantombuffer_impl.h:158
Definition: phantombuffer.h:33
int begin
Definition: phantombuffer.h:35
int turn
Definition: phantombuffer.h:37
int end
Definition: phantombuffer.h:36
int total(int bufferSize) const
Definition: phantombuffer.h:41
#define NOWARN_UNUSED(expr)
Definition: essentiautil.h:42
Definition: algorithm.h:28
void fastcopy(T *dest, const T *src, int n)
Definition: essentiautil.h:180
int ReaderID
Definition: types.h:344
unsigned int uint
Definition: types.h:49