cib.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016 Kaspar Schleiser <kaspar@schleiser.de>
3  * SPDX-FileCopyrightText: 2013 Freie Universität Berlin
4  * SPDX-License-Identifier: LGPL-2.1-only
5  */
6 
7 #pragma once
8 
32 #include "assert.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
41 typedef struct {
42  unsigned int read_count;
43  unsigned int write_count;
44  unsigned int mask;
45 } cib_t;
46 
54 #define CIB_INIT(SIZE) { 0, 0, (SIZE)-1 }
55 
65 static inline void cib_init(cib_t *__restrict cib, unsigned int size)
66 {
67  /* check if size is a power of 2 by comparing it to its complement */
68  assert(!(size & (size - 1)));
69 
70  cib_t c = CIB_INIT(size);
71 
72  *cib = c;
73 }
74 
83 static inline unsigned int cib_size(const cib_t *cib)
84 {
85  return cib->mask + 1;
86 }
87 
98 static inline unsigned int cib_avail(const cib_t *cib)
99 {
100  return cib->write_count - cib->read_count;
101 }
102 
113 static inline unsigned int cib_full(const cib_t *cib)
114 {
115  return ((int)cib_avail(cib)) > ((int)cib->mask);
116 }
117 
129 static inline int cib_get(cib_t *__restrict cib)
130 {
131  if (cib_avail(cib)) {
132  return (int)(cib->read_count++ & cib->mask);
133  }
134 
135  return -1;
136 }
137 
158 static inline int cib_peek_at_unsafe(const cib_t *__restrict cib, unsigned offset)
159 {
160  return (cib->read_count + offset) & cib->mask;
161 }
162 
179 static inline int cib_peek_at(const cib_t *__restrict cib, unsigned offset)
180 {
181  if (offset < cib_avail(cib)) {
182  return cib_peek_at_unsafe(cib, offset);
183  }
184 
185  return -1;
186 }
187 
202 static inline int cib_peek_unsafe(const cib_t *__restrict cib)
203 {
204  return cib_peek_at_unsafe(cib, 0);
205 }
206 
218 static inline int cib_peek(const cib_t *__restrict cib)
219 {
220  return cib_peek_at(cib, 0);
221 }
222 
235 static inline int cib_get_unsafe(cib_t *cib)
236 {
237  return (int)(cib->read_count++ & cib->mask);
238 }
239 
251 static inline int cib_put(cib_t *__restrict cib)
252 {
253  unsigned int avail = cib_avail(cib);
254 
255  /* We use a signed compare, because the mask is -1u for an empty CIB. */
256  if ((int)avail <= (int)cib->mask) {
257  return (int)(cib->write_count++ & cib->mask);
258  }
259 
260  return -1;
261 }
262 
275 static inline int cib_put_unsafe(cib_t *cib)
276 {
277  return (int)(cib->write_count++ & cib->mask);
278 }
279 
280 #ifdef __cplusplus
281 }
282 #endif
283 
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:143
static int cib_peek(const cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:218
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:83
static int cib_get_unsafe(cib_t *cib)
Get the index of the next item in buffer.
Definition: cib.h:235
#define CIB_INIT(SIZE)
Initialize cib_t to a given size.
Definition: cib.h:54
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:179
static unsigned int cib_full(const cib_t *cib)
Check if cib is full.
Definition: cib.h:113
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:202
static int cib_get(cib_t *__restrict cib)
Get the index of the next item in buffer.
Definition: cib.h:129
static int cib_put_unsafe(cib_t *cib)
Get index for item in buffer to put to.
Definition: cib.h:275
static int cib_put(cib_t *__restrict cib)
Get index for item in buffer to put to.
Definition: cib.h:251
static void cib_init(cib_t *__restrict cib, unsigned int size)
Initialize cib to 0 and set buffer size to size.
Definition: cib.h:65
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:158
static unsigned int cib_avail(const cib_t *cib)
Calculates difference between cib_put() and cib_get() accesses.
Definition: cib.h:98
circular integer buffer structure
Definition: cib.h:41
unsigned int mask
Size of buffer -1, i.e.
Definition: cib.h:44
unsigned int write_count
number of (successful) write accesses
Definition: cib.h:43
unsigned int read_count
number of (successful) read accesses
Definition: cib.h:42