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 
75 static inline unsigned int cib_avail(const cib_t *cib)
76 {
77  return cib->write_count - cib->read_count;
78 }
79 
87 static inline unsigned int cib_full(const cib_t *cib)
88 {
89  return ((int)cib_avail(cib)) > ((int)cib->mask);
90 }
91 
99 static inline int cib_get(cib_t *__restrict cib)
100 {
101  if (cib_avail(cib)) {
102  return (int)(cib->read_count++ & cib->mask);
103  }
104 
105  return -1;
106 }
107 
115 static inline int cib_peek(cib_t *__restrict cib)
116 {
117  if (cib_avail(cib)) {
118  return (int)(cib->read_count & cib->mask);
119  }
120 
121  return -1;
122 }
123 
133 static inline int cib_get_unsafe(cib_t *cib)
134 {
135  return (int)(cib->read_count++ & cib->mask);
136 }
137 
145 static inline int cib_put(cib_t *__restrict cib)
146 {
147  unsigned int avail = cib_avail(cib);
148 
149  /* We use a signed compare, because the mask is -1u for an empty CIB. */
150  if ((int)avail <= (int)cib->mask) {
151  return (int)(cib->write_count++ & cib->mask);
152  }
153 
154  return -1;
155 }
156 
166 static inline int cib_put_unsafe(cib_t *cib)
167 {
168  return (int)(cib->write_count++ & cib->mask);
169 }
170 
171 #ifdef __cplusplus
172 }
173 #endif
174 
175 #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:104
static int cib_peek(cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:115
static int cib_get_unsafe(cib_t *cib)
Get the index of the next item in buffer.
Definition: cib.h:133
#define CIB_INIT(SIZE)
Initialize cib_t to a given size.
Definition: cib.h:47
static unsigned int cib_full(const cib_t *cib)
Check if cib is full.
Definition: cib.h:87
static int cib_get(cib_t *__restrict cib)
Get the index of the next item in buffer.
Definition: cib.h:99
static int cib_put_unsafe(cib_t *cib)
Get index for item in buffer to put to.
Definition: cib.h:166
static int cib_put(cib_t *__restrict cib)
Get index for item in buffer to put to.
Definition: cib.h:145
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 unsigned int cib_avail(const cib_t *cib)
Calculates difference between cib_put() and cib_get() accesses.
Definition: cib.h:75
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