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 
10 #pragma once
11 
35 #include "assert.h"
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
44 typedef struct {
45  unsigned int read_count;
46  unsigned int write_count;
47  unsigned int mask;
48 } cib_t;
49 
57 #define CIB_INIT(SIZE) { 0, 0, (SIZE)-1 }
58 
68 static inline void cib_init(cib_t *__restrict cib, unsigned int size)
69 {
70  /* check if size is a power of 2 by comparing it to its complement */
71  assert(!(size & (size - 1)));
72 
73  cib_t c = CIB_INIT(size);
74 
75  *cib = c;
76 }
77 
86 static inline unsigned int cib_size(const cib_t *cib)
87 {
88  return cib->mask + 1;
89 }
90 
101 static inline unsigned int cib_avail(const cib_t *cib)
102 {
103  return cib->write_count - cib->read_count;
104 }
105 
116 static inline unsigned int cib_full(const cib_t *cib)
117 {
118  return ((int)cib_avail(cib)) > ((int)cib->mask);
119 }
120 
132 static inline int cib_get(cib_t *__restrict cib)
133 {
134  if (cib_avail(cib)) {
135  return (int)(cib->read_count++ & cib->mask);
136  }
137 
138  return -1;
139 }
140 
161 static inline int cib_peek_at_unsafe(const cib_t *__restrict cib, unsigned offset)
162 {
163  return (cib->read_count + offset) & cib->mask;
164 }
165 
182 static inline int cib_peek_at(const cib_t *__restrict cib, unsigned offset)
183 {
184  if (offset < cib_avail(cib)) {
185  return cib_peek_at_unsafe(cib, offset);
186  }
187 
188  return -1;
189 }
190 
205 static inline int cib_peek_unsafe(const cib_t *__restrict cib)
206 {
207  return cib_peek_at_unsafe(cib, 0);
208 }
209 
221 static inline int cib_peek(const cib_t *__restrict cib)
222 {
223  return cib_peek_at(cib, 0);
224 }
225 
238 static inline int cib_get_unsafe(cib_t *cib)
239 {
240  return (int)(cib->read_count++ & cib->mask);
241 }
242 
254 static inline int cib_put(cib_t *__restrict cib)
255 {
256  unsigned int avail = cib_avail(cib);
257 
258  /* We use a signed compare, because the mask is -1u for an empty CIB. */
259  if ((int)avail <= (int)cib->mask) {
260  return (int)(cib->write_count++ & cib->mask);
261  }
262 
263  return -1;
264 }
265 
278 static inline int cib_put_unsafe(cib_t *cib)
279 {
280  return (int)(cib->write_count++ & cib->mask);
281 }
282 
283 #ifdef __cplusplus
284 }
285 #endif
286 
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:135
static int cib_peek(const cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:221
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:86
static int cib_get_unsafe(cib_t *cib)
Get the index of the next item in buffer.
Definition: cib.h:238
#define CIB_INIT(SIZE)
Initialize cib_t to a given size.
Definition: cib.h:57
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:182
static unsigned int cib_full(const cib_t *cib)
Check if cib is full.
Definition: cib.h:116
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:205
static int cib_get(cib_t *__restrict cib)
Get the index of the next item in buffer.
Definition: cib.h:132
static int cib_put_unsafe(cib_t *cib)
Get index for item in buffer to put to.
Definition: cib.h:278
static int cib_put(cib_t *__restrict cib)
Get index for item in buffer to put to.
Definition: cib.h:254
static void cib_init(cib_t *__restrict cib, unsigned int size)
Initialize cib to 0 and set buffer size to size.
Definition: cib.h:68
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:161
static unsigned int cib_avail(const cib_t *cib)
Calculates difference between cib_put() and cib_get() accesses.
Definition: cib.h:101
circular integer buffer structure
Definition: cib.h:44
unsigned int mask
Size of buffer -1, i.e.
Definition: cib.h:47
unsigned int write_count
number of (successful) write accesses
Definition: cib.h:46
unsigned int read_count
number of (successful) read accesses
Definition: cib.h:45