Final assignment for the course "Real Time and Embedded Systems" of THMMY in AUTH university.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

143 lines
2.5 KiB

#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
#include "circ_buff.h"
// Defines the circular buffer structure
struct circ_buf_t {
message_handle_t *buffer;
size_t head;
size_t tail;
size_t max; // of the buffer
bool full;
};
// Private Functions
unit_static void advance_pointer(cbuf_handle_t cbuf) {
assert(cbuf);
if(cbuf->full) {
cbuf->tail = (cbuf->tail + 1) % cbuf->max;
}
cbuf->head = (cbuf->head + 1) % cbuf->max;
// We mark full because we will advance tail on the next time around
cbuf->full = (cbuf->head == cbuf->tail);
}
unit_static void retreat_pointer(cbuf_handle_t cbuf) {
assert(cbuf);
cbuf->full = false;
cbuf->tail = (cbuf->tail + 1) % cbuf->max;
}
// APIs
cbuf_handle_t circ_buf_init(message_handle_t *buffer, size_t size) {
assert(buffer && size);
cbuf_handle_t cbuf = malloc(sizeof(circ_buf_t));
assert(cbuf);
cbuf->buffer = buffer;
cbuf->max = size;
circ_buf_reset(cbuf);
assert(circ_buf_empty(cbuf));
return cbuf;
}
void circ_buf_free(cbuf_handle_t cbuf) {
assert(cbuf);
free(cbuf);
}
void circ_buf_reset(cbuf_handle_t cbuf) {
assert(cbuf);
cbuf->head = 0;
cbuf->tail = 0;
cbuf->full = false;
}
size_t circ_buf_size(cbuf_handle_t cbuf) {
assert(cbuf);
size_t size = cbuf->max;
if(!cbuf->full) {
if(cbuf->head >= cbuf->tail) {
size = (cbuf->head - cbuf->tail);
}
else {
size = (cbuf->max + cbuf->head - cbuf->tail);
}
}
return size;
}
size_t circ_buf_capacity(cbuf_handle_t cbuf) {
assert(cbuf);
return cbuf->max;
}
void circ_buf_put(cbuf_handle_t cbuf, const message_handle_t *data) {
assert(cbuf && cbuf->buffer);
if (cbuf->buffer[cbuf->head]) {
message_free(cbuf->buffer[cbuf->head]);
}
cbuf->buffer[cbuf->head] = *data;
advance_pointer(cbuf);
}
int circ_buf_get(cbuf_handle_t cbuf, message_handle_t *data) {
assert(cbuf && data && cbuf->buffer);
int r = -1;
if(!circ_buf_empty(cbuf)) {
data = &(cbuf->buffer[cbuf->tail]);
retreat_pointer(cbuf);
r = 0;
}
return r;
}
int circ_buf_peek(cbuf_handle_t cbuf, size_t position, message_handle_t *data) {
assert(cbuf && data && cbuf->buffer && (position < circ_buf_size(cbuf)));
int r = -1;
if(!circ_buf_empty(cbuf)) {
data = &(cbuf->buffer[(cbuf->tail + position) % cbuf->max]);
r = 0;
}
return r;
}
bool circ_buf_empty(cbuf_handle_t cbuf) {
assert(cbuf);
return (!cbuf->full && (cbuf->head == cbuf->tail));
}
bool circ_buf_full(cbuf_handle_t cbuf) {
assert(cbuf);
return cbuf->full;
}