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  *cib = c;
65 }
66 
74 static inline unsigned int cib_avail(const cib_t *cib)
75 {
76  return cib->write_count - cib->read_count;
77 }
78 
86 static inline unsigned int cib_full(const cib_t *cib)
87 {
88  return ((int)cib_avail(cib)) > ((int)cib->mask);
89 }
90 
98 static inline int cib_get(cib_t *__restrict cib)
99 {
100  if (cib_avail(cib)) {
101  return (int)(cib->read_count++ & cib->mask);
102  }
103 
104  return -1;
105 }
106 
114 static inline int cib_peek(cib_t *__restrict cib)
115 {
116  if (cib_avail(cib)) {
117  return (int)(cib->read_count & cib->mask);
118  }
119 
120  return -1;
121 }
122 
132 static inline int cib_get_unsafe(cib_t *cib)
133 {
134  return (int)(cib->read_count++ & cib->mask);
135 }
136 
144 static inline int cib_put(cib_t *__restrict cib)
145 {
146  unsigned int avail = cib_avail(cib);
147 
148  /* We use a signed compare, because the mask is -1u for an empty CIB. */
149  if ((int)avail <= (int)cib->mask) {
150  return (int)(cib->write_count++ & cib->mask);
151  }
152 
153  return -1;
154 }
155 
165 static inline int cib_put_unsafe(cib_t *cib)
166 {
167  return (int)(cib->write_count++ & cib->mask);
168 }
169 
170 #ifdef __cplusplus
171 }
172 #endif
173 
174 #endif /* CIB_H */
175 
cib_t::read_count
unsigned int read_count
number of (successful) read accesses
Definition: cib.h:35
cib_init
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
assert
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:104
assert.h
POSIX.1-2008 compliant version of the assert macro.
CIB_INIT
#define CIB_INIT(SIZE)
Initialize cib_t to a given size.
Definition: cib.h:47
cib_t::mask
unsigned int mask
Size of buffer -1, i.e.
Definition: cib.h:37
cib_get_unsafe
static int cib_get_unsafe(cib_t *cib)
Get the index of the next item in buffer.
Definition: cib.h:132
cib_avail
static unsigned int cib_avail(const cib_t *cib)
Calculates difference between cib_put() and cib_get() accesses.
Definition: cib.h:74
cib_peek
static int cib_peek(cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:114
cib_t
circular integer buffer structure
Definition: cib.h:34
cib_t::write_count
unsigned int write_count
number of (successful) write accesses
Definition: cib.h:36
cib_get
static int cib_get(cib_t *__restrict cib)
Get the index of the next item in buffer.
Definition: cib.h:98
cib_put
static int cib_put(cib_t *__restrict cib)
Get index for item in buffer to put to.
Definition: cib.h:144
cib_full
static unsigned int cib_full(const cib_t *cib)
Check if cib is full.
Definition: cib.h:86
cib_put_unsafe
static int cib_put_unsafe(cib_t *cib)
Get index for item in buffer to put to.
Definition: cib.h:165