vdr-plugin-softhddevice-drm-gles 1.5.9-20e15de
ringbuffer.cpp
Go to the documentation of this file.
1
24#include <cstdio>
25#include <cstdint>
26#include <cstdlib>
27#include <cstring>
28
29#include "logger.h"
30#include "ringbuffer.h"
31
32/******************************************************************************
33 * cSoftHdRingbuffer class
34 *
35 * Lock free ring buffer with only one writer and one reader
36 *****************************************************************************/
37
46 : m_size(size)
47{
48 if (!(m_pBuffer = (char *)malloc(size))) // allocate buffer
49 LOGFATAL("ringbuffer: %s: can't allocate memory for ringbuffer", __FUNCTION__);
50
51 m_pBufferEnd = m_pBuffer + size;
55}
56
64
74
83{
84 size_t n;
85
87 if (cnt > n) { // not enough space
88 cnt = n;
89 }
90 //
91 // Hitting end of buffer?
92 //
94 if (n > cnt) { // don't cross the end
95 m_pWritePointer += cnt;
96 } else { // reached or cross the end
98 if (n < cnt) {
99 n = cnt - n;
100 m_pWritePointer += n;
101 }
102 }
103
104 //
105 // Only atomic modification!
106 //
107 atomic_add(cnt, &m_filled);
108 return cnt;
109}
110
119size_t cSoftHdRingbuffer::Write(const void *buf, size_t cnt)
120{
121 size_t n;
122
124 if (cnt > n) { // not enough space
125 cnt = n;
126 }
127 //
128 // Hitting end of buffer?
129 //
131 if (n > cnt) { // don't cross the end
132 memcpy(m_pWritePointer, buf, cnt);
133 m_pWritePointer += cnt;
134 } else { // reached or cross the end
135 memcpy(m_pWritePointer, buf, n);
137 if (n < cnt) {
138 buf = (uint8_t *)buf + n;
139 n = cnt - n;
140 memcpy(m_pWritePointer, buf, n);
141 m_pWritePointer += n;
142 }
143 }
144
145 //
146 // Only atomic modification!
147 //
148 atomic_add(cnt, &m_filled);
149 return cnt;
150}
151
161{
162 size_t n;
163 size_t cnt;
164
165 // Total free bytes available in ring buffer
166 cnt = m_size - atomic_read(&m_filled);
167
168 *wp = m_pWritePointer;
169
170 //
171 // Hitting end of buffer?
172 //
174 if (n <= cnt) { // reached or cross the end
175 return n;
176 }
177 return cnt;
178}
179
188{
189 size_t n;
190
191 n = atomic_read(&m_filled);
192 if (cnt > n) { // not enough filled
193 cnt = n;
194 }
195 //
196 // Hitting end of buffer?
197 //
199 if (n > cnt) { // don't cross the end
200 m_pReadPointer += cnt;
201 } else { // reached or cross the end
203 if (n < cnt) {
204 n = cnt - n;
205 m_pReadPointer += n;
206 }
207 }
208
209 //
210 // Only atomic modification!
211 //
212 atomic_sub(cnt, &m_filled);
213 return cnt;
214}
215
224size_t cSoftHdRingbuffer::Read(void *buf, size_t cnt)
225{
226 size_t n;
227
228 n = atomic_read(&m_filled);
229 if (cnt > n) { // not enough filled
230 cnt = n;
231 }
232 //
233 // Hitting end of buffer?
234 //
236 if (n > cnt) { // don't cross the end
237 memcpy(buf, m_pReadPointer, cnt);
238 m_pReadPointer += cnt;
239 } else { // reached or cross the end
240 memcpy(buf, m_pReadPointer, n);
242 if (n < cnt) {
243 buf = (uint8_t *)buf + n;
244 n = cnt - n;
245 memcpy(buf, m_pReadPointer, n);
246 m_pReadPointer += n;
247 }
248 }
249
250 //
251 // Only atomic modification!
252 //
253 atomic_sub(cnt, &m_filled);
254 return cnt;
255}
256
266{
267 size_t n;
268 size_t cnt;
269
270 // Total used bytes in ring buffer
271 cnt = atomic_read(&m_filled);
272
273 *rp = m_pReadPointer;
274
275 //
276 // Hitting end of buffer?
277 //
279 if (n <= cnt) { // reached or cross the end
280 return n;
281 }
282 return cnt;
283}
284
291{
292 return m_size - atomic_read(&m_filled);
293}
294
301{
302 return atomic_read(&m_filled);
303}
size_t GetWritePointer(void **)
Get write pointer and free bytes at this position of ring buffer.
size_t m_size
bytes in buffer (for faster calc)
Definition ringbuffer.h:60
~cSoftHdRingbuffer(void)
cSoftHdRingbuffer destructor
char * m_pWritePointer
only used by writer
Definition ringbuffer.h:62
size_t Read(void *, size_t)
Read from a ring buffer.
size_t UsedBytes(void)
Get used bytes in ring buffer.
size_t WriteAdvance(size_t)
Advance write pointer in ring buffer.
size_t FreeBytes(void)
Get free bytes in ring buffer.
cSoftHdRingbuffer(size_t)
cSoftHdRingbuffer constructor
atomic_t m_filled
how many of the buffer is used
Definition ringbuffer.h:65
size_t ReadAdvance(size_t)
Advance read pointer in ring buffer.
const char * m_pReadPointer
only used by reader
Definition ringbuffer.h:61
size_t GetReadPointer(const void **)
Get read pointer and used bytes at this position of ring buffer.
const char * m_pBufferEnd
end of buffer
Definition ringbuffer.h:59
size_t Write(const void *, size_t)
Write to a ring buffer.
char * m_pBuffer
ring buffer data
Definition ringbuffer.h:58
void Reset(void)
Reset ring buffer pointers.
Logger class header file.
#define LOGFATAL
Logger macros.
Definition logger.h:40
Ringbuffer class header file.
#define atomic_add(val, ptr)
Definition ringbuffer.h:35
#define atomic_set(ptr, val)
Definition ringbuffer.h:31
#define atomic_read(ptr)
Definition ringbuffer.h:32
#define atomic_sub(val, ptr)
Definition ringbuffer.h:36