-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrbuf.c
103 lines (84 loc) · 1.54 KB
/
rbuf.c
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* An implementation of ring buffer.
*
* Author: Yitian Huang, [email protected], 2017
*/
#include "rbuf.h"
#include "kalloc.h"
rbuf_t*
rbuf_init(uint capacity)
{
rbuf_t* rb = (rbuf_t*)kalloc(sizeof(struct rbuf));
assert(rb);
if(0 == capacity){
rb->capacity = INFINITE_CAP + 1;
rb->buf = (void**)kalloc(sizeof(void*) * rb->capacity);
}else{
/* The reason why use capacity+1 here is
* for the convenience of rbuf_isfull() and rbuf_isempty()
*/
rb->capacity = capacity + 1;
rb->buf = (void**)kalloc(sizeof(void*) * rb->capacity);
}
rb->head = 0;
rb->tail = 0;
assert(rb->buf);
return rb;
}
void
rbuf_free(rbuf_t **rb)
{
assert(rb && *rb);
kfree((char*)((*rb)->buf), sizeof(void*) * (*rb)->capacity);
kfree((char*)*rb, sizeof(struct rbuf));
*rb = NULL;
}
uint
rbuf_capacity(rbuf_t *rb)
{
return rb->capacity - 1;
}
uint
rbuf_size(rbuf_t *rb)
{
return (rb->tail + rb->capacity - rb->head) % rb->capacity;
}
int
rbuf_isempty(rbuf_t *rb)
{
return (rb->head == rb->tail);
}
int
rbuf_isfull(rbuf_t *rb)
{
return ((rb->tail + 1) % rb->capacity) == rb->head;
}
void
rbuf_erase(rbuf_t *rb)
{
rb->head = 0;
rb->tail = 0;
}
int
rbuf_write(rbuf_t *rb, void* data)
{
if(data == NULL){
return WRITERBUF_ERROR;
}
if(rbuf_isfull(rb)){
return WRITERBUF_FULL;
}
rb->buf[rb->tail] = data;
rb->tail = (rb->tail + 1) % rb->capacity;
return WRITERBUF_OK;
}
void*
rbuf_read(rbuf_t *rb)
{
if(rbuf_isempty(rb)){
return NULL;
}
void* ret = rb->buf[rb->head];
rb->head = (rb->head + 1)% rb->capacity;
return ret;
}