aboutsummaryrefslogtreecommitdiff
path: root/kernel/collection/include/collection/rbuffer.h
blob: dbdd6ee33bb934c0cba6dea9501d22b82b74e714 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#ifndef RBUFFER_H
#define RBUFFER_H

#include <stddef.h>

#define EEMPTY -1
#define EFULL -2

typedef char rbuffer_byte_t;

struct rbuffer_t {
  rbuffer_byte_t* address;
  size_t size;
  size_t head;
  size_t tail;
};

#define RBUFFER_INIT(array, length) \
  { \
    .address = array, \
    .size = length, \
    .head=0, \
    .tail=0 \
  }

void rbuffer_init(struct rbuffer_t* rb, rbuffer_byte_t* address, size_t size);

/** Read data from ringbuffer. */
static inline int rbuffer_read(struct rbuffer_t* const rb, rbuffer_byte_t* const data_out) {
  if (rb->head == rb->tail) return EEMPTY;
  *data_out = rb->address[rb->head];
  rb->head = rb->head + 1;
  if (rb->head >= rb->size) rb->head=0;
  return 0;
}

static inline int rbuffer_write(struct rbuffer_t* const rb, rbuffer_byte_t data_in) {
  size_t next_tail = rb->tail + 1;
  if (next_tail >= rb->size) next_tail = 0;  
  if (rb->head == next_tail) return EFULL;
  
  rb->address[rb->tail] = data_in;
  rb->tail = next_tail;
  return 0;
}

#endif