cib.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
3  * 2013 Freie Universität Berlin
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
22 #ifndef CIB_H
23 #define CIB_H
24 
25 #include "assert.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
34 typedef struct {
35  unsigned int read_count;
36  unsigned int write_count;
37  unsigned int mask;
38 } cib_t;
39 
47 #define CIB_INIT(SIZE) { 0, 0, (SIZE)-1 }
48 
58 static inline void cib_init(cib_t *__restrict cib, unsigned int size)
59 {
60  /* check if size is a power of 2 by comparing it to its complement */
61  assert(!(size & (size - 1)));
62 
63  cib_t c = CIB_INIT(size);
64 
65  *cib = c;
66 }
67 
76 static inline unsigned int cib_size(const cib_t *cib)
77 {
78  return cib->mask + 1;
79 }
80 
88 static inline unsigned int cib_avail(const cib_t *cib)
89 {
90  return cib->write_count - cib->read_count;
91 }
92 
100 static inline unsigned int cib_full(const cib_t *cib)
101 {
102  return ((int)cib_avail(cib)) > ((int)cib->mask);
103 }
104 
113 static inline int cib_get(cib_t *__restrict cib)
114 {
115  if (cib_avail(cib)) {
116  return (int)(cib->read_count++ & cib->mask);
117  }
118 
119  return -1;
120 }
121 
138 static inline int cib_peek_at_unsafe(const cib_t *__restrict cib, unsigned offset)
139 {
140  return (cib->read_count + offset) & cib->mask;
141 }
142 
156 static inline int cib_peek_at(const cib_t *__restrict cib, unsigned offset)
157 {
158  if (offset < cib_avail(cib)) {
159  return cib_peek_at_unsafe(cib, offset);
160  }
161 
162  return -1;
163 }
164 
175 static inline int cib_peek_unsafe(const cib_t *__restrict cib)
176 {
177  return cib_peek_at_unsafe(cib, 0);
178 }
179 
188 static inline int cib_peek(const cib_t *__restrict cib)
189 {
190  return cib_peek_at(cib, 0);
191 }
192 
202 static inline int cib_get_unsafe(cib_t *cib)
203 {
204  return (int)(cib->read_count++ & cib->mask);
205 }
206 
215 static inline int cib_put(cib_t *__restrict cib)
216 {
217  unsigned int avail = cib_avail(cib);
218 
219  /* We use a signed compare, because the mask is -1u for an empty CIB. */
220  if ((int)avail <= (int)cib->mask) {
221  return (int)(cib->write_count++ & cib->mask);
222  }
223 
224  return -1;
225 }
226 
236 static inline int cib_put_unsafe(cib_t *cib)
237 {
238  return (int)(cib->write_count++ & cib->mask);
239 }
240 
241 #ifdef __cplusplus
242 }
243 #endif
244 
245 #endif /* CIB_H */
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:136
static int cib_peek(const cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:188
static unsigned int cib_size(const cib_t *cib)
Returns the total capacity (size parameter of cib_init()) of a cib_t.
Definition: cib.h:76
static int cib_get_unsafe(cib_t *cib)
Get the index of the next item in buffer.
Definition: cib.h:202
#define CIB_INIT(SIZE)
Initialize cib_t to a given size.
Definition: cib.h:47
static int cib_peek_at(const cib_t *__restrict cib, unsigned offset)
Get the index of an item in the buffer without removing anything.
Definition: cib.h:156
static unsigned int cib_full(const cib_t *cib)
Check if cib is full.
Definition: cib.h:100
static int cib_peek_unsafe(const cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:175
static int cib_get(cib_t *__restrict cib)
Get the index of the next item in buffer.
Definition: cib.h:113
static int cib_put_unsafe(cib_t *cib)
Get index for item in buffer to put to.
Definition: cib.h:236
static int cib_put(cib_t *__restrict cib)
Get index for item in buffer to put to.
Definition: cib.h:215
static void cib_init(cib_t *__restrict cib, unsigned int size)
Initialize cib to 0 and set buffer size to size.
Definition: cib.h:58
static int cib_peek_at_unsafe(const cib_t *__restrict cib, unsigned offset)
Get the index of an item in the buffer without removing anything.
Definition: cib.h:138
static unsigned int cib_avail(const cib_t *cib)
Calculates difference between cib_put() and cib_get() accesses.
Definition: cib.h:88
circular integer buffer structure
Definition: cib.h:34
unsigned int mask
Size of buffer -1, i.e.
Definition: cib.h:37
unsigned int write_count
number of (successful) write accesses
Definition: cib.h:36
unsigned int read_count
number of (successful) read accesses
Definition: cib.h:35