MentOS  0.8.0
The Mentoring Operating System
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