/[svn]/linuxsampler/trunk/src/common/RingBuffer.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/common/RingBuffer.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 56 by schoenebeck, Tue Apr 27 09:21:58 2004 UTC revision 294 by schoenebeck, Mon Oct 25 15:21:43 2004 UTC
# Line 249  public: Line 249  public:
249      int size;      int size;
250      int wrap_elements;      int wrap_elements;
251    
252        /**
253         * Independent, random access reading from a RingBuffer. This class
254         * allows to read from a RingBuffer without being forced to free read
255         * data while reading / positioning.
256         */
257        template<class _T>
258        class _NonVolatileReader {
259            public:
260                int read_space() {
261                    int r = read_ptr;
262                    int w = atomic_read(&pBuf->write_ptr);
263                    return (w >= r) ? w - r : (w - r + pBuf->size) & pBuf->size_mask;
264                }
265    
266                /**
267                 * Prefix decrement operator, for reducing NonVolatileReader's
268                 * read position by one.
269                 */
270                inline void operator--() {
271                    if (read_ptr == atomic_read(&pBuf->read_ptr)) return; //TODO: or should we react oh this case (e.g. force segfault), as this is a very odd case?
272                    --read_ptr & pBuf->size_mask;
273                }
274    
275                /**
276                 * Postfix decrement operator, for reducing NonVolatileReader's
277                 * read position by one.
278                 */
279                inline void operator--(int) {
280                    --*this;
281                }
282    
283                /**
284                 * Returns pointer to the RingBuffer data of current
285                 * NonVolatileReader's read position and increments
286                 * NonVolatileReader's read position by one.
287                 *
288                 * @returns pointer to element of current read position
289                 */
290                T* pop() {
291                    if (!read_space()) return NULL;
292                    T* pData = &pBuf->buf[read_ptr];
293                    read_ptr++;
294                    read_ptr &= pBuf->size_mask;
295                    return pData;
296                }
297    
298                /**
299                 * Reads one element from the NonVolatileReader's current read
300                 * position and copies it to the variable pointed by \a dst and
301                 * finally increments the NonVolatileReader's read position by
302                 * one.
303                 *
304                 * @param dst - where the element is copied to
305                 * @returns 1 on success, 0 otherwise
306                 */
307                int pop(T* dst) { return read(dst,1); }
308    
309                /**
310                 * Reads \a cnt elements from the NonVolatileReader's current
311                 * read position and copies it to the buffer pointed by \a dest
312                 * and finally increments the NonVolatileReader's read position
313                 * by the number of read elements.
314                 *
315                 * @param dest - destination buffer
316                 * @param cnt  - number of elements to read
317                 * @returns number of read elements
318                 */
319                int read(T* dest, int cnt) {
320                    int free_cnt;
321                    int cnt2;
322                    int to_read;
323                    int n1, n2;
324                    int priv_read_ptr;
325    
326                    priv_read_ptr = read_ptr;
327    
328                    if ((free_cnt = read_space()) == 0) return 0;
329    
330                    to_read = cnt > free_cnt ? free_cnt : cnt;
331    
332                    cnt2 = priv_read_ptr + to_read;
333    
334                    if (cnt2 > pBuf->size) {
335                        n1 = pBuf->size - priv_read_ptr;
336                        n2 = cnt2 & pBuf->size_mask;
337                    } else {
338                        n1 = to_read;
339                        n2 = 0;
340                    }
341    
342                    memcpy(dest, &pBuf->buf[priv_read_ptr], n1 * sizeof(T));
343                    priv_read_ptr = (priv_read_ptr + n1) & pBuf->size_mask;
344    
345                    if (n2) {
346                        memcpy(dest+n1, pBuf->buf, n2 * sizeof(T));
347                        priv_read_ptr = n2;
348                    }
349    
350                    this->read_ptr = priv_read_ptr;
351                    return to_read;
352                }
353    
354                /**
355                 * Finally when the read data is not needed anymore, this method
356                 * should be called to free the data in the RingBuffer up to the
357                 * current read position of this NonVolatileReader.
358                 *
359                 * @see RingBuffer::increment_read_ptr()
360                 */
361                void free() {
362                    atomic_set(&pBuf->read_ptr, read_ptr);
363                }
364    
365            protected:
366                _NonVolatileReader(RingBuffer<_T>* pBuf) {
367                    this->pBuf     = pBuf;
368                    this->read_ptr = atomic_read(&pBuf->read_ptr);
369                }
370    
371                RingBuffer<_T>* pBuf;
372                int read_ptr;
373    
374                friend class RingBuffer<_T>;
375        };
376    
377        typedef _NonVolatileReader<T> NonVolatileReader;
378    
379        NonVolatileReader get_non_volatile_reader() { return NonVolatileReader(this); }
380    
381    protected:    protected:
382      T *buf;      T *buf;
383      atomic_t write_ptr;      atomic_t write_ptr;
384      atomic_t read_ptr;      atomic_t read_ptr;
385      int size_mask;      int size_mask;
386    
387        friend class _NonVolatileReader<T>;
388  };  };
389    
390  template<class T> T *  template<class T> T *

Legend:
Removed from v.56  
changed lines
  Added in v.294

  ViewVC Help
Powered by ViewVC