#include "src/system/str.c"
#include "src/dynarray.c"
#include "src/system/file.c"
+#include "src/ring_buffer.c"
--- /dev/null
+#include "ring_buffer.h"
+#include "system/stacktrace.h"
+
+void ring_buffer_push(RingBuffer *buffer,
+ void *element)
+{
+ trace_assert(buffer);
+ trace_assert(element);
+
+ size_t i = (buffer->begin + buffer->count) % buffer->capacity;
+
+ if (buffer->count < buffer->capacity) {
+ memcpy(
+ buffer->data + i * buffer->element_size,
+ element,
+ buffer->element_size);
+ buffer->count += 1;
+ } else {
+ if (buffer->dtor) buffer->dtor(buffer->data + i * buffer->element_size);
+ memcpy(
+ buffer->data + i * buffer->element_size,
+ element,
+ buffer->element_size);
+ buffer->begin = (buffer->begin + 1) % buffer->capacity;
+ }
+}
+
+int ring_buffer_pop(RingBuffer *buffer)
+{
+ trace_assert(buffer);
+
+ if (buffer->count == 0) return 0;
+
+ if (buffer->dtor) {
+ size_t i = (buffer->begin + buffer->count - 1) % buffer->capacity;
+ buffer->dtor(buffer->data + i * buffer->element_size);
+ }
+
+ buffer->count--;
+
+ return 1;
+}
+
+void *ring_buffer_top(RingBuffer *buffer)
+{
+ trace_assert(buffer);
+ if (buffer->count == 0) return NULL;
+ size_t i = (buffer->begin + buffer->count - 1) % buffer->capacity;
+ return buffer->data + i * buffer->element_size;
+}
--- /dev/null
+#ifndef RING_BUFFER_H_
+#define RING_BUFFER_H_
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+typedef void (*RingBufferDtor)(void *element);
+
+typedef struct {
+ size_t element_size;
+ size_t capacity;
+ size_t count;
+ size_t begin;
+ uint8_t *data;
+ RingBufferDtor dtor;
+} RingBuffer;
+
+static inline
+RingBuffer create_ring_buffer(size_t element_size,
+ size_t capacity,
+ RingBufferDtor dtor)
+{
+ RingBuffer result = {0};
+ result.element_size = element_size;
+ result.capacity = capacity;
+ result.dtor = dtor;
+ result.data = malloc(result.element_size * result.capacity);
+ return result;
+}
+
+static inline
+void destroy_ring_buffer(RingBuffer buffer)
+{
+ free(buffer.data);
+}
+
+void ring_buffer_push(RingBuffer *buffer, void *element);
+int ring_buffer_pop(RingBuffer *buffer);
+void *ring_buffer_top(RingBuffer *buffer);
+
+#endif // RING_BUFFER_H_