bitfield.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 INRIA
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
29 #ifndef BITFIELD_H
30 #define BITFIELD_H
31 
32 #include <stdint.h>
33 #include <stdbool.h>
34 #include <stddef.h>
35 #include <string.h>
36 #include "irq.h"
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
48 #define BITFIELD(NAME, SIZE) uint8_t NAME[((SIZE) + 7) / 8]
49 
56 static inline void bf_set(uint8_t field[], size_t idx)
57 {
58  field[idx / 8] |= (1u << (7 - (idx % 8)));
59 }
60 
67 static inline void bf_set_atomic(uint8_t field[], size_t idx)
68 {
69  unsigned state = irq_disable();
70  bf_set(field, idx);
71  irq_restore(state);
72 }
73 
80 static inline void bf_unset(uint8_t field[], size_t idx)
81 {
82  field[idx / 8] &= ~(1u << (7 - (idx % 8)));
83 }
84 
91 static inline void bf_unset_atomic(uint8_t field[], size_t idx)
92 {
93  unsigned state = irq_disable();
94  bf_unset(field, idx);
95  irq_restore(state);
96 }
97 
104 static inline void bf_toggle(uint8_t field[], size_t idx)
105 {
106  field[idx / 8] ^= (1u << (7 - (idx % 8)));
107 }
108 
115 static inline void bf_toggle_atomic(uint8_t field[], size_t idx)
116 {
117  unsigned state = irq_disable();
118  bf_toggle(field, idx);
119  irq_restore(state);
120 }
121 
128 static inline bool bf_isset(const uint8_t field[], size_t idx)
129 {
130  return (field[idx / 8] & (1u << (7 - (idx % 8))));
131 }
132 
147 static inline void bf_or(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
148 {
149  len = (len + 7) / 8;
150  while (len--) {
151  out[len] = a[len] | b[len];
152  }
153 }
154 
169 static inline void bf_or_atomic(uint8_t out[], const uint8_t a[],
170  const uint8_t b[], size_t len)
171 {
172  unsigned state = irq_disable();
173  bf_or(out, a, b, len);
174  irq_restore(state);
175 }
176 
191 static inline void bf_and(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
192 {
193  len = (len + 7) / 8;
194  while (len--) {
195  out[len] = a[len] & b[len];
196  }
197 }
198 
213 static inline void bf_and_atomic(uint8_t out[], const uint8_t a[],
214  const uint8_t b[], size_t len)
215 {
216  unsigned state = irq_disable();
217  bf_and(out, a, b, len);
218  irq_restore(state);
219 }
220 
235 static inline void bf_xor(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
236 {
237  len = (len + 7) / 8;
238  while (len--) {
239  out[len] = a[len] ^ b[len];
240  }
241 }
242 
257 static inline void bf_xor_atomic(uint8_t out[], const uint8_t a[],
258  const uint8_t b[], size_t len)
259 {
260  unsigned state = irq_disable();
261  bf_xor(out, a, b, len);
262  irq_restore(state);
263 }
264 
278 static inline void bf_inv(uint8_t out[], const uint8_t a[], size_t len)
279 {
280  len = (len + 7) / 8;
281  while (len--) {
282  out[len] = ~a[len];
283  }
284 }
285 
299 static inline void bf_inv_atomic(uint8_t out[], const uint8_t a[], size_t len)
300 {
301  unsigned state = irq_disable();
302  bf_inv(out, a, len);
303  irq_restore(state);
304 }
305 
317 int bf_get_unset(uint8_t field[], size_t len);
318 
328 int bf_find_first_set(const uint8_t field[], size_t size);
329 
339 int bf_find_first_unset(const uint8_t field[], size_t size);
340 
347 void bf_set_all(uint8_t field[], size_t size);
348 
355 static inline void bf_set_all_atomic(uint8_t field[], size_t size)
356 {
357  unsigned state = irq_disable();
358  bf_set_all(field, size);
359  irq_restore(state);
360 }
361 
368 void bf_clear_all(uint8_t field[], size_t size);
369 
376 static inline void bf_clear_all_atomic(uint8_t field[], size_t size)
377 {
378  unsigned state = irq_disable();
379  bf_clear_all(field, size);
380  irq_restore(state);
381 }
382 
391 unsigned bf_popcnt(const uint8_t field[], size_t size);
392 
393 #ifdef __cplusplus
394 }
395 #endif
396 
398 #endif /* BITFIELD_H */
static void bf_toggle_atomic(uint8_t field[], size_t idx)
Atomically toggle the bit.
Definition: bitfield.h:115
static void bf_set(uint8_t field[], size_t idx)
Set the bit to 1.
Definition: bitfield.h:56
static void bf_inv_atomic(uint8_t out[], const uint8_t a[], size_t len)
Atomically perform a bitwise NOT operation on a bitfield out = ~a
Definition: bitfield.h:299
static void bf_unset_atomic(uint8_t field[], size_t idx)
Atomically clear the bit.
Definition: bitfield.h:91
static void bf_or_atomic(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
Atomically perform a bitwise OR operation on two bitfields out = a | b
Definition: bitfield.h:169
static void bf_clear_all_atomic(uint8_t field[], size_t size)
Atomically clear all bits in the bitfield to 0.
Definition: bitfield.h:376
static void bf_set_all_atomic(uint8_t field[], size_t size)
Atomically set all bits in the bitfield to 1.
Definition: bitfield.h:355
int bf_find_first_unset(const uint8_t field[], size_t size)
Get the index of the zero bit in the field.
void bf_clear_all(uint8_t field[], size_t size)
Clear all bits in the bitfield to 0.
static void bf_and_atomic(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
Atomically perform a bitwise AND operation on two bitfields out = a & b
Definition: bitfield.h:213
static void bf_xor(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
Perform a bitwise XOR operation on two bitfields out = a ^ b
Definition: bitfield.h:235
static void bf_set_atomic(uint8_t field[], size_t idx)
Atomically set the bit to 1.
Definition: bitfield.h:67
static void bf_toggle(uint8_t field[], size_t idx)
Toggle the bit.
Definition: bitfield.h:104
static void bf_and(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
Perform a bitwise AND operation on two bitfields out = a & b
Definition: bitfield.h:191
int bf_find_first_set(const uint8_t field[], size_t size)
Get the index of the first set bit in the field.
static void bf_xor_atomic(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
Atomically perform a bitwise XOR operation on two bitfields out = a ^ b
Definition: bitfield.h:257
static void bf_unset(uint8_t field[], size_t idx)
Clear the bit.
Definition: bitfield.h:80
static void bf_or(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
Perform a bitwise OR operation on two bitfields out = a | b
Definition: bitfield.h:147
unsigned bf_popcnt(const uint8_t field[], size_t size)
Count set bits in the bitfield.
static void bf_inv(uint8_t out[], const uint8_t a[], size_t len)
Perform a bitwise NOT operation on a bitfield out = ~a
Definition: bitfield.h:278
static bool bf_isset(const uint8_t field[], size_t idx)
Check if the bet is set.
Definition: bitfield.h:128
void bf_set_all(uint8_t field[], size_t size)
Set all bits in the bitfield to 1.
int bf_get_unset(uint8_t field[], size_t len)
Atomically get the number of an unset bit and set it.
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
IRQ driver interface.