PipeWire 1.2.6
 
Loading...
Searching...
No Matches
ringbuffer.h
Go to the documentation of this file.
1/* Simple Plugin API */
2/* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */
3/* SPDX-License-Identifier: MIT */
4
5#ifndef SPA_RINGBUFFER_H
6#define SPA_RINGBUFFER_H
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
16
21
22struct spa_ringbuffer;
23
24#include <string.h>
25
26#include <spa/utils/defs.h>
27
31struct spa_ringbuffer {
32 uint32_t readindex; /*< the current read index */
33 uint32_t writeindex; /*< the current write index */
34};
35
36#define SPA_RINGBUFFER_INIT() ((struct spa_ringbuffer) { 0, 0 })
41
43static inline void spa_ringbuffer_init(struct spa_ringbuffer *rbuf)
44{
45 *rbuf = SPA_RINGBUFFER_INIT();
46}
47
50 *
51 * \param rbuf a spa_ringbuffer
52 * \param size the target size of \a rbuf
53 */
54static inline void spa_ringbuffer_set_avail(struct spa_ringbuffer *rbuf, uint32_t size)
55{
56 rbuf->readindex = 0;
57 rbuf->writeindex = size;
58}
59
61 * Get the read index and available bytes for reading.
62 *
63 * \param rbuf a spa_ringbuffer
64 * \param index the value of readindex, should be taken modulo the size of the
65 * ringbuffer memory to get the offset in the ringbuffer memory
66 * \return number of available bytes to read. values < 0 mean
67 * there was an underrun. values > rbuf->size means there
68 * was an overrun.
69 */
70static inline int32_t spa_ringbuffer_get_read_index(struct spa_ringbuffer *rbuf, uint32_t *index)
71{
72 *index = __atomic_load_n(&rbuf->readindex, __ATOMIC_RELAXED);
73 return (int32_t) (__atomic_load_n(&rbuf->writeindex, __ATOMIC_ACQUIRE) - *index);
74}
75
77 * Read \a len bytes from \a rbuf starting \a offset. \a offset must be taken
78 * modulo \a size and len should be smaller than \a size.
79 *
80 * \param rbuf a struct \ref spa_ringbuffer
81 * \param buffer memory to read from
82 * \param size the size of \a buffer
83 * \param offset offset in \a buffer to read from
84 * \param data destination memory
85 * \param len number of bytes to read
86 */
87static inline void
89 const void *buffer, uint32_t size,
90 uint32_t offset, void *data, uint32_t len)
91{
92 uint32_t l0 = SPA_MIN(len, size - offset), l1 = len - l0;
93 spa_memcpy(data, SPA_PTROFF(buffer, offset, void), l0);
94 if (SPA_UNLIKELY(l1 > 0))
95 spa_memcpy(SPA_PTROFF(data, l0, void), buffer, l1);
96}
97
104static inline void spa_ringbuffer_read_update(struct spa_ringbuffer *rbuf, int32_t index)
105{
106 __atomic_store_n(&rbuf->readindex, index, __ATOMIC_RELEASE);
107}
108
112 * \param rbuf a spa_ringbuffer
113 * \param index the value of writeindex, should be taken modulo the size of the
114 * ringbuffer memory to get the offset in the ringbuffer memory
115 * \return the fill level of \a rbuf. values < 0 mean
116 * there was an underrun. values > rbuf->size means there
117 * was an overrun. Subtract from the buffer size to get
118 * the number of bytes available for writing.
119 */
120static inline int32_t spa_ringbuffer_get_write_index(struct spa_ringbuffer *rbuf, uint32_t *index)
121{
122 *index = __atomic_load_n(&rbuf->writeindex, __ATOMIC_RELAXED);
123 return (int32_t) (*index - __atomic_load_n(&rbuf->readindex, __ATOMIC_ACQUIRE));
124}
125
127 * Write \a len bytes to \a buffer starting \a offset. \a offset must be taken
128 * modulo \a size and len should be smaller than \a size.
129 *
130 * \param rbuf a spa_ringbuffer
131 * \param buffer memory to write to
132 * \param size the size of \a buffer
133 * \param offset offset in \a buffer to write to
134 * \param data source memory
135 * \param len number of bytes to write
136 */
137static inline void
139 void *buffer, uint32_t size,
140 uint32_t offset, const void *data, uint32_t len)
141{
142 uint32_t l0 = SPA_MIN(len, size - offset), l1 = len - l0;
143 spa_memcpy(SPA_PTROFF(buffer, offset, void), data, l0);
144 if (SPA_UNLIKELY(l1 > 0))
145 spa_memcpy(buffer, SPA_PTROFF(data, l0, void), l1);
146}
147
154static inline void spa_ringbuffer_write_update(struct spa_ringbuffer *rbuf, int32_t index)
155{
156 __atomic_store_n(&rbuf->writeindex, index, __ATOMIC_RELEASE);
157}
158
161 */
162
163
164#ifdef __cplusplus
165} /* extern "C" */
166#endif
167
168#endif /* SPA_RINGBUFFER_H */
spa/utils/defs.h
static void spa_ringbuffer_set_avail(struct spa_ringbuffer *rbuf, uint32_t size)
Sets the pointers so that the ringbuffer contains size bytes.
Definition ringbuffer.h:61
static void spa_ringbuffer_init(struct spa_ringbuffer *rbuf)
Initialize a spa_ringbuffer with size.
Definition ringbuffer.h:50
static void spa_ringbuffer_read_update(struct spa_ringbuffer *rbuf, int32_t index)
Update the read pointer to index.
Definition ringbuffer.h:111
#define SPA_RINGBUFFER_INIT()
Definition ringbuffer.h:43
static void spa_ringbuffer_write_update(struct spa_ringbuffer *rbuf, int32_t index)
Update the write pointer to index.
Definition ringbuffer.h:161
static void spa_ringbuffer_read_data(struct spa_ringbuffer *rbuf, const void *buffer, uint32_t size, uint32_t offset, void *data, uint32_t len)
Read len bytes from rbuf starting offset.
Definition ringbuffer.h:95
static int32_t spa_ringbuffer_get_read_index(struct spa_ringbuffer *rbuf, uint32_t *index)
Get the read index and available bytes for reading.
Definition ringbuffer.h:77
static void spa_ringbuffer_write_data(struct spa_ringbuffer *rbuf, void *buffer, uint32_t size, uint32_t offset, const void *data, uint32_t len)
Write len bytes to buffer starting offset.
Definition ringbuffer.h:145
static int32_t spa_ringbuffer_get_write_index(struct spa_ringbuffer *rbuf, uint32_t *index)
Get the write index and the number of bytes inside the ringbuffer.
Definition ringbuffer.h:127
#define SPA_MIN(a, b)
Definition defs.h:165
#define SPA_UNUSED
Definition defs.h:307
#define SPA_UNLIKELY(x)
Definition defs.h:369
#define spa_memcpy(d, s, n)
Definition defs.h:499
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition defs.h:222
spa/utils/string.h
A ringbuffer type.
Definition ringbuffer.h:37
uint32_t readindex
Definition ringbuffer.h:38
uint32_t writeindex
Definition ringbuffer.h:39