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