MentOS
0.8.0
The Mentoring Operating System
libc
inc
ring_buffer.h
Go to the documentation of this file.
1
6
#pragma once
7
9
#define DECLARE_FIXED_SIZE_RING_BUFFER(type, name, length, init) \
10
typedef struct fs_rb_##name##_t { \
11
unsigned size, read, write; \
12
type buffer[length]; \
13
} fs_rb_##name##_t; \
14
static inline void fs_rb_##name##_init(fs_rb_##name##_t *rb) \
15
{ \
16
rb->size = length; \
17
rb->read = rb->write = 0; \
18
char *dst = (char *)rb->buffer; \
19
long num = sizeof(type) * length; \
20
while (num--) *dst++ = (char)(init & 0xFF); \
21
} \
22
static inline unsigned fs_rb_##name##_step(fs_rb_##name##_t *rb, unsigned index) \
23
{ \
24
return (index == (rb->size - 1)) ? 0 : index + 1; \
25
} \
26
static inline void fs_rb_##name##_push_front(fs_rb_##name##_t *rb, type item) \
27
{ \
28
if (fs_rb_##name##_step(rb, rb->write) == rb->read) \
29
rb->read = fs_rb_##name##_step(rb, rb->read); \
30
rb->buffer[rb->write] = item; \
31
rb->write = fs_rb_##name##_step(rb, rb->write); \
32
} \
33
static inline type fs_rb_##name##_empty(fs_rb_##name##_t *rb) \
34
{ \
35
return rb->write == rb->read; \
36
} \
37
static inline type fs_rb_##name##_pop_back(fs_rb_##name##_t *rb) \
38
{ \
39
type item = init; \
40
if (!fs_rb_##name##_empty(rb)) { \
41
item = rb->buffer[rb->read]; \
42
rb->read = fs_rb_##name##_step(rb, rb->read); \
43
} \
44
return item; \
45
} \
46
static inline type fs_rb_##name##_pop_front(fs_rb_##name##_t *rb) \
47
{ \
48
if (fs_rb_##name##_empty(rb)) \
49
return init; \
50
rb->write = (rb->write > 0) ? rb->write - 1 : rb->size - 1; \
51
return rb->buffer[rb->write]; \
52
} \
53
static inline type fs_rb_##name##_get(fs_rb_##name##_t *rb, unsigned index) \
54
{ \
55
if (index < rb->size) \
56
return rb->buffer[index]; \
57
return init; \
58
} \
59
static inline type fs_rb_##name##_back(fs_rb_##name##_t *rb) \
60
{ \
61
if (fs_rb_##name##_empty(rb)) \
62
return init; \
63
return rb->buffer[rb->read]; \
64
} \
65
static inline type fs_rb_##name##_front(fs_rb_##name##_t *rb) \
66
{ \
67
if (fs_rb_##name##_empty(rb)) \
68
return init; \
69
return rb->buffer[(rb->write > 0) ? rb->write - 1 : rb->size - 1]; \
70
}
71
72
#ifdef __KERNEL__
74
#define RING_BUFFER_ALLOC kmalloc
76
#define RING_BUFFER_FREE kfree
77
#else
79
#define RING_BUFFER_ALLOC malloc
81
#define RING_BUFFER_FREE free
82
#endif
83
85
#define DECLARE_RING_BUFFER(type, name, init) \
86
typedef struct rb_##name##_t { \
87
const unsigned size; \
88
unsigned read, write; \
89
type *buffer; \
90
} rb_##name##_t; \
91
static inline rb_##name##_t alloc_rb_##name(unsigned len) \
92
{ \
93
rb_##name##_t rb = { len, 0U, 0U, len > 0 ? RING_BUFFER_ALLOC(sizeof(type) * len) : NULL }; \
94
memset(rb.buffer, init, sizeof(type) * len); \
95
return rb; \
96
} \
97
static inline void free_rb_##name(rb_##name##_t *rb) \
98
{ \
99
RING_BUFFER_FREE(rb->buffer); \
100
} \
101
static inline unsigned step_rb_##name(rb_##name##_t *rb, unsigned index) \
102
{ \
103
return (index == (rb->size - 1)) ? 0 : index + 1; \
104
} \
105
static inline void push_rb_##name(rb_##name##_t *rb, type item) \
106
{ \
107
if (step_rb_##name(rb, rb->write) == rb->read) \
108
rb->read = step_rb_##name(rb, rb->read); \
109
rb->buffer[rb->write] = item; \
110
rb->write = step_rb_##name(rb, rb->write); \
111
} \
112
static inline void pop_rb_##name(rb_##name##_t *rb, type *item) \
113
{ \
114
*item = init; \
115
if (rb->write != rb->read) { \
116
*item = rb->buffer[rb->read]; \
117
rb->read = step_rb_##name(rb, rb->read); \
118
} \
119
} \
120
static inline void get_rb_##name(rb_##name##_t *rb, unsigned index, type *item) \
121
{ \
122
if (index < rb->size) \
123
*item = rb->buffer[index]; \
124
}
125
126
#undef RING_BUFFER_ALLOC
127
#undef RING_BUFFER_FREE
Generated by
1.9.1