blob: 1747b7e720f3b59f4a17cb559abd616d30e523f7 [file]
/*
* Copyright © 2025 Valve Corporation
*
* SPDX-License-Identifier: MIT
*/
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
#include "util/macros.h"
#define RINGBUFFER_DECLARE(name, type, N) \
struct { \
type data[N]; \
uint32_t head; \
uint32_t tail; \
uint32_t size; \
simple_mtx_t mtx; \
} name
#define ringbuffer_init(buffer) \
(buffer.head = buffer.tail = buffer.size = 0, simple_mtx_init(&buffer.mtx, mtx_plain))
#define ringbuffer_lock(buffer) simple_mtx_lock(&buffer.mtx)
#define ringbuffer_unlock(buffer) simple_mtx_unlock(&buffer.mtx)
static inline uint32_t
__ringbuffer_add_wrap(uint32_t *val, uint32_t *size, uint32_t N)
{
uint32_t prev = *val;
*val = (*val + 1) % N;
*size = *size + 1;
assert(*size <= N);
return prev;
}
#define ringbuffer_alloc(buffer) \
(buffer.size == ARRAY_SIZE(buffer.data) \
? NULL \
: &buffer.data[__ringbuffer_add_wrap(&buffer.head, &buffer.size, ARRAY_SIZE(buffer.data))])
#define ringbuffer_free(buffer, elem) \
assert(elem == NULL || elem == &buffer.data[buffer.tail]); \
buffer.size--; \
assert(buffer.size < ARRAY_SIZE(buffer.data)); \
buffer.tail = (buffer.tail + 1) % ARRAY_SIZE(buffer.data)
#define ringbuffer_first(buffer) (&buffer.data[buffer.tail])
#define ringbuffer_last(buffer) \
(&buffer.data[(buffer.head + ARRAY_SIZE(buffer.data) - 1) % ARRAY_SIZE(buffer.data)])
#define ringbuffer_index(buffer, elem) (elem - buffer.data)
#define ringbuffer_next(buffer, elem) \
(&buffer.data[(ringbuffer_index(buffer, elem) + 1) % ARRAY_SIZE(buffer.data)])
#endif /* RINGBUFFER_H */