tabs/kernel/util/ringbuffer.c

80 lines
1.5 KiB
C
Raw Normal View History

2020-01-29 14:45:48 +01:00
#ifndef RINGBUFFER_C
#define RINGBUFFER_C
2020-02-01 22:47:51 +01:00
#include "ringbuffer.h"
2020-01-31 06:20:56 +01:00
#include "../memory.c"
2020-01-29 14:45:48 +01:00
2020-02-01 22:47:51 +01:00
struct ringbuffer* rbfr_create(const int capacity, void (*destroy_element)(void*)) {
2020-01-29 14:45:48 +01:00
struct ringbuffer* const this = alloc(sizeof (struct ringbuffer));
this->buffer = alloc(capacity * sizeof (void*));
this->buffer_n = capacity;
2020-02-01 22:47:51 +01:00
this->size = 0;
this->head = 0;
this->destroy_element = destroy_element;
2020-01-29 14:45:48 +01:00
return this;
}
void rbfr_destroy(struct ringbuffer* this) {
2020-02-01 22:47:51 +01:00
rbfr_clear(this);
2020-01-29 14:45:48 +01:00
free(this->buffer);
free(this);
}
int rbfr_size(const struct ringbuffer* this) {
return this->size;
}
int rbfr_capacity(const struct ringbuffer* this) {
return this->buffer_n;
}
void rbfr_enqueue(struct ringbuffer* this, void* element) {
if (this->buffer_n == 0) {
return;
}
int index = this->head + this->size;
if (index >= this->buffer_n) {
index -= this->buffer_n;
}
this->buffer[index] = element;
if (this->size < this->buffer_n) {
this->size++;
} else {
this->head++;
}
return;
}
bool rbfr_peek(const struct ringbuffer* this, void** element) {
if (this->size == 0) {
return false;
}
*element = this->buffer[this->head];
return true;
}
bool rbfr_dequeue(struct ringbuffer* this, void** element) {
if (!rbfr_peek(this, element)) {
return false;
}
this->size--;
this->head++;
if (this->head >= this->buffer_n) {
this->head = 0;
}
return true;
}
2020-02-01 22:47:51 +01:00
void rbfr_clear(struct ringbuffer* this) {
void* element;
while (rbfr_dequeue(this, &element)) {
this->destroy_element(element);
}
}
2020-01-29 14:45:48 +01:00
#endif // RINGBUFFER_C