LMMS
Loading...
Searching...
No Matches
LocklessRingBuffer.h
Go to the documentation of this file.
1/*
2 * LocklessRingBuffer.h - LMMS wrapper for a lockless ringbuffer library
3 *
4 * Copyright (c) 2019 Martin Pavelek <he29/dot/HS/at/gmail/dot/com>
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25#ifndef LMMS_LOCKLESS_RING_BUFFER_H
26#define LMMS_LOCKLESS_RING_BUFFER_H
27
28#include <QMutex>
29#include <QWaitCondition>
30
31#include <ringbuffer/ringbuffer.h>
32
33#include "LmmsTypes.h"
34
35namespace lmms
36{
37
39template <class T>
41{
42 template<class _T>
44public:
45 LocklessRingBuffer(std::size_t sz) : m_buffer(sz)
46 {
47 m_buffer.touch(); // reserve storage space before realtime operation starts
48 }
50
51 std::size_t capacity() const {return m_buffer.maximum_eventual_write_space();}
52 std::size_t free() const {return m_buffer.write_space();}
53 void wakeAll() {m_notifier.wakeAll();}
54 std::size_t write(const T *src, std::size_t cnt, bool notify = false)
55 {
56 std::size_t written = LocklessRingBuffer<T>::m_buffer.write(src, cnt);
57 // Let all waiting readers know new data are available.
58 if (notify) {LocklessRingBuffer<T>::m_notifier.wakeAll();}
59 return written;
60 }
61 void mlock() { m_buffer.mlock(); }
62
63protected:
64 ringbuffer_t<T> m_buffer;
65 QWaitCondition m_notifier;
66};
67
68
70template <class T>
71class LocklessRingBufferReader : public ringbuffer_reader_t<T>
72{
73public:
75 ringbuffer_reader_t<T>(rb.m_buffer),
76 m_notifier(&rb.m_notifier) {};
77
78 bool empty() const {return !this->read_space();}
80 {
81 QMutex useless_lock;
82 useless_lock.lock();
83 m_notifier->wait(&useless_lock);
84 useless_lock.unlock();
85 }
86private:
87 QWaitCondition *m_notifier;
88};
89
90
91} // namespace lmms
92
93#endif // LMMS_LOCKLESS_RING_BUFFER_H
A convenience layer for a realtime-safe and thread-safe multi-reader ringbuffer.
Definition LocklessRingBuffer.h:41
std::size_t free() const
Definition LocklessRingBuffer.h:52
std::size_t capacity() const
Definition LocklessRingBuffer.h:51
void mlock()
Definition LocklessRingBuffer.h:61
QWaitCondition m_notifier
Definition LocklessRingBuffer.h:65
LocklessRingBuffer(std::size_t sz)
Definition LocklessRingBuffer.h:45
std::size_t write(const T *src, std::size_t cnt, bool notify=false)
Definition LocklessRingBuffer.h:54
ringbuffer_t< T > m_buffer
Definition LocklessRingBuffer.h:64
void wakeAll()
Definition LocklessRingBuffer.h:53
friend class LocklessRingBufferReader
Definition LocklessRingBuffer.h:43
LocklessRingBufferReader(LocklessRingBuffer< T > &rb)
Definition LocklessRingBuffer.h:74
bool empty() const
Definition LocklessRingBuffer.h:78
void waitForData()
Definition LocklessRingBuffer.h:79
QWaitCondition * m_notifier
Definition LocklessRingBuffer.h:87
Definition AudioAlsa.cpp:35