bitfield.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2015 INRIA
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
28 #include <stdint.h>
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <string.h>
32 #include "irq.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
44 #define BITFIELD(NAME, SIZE) uint8_t NAME[((SIZE) + 7) / 8]
45 
52 static inline void bf_set(uint8_t field[], size_t idx)
53 {
54  field[idx / 8] |= (1u << (7 - (idx % 8)));
55 }
56 
63 static inline void bf_set_atomic(uint8_t field[], size_t idx)
64 {
65  unsigned state = irq_disable();
66  bf_set(field, idx);
67  irq_restore(state);
68 }
69 
76 static inline void bf_unset(uint8_t field[], size_t idx)
77 {
78  field[idx / 8] &= ~(1u << (7 - (idx % 8)));
79 }
80 
87 static inline void bf_unset_atomic(uint8_t field[], size_t idx)
88 {
89  unsigned state = irq_disable();
90  bf_unset(field, idx);
91  irq_restore(state);
92 }
93 
100 static inline void bf_toggle(uint8_t field[], size_t idx)
101 {
102  field[idx / 8] ^= (1u << (7 - (idx % 8)));
103 }
104 
111 static inline void bf_toggle_atomic(uint8_t field[], size_t idx)
112 {
113  unsigned state = irq_disable();
114  bf_toggle(field, idx);
115  irq_restore(state);
116 }
117 
124 static inline bool bf_isset(const uint8_t field[], size_t idx)
125 {
126  return (field[idx / 8] & (1u << (7 - (idx % 8))));
127 }
128 
143 static inline void bf_or(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
144 {
145  len = (len + 7) / 8;
146  while (len--) {
147  out[len] = a[len] | b[len];
148  }
149 }
150 
165 static inline void bf_or_atomic(uint8_t out[], const uint8_t a[],
166  const uint8_t b[], size_t len)
167 {
168  unsigned state = irq_disable();
169  bf_or(out, a, b, len);
170  irq_restore(state);
171 }
172 
187 static inline void bf_and(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
188 {
189  len = (len + 7) / 8;
190  while (len--) {
191  out[len] = a[len] & b[len];
192  }
193 }
194 
209 static inline void bf_and_atomic(uint8_t out[], const uint8_t a[],
210  const uint8_t b[], size_t len)
211 {
212  unsigned state = irq_disable();
213  bf_and(out, a, b, len);
214  irq_restore(state);
215 }
216 
231 static inline void bf_xor(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
232 {
233  len = (len + 7) / 8;
234  while (len--) {
235  out[len] = a[len] ^ b[len];
236  }
237 }
238 
253 static inline void bf_xor_atomic(uint8_t out[], const uint8_t a[],
254  const uint8_t b[], size_t len)
255 {
256  unsigned state = irq_disable();
257  bf_xor(out, a, b, len);
258  irq_restore(state);
259 }
260 
274 static inline void bf_inv(uint8_t out[], const uint8_t a[], size_t len)
275 {
276  len = (len + 7) / 8;
277  while (len--) {
278  out[len] = ~a[len];
279  }
280 }
281 
295 static inline void bf_inv_atomic(uint8_t out[], const uint8_t a[], size_t len)
296 {
297  unsigned state = irq_disable();
298  bf_inv(out, a, len);
299  irq_restore(state);
300 }
301 
313 int bf_get_unset(uint8_t field[], size_t len);
314 
324 int bf_find_first_set(const uint8_t field[], size_t size);
325 
335 int bf_find_first_unset(const uint8_t field[], size_t size);
336 
343 void bf_set_all(uint8_t field[], size_t size);
344 
351 static inline void bf_set_all_atomic(uint8_t field[], size_t size)
352 {
353  unsigned state = irq_disable();
354  bf_set_all(field, size);
355  irq_restore(state);
356 }
357 
364 void bf_clear_all(uint8_t field[], size_t size);
365 
372 static inline void bf_clear_all_atomic(uint8_t field[], size_t size)
373 {
374  unsigned state = irq_disable();
375  bf_clear_all(field, size);
376  irq_restore(state);
377 }
378 
387 unsigned bf_popcnt(const uint8_t field[], size_t size);
388 
389 #ifdef __cplusplus
390 }
391 #endif
392 
static void bf_toggle_atomic(uint8_t field[], size_t idx)
Atomically toggle the bit.
Definition: bitfield.h:111
static void bf_set(uint8_t field[], size_t idx)
Set the bit to 1.
Definition: bitfield.h:52
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:295
static void bf_unset_atomic(uint8_t field[], size_t idx)
Atomically clear the bit.
Definition: bitfield.h:87
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:165
static void bf_clear_all_atomic(uint8_t field[], size_t size)
Atomically clear all bits in the bitfield to 0.
Definition: bitfield.h:372
static void bf_set_all_atomic(uint8_t field[], size_t size)
Atomically set all bits in the bitfield to 1.
Definition: bitfield.h:351
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:209
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:231
static void bf_set_atomic(uint8_t field[], size_t idx)
Atomically set the bit to 1.
Definition: bitfield.h:63
static void bf_toggle(uint8_t field[], size_t idx)
Toggle the bit.
Definition: bitfield.h:100
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:187
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:253
static void bf_unset(uint8_t field[], size_t idx)
Clear the bit.
Definition: bitfield.h:76
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:143
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:274
static bool bf_isset(const uint8_t field[], size_t idx)
Check if the bet is set.
Definition: bitfield.h:124
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.