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 
43 #define CIB_INIT(SIZE) { 0, 0, (SIZE) - 1 }
44 
53 static inline void cib_init(cib_t *__restrict cib, unsigned int size)
54 {
55  /* check if size is a power of 2 by comparing it to its complement */
56  assert(!(size & (size - 1)));
57 
58  cib_t c = CIB_INIT(size);
59  *cib = c;
60 }
61 
69 static inline unsigned int cib_avail(const cib_t *cib)
70 {
71  return cib->write_count - cib->read_count;
72 }
73 
81 static inline unsigned int cib_full(const cib_t *cib)
82 {
83  return ((int) cib_avail(cib)) > ((int) cib->mask);
84 }
85 
93 static inline int cib_get(cib_t *__restrict cib)
94 {
95  if (cib->write_count > cib->read_count) {
96  return (int) (cib->read_count++ & cib->mask);
97  }
98 
99  return -1;
100 }
101 
109 static inline int cib_peek(cib_t *__restrict cib)
110 {
111  if (cib->write_count > cib->read_count) {
112  return (int) (cib->read_count & cib->mask);
113  }
114 
115  return -1;
116 }
117 
127 static inline int cib_get_unsafe(cib_t *cib)
128 {
129  return (int) (cib->read_count++ & cib->mask);
130 }
131 
139 static inline int cib_put(cib_t *__restrict cib)
140 {
141  unsigned int avail = cib_avail(cib);
142 
143  /* We use a signed compare, because the mask is -1u for an empty CIB. */
144  if ((int) avail <= (int) cib->mask) {
145  return (int) (cib->write_count++ & cib->mask);
146  }
147 
148  return -1;
149 }
150 
160 static inline int cib_put_unsafe(cib_t *cib)
161 {
162  return (int) (cib->write_count++ & cib->mask);
163 }
164 
165 #ifdef __cplusplus
166 }
167 #endif
168 
169 #endif /* CIB_H */
170 
static int cib_peek(cib_t *__restrict cib)
Get the index of the next item in buffer without removing it.
Definition: cib.h:109
unsigned int mask
Size of buffer -1, i.e.
Definition: cib.h:37
circular integer buffer structure
Definition: cib.h:34
static int cib_get(cib_t *__restrict cib)
Get the index of the next item in buffer.
Definition: cib.h:93
#define CIB_INIT(SIZE)
Initialize cib_t to a given size.
Definition: cib.h:43
static unsigned int cib_full(const cib_t *cib)
Check if cib is full.
Definition: cib.h:81
POSIX.1-2008 compliant version of the assert macro.
unsigned int read_count
number of (successful) read accesses
Definition: cib.h:35
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:104
static void cib_init(cib_t *__restrict cib, unsigned int size)
Initialize cib to 0 and set buffer size to size.
Definition: cib.h:53
static unsigned int cib_avail(const cib_t *cib)
Calculates difference between cib_put() and cib_get() accesses.
Definition: cib.h:69
static int cib_put(cib_t *__restrict cib)
Get index for item in buffer to put to.
Definition: cib.h:139
static int cib_get_unsafe(cib_t *cib)
Get the index of the next item in buffer.
Definition: cib.h:127
static int cib_put_unsafe(cib_t *cib)
Get index for item in buffer to put to.
Definition: cib.h:160
unsigned int write_count
number of (successful) write accesses
Definition: cib.h:36