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 
9 #pragma once
10 
31 #include <stdint.h>
32 #include <stdbool.h>
33 #include <stddef.h>
34 #include <string.h>
35 #include "irq.h"
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
47 #define BITFIELD(NAME, SIZE) uint8_t NAME[((SIZE) + 7) / 8]
48 
55 static inline void bf_set(uint8_t field[], size_t idx)
56 {
57  field[idx / 8] |= (1u << (7 - (idx % 8)));
58 }
59 
66 static inline void bf_set_atomic(uint8_t field[], size_t idx)
67 {
68  unsigned state = irq_disable();
69  bf_set(field, idx);
70  irq_restore(state);
71 }
72 
79 static inline void bf_unset(uint8_t field[], size_t idx)
80 {
81  field[idx / 8] &= ~(1u << (7 - (idx % 8)));
82 }
83 
90 static inline void bf_unset_atomic(uint8_t field[], size_t idx)
91 {
92  unsigned state = irq_disable();
93  bf_unset(field, idx);
94  irq_restore(state);
95 }
96 
103 static inline void bf_toggle(uint8_t field[], size_t idx)
104 {
105  field[idx / 8] ^= (1u << (7 - (idx % 8)));
106 }
107 
114 static inline void bf_toggle_atomic(uint8_t field[], size_t idx)
115 {
116  unsigned state = irq_disable();
117  bf_toggle(field, idx);
118  irq_restore(state);
119 }
120 
127 static inline bool bf_isset(const uint8_t field[], size_t idx)
128 {
129  return (field[idx / 8] & (1u << (7 - (idx % 8))));
130 }
131 
146 static inline void bf_or(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
147 {
148  len = (len + 7) / 8;
149  while (len--) {
150  out[len] = a[len] | b[len];
151  }
152 }
153 
168 static inline void bf_or_atomic(uint8_t out[], const uint8_t a[],
169  const uint8_t b[], size_t len)
170 {
171  unsigned state = irq_disable();
172  bf_or(out, a, b, len);
173  irq_restore(state);
174 }
175 
190 static inline void bf_and(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
191 {
192  len = (len + 7) / 8;
193  while (len--) {
194  out[len] = a[len] & b[len];
195  }
196 }
197 
212 static inline void bf_and_atomic(uint8_t out[], const uint8_t a[],
213  const uint8_t b[], size_t len)
214 {
215  unsigned state = irq_disable();
216  bf_and(out, a, b, len);
217  irq_restore(state);
218 }
219 
234 static inline void bf_xor(uint8_t out[], const uint8_t a[], const uint8_t b[], size_t len)
235 {
236  len = (len + 7) / 8;
237  while (len--) {
238  out[len] = a[len] ^ b[len];
239  }
240 }
241 
256 static inline void bf_xor_atomic(uint8_t out[], const uint8_t a[],
257  const uint8_t b[], size_t len)
258 {
259  unsigned state = irq_disable();
260  bf_xor(out, a, b, len);
261  irq_restore(state);
262 }
263 
277 static inline void bf_inv(uint8_t out[], const uint8_t a[], size_t len)
278 {
279  len = (len + 7) / 8;
280  while (len--) {
281  out[len] = ~a[len];
282  }
283 }
284 
298 static inline void bf_inv_atomic(uint8_t out[], const uint8_t a[], size_t len)
299 {
300  unsigned state = irq_disable();
301  bf_inv(out, a, len);
302  irq_restore(state);
303 }
304 
316 int bf_get_unset(uint8_t field[], size_t len);
317 
327 int bf_find_first_set(const uint8_t field[], size_t size);
328 
338 int bf_find_first_unset(const uint8_t field[], size_t size);
339 
346 void bf_set_all(uint8_t field[], size_t size);
347 
354 static inline void bf_set_all_atomic(uint8_t field[], size_t size)
355 {
356  unsigned state = irq_disable();
357  bf_set_all(field, size);
358  irq_restore(state);
359 }
360 
367 void bf_clear_all(uint8_t field[], size_t size);
368 
375 static inline void bf_clear_all_atomic(uint8_t field[], size_t size)
376 {
377  unsigned state = irq_disable();
378  bf_clear_all(field, size);
379  irq_restore(state);
380 }
381 
390 unsigned bf_popcnt(const uint8_t field[], size_t size);
391 
392 #ifdef __cplusplus
393 }
394 #endif
395 
static void bf_toggle_atomic(uint8_t field[], size_t idx)
Atomically toggle the bit.
Definition: bitfield.h:114
static void bf_set(uint8_t field[], size_t idx)
Set the bit to 1.
Definition: bitfield.h:55
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:298
static void bf_unset_atomic(uint8_t field[], size_t idx)
Atomically clear the bit.
Definition: bitfield.h:90
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:168
static void bf_clear_all_atomic(uint8_t field[], size_t size)
Atomically clear all bits in the bitfield to 0.
Definition: bitfield.h:375
static void bf_set_all_atomic(uint8_t field[], size_t size)
Atomically set all bits in the bitfield to 1.
Definition: bitfield.h:354
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:212
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:234
static void bf_set_atomic(uint8_t field[], size_t idx)
Atomically set the bit to 1.
Definition: bitfield.h:66
static void bf_toggle(uint8_t field[], size_t idx)
Toggle the bit.
Definition: bitfield.h:103
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:190
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:256
static void bf_unset(uint8_t field[], size_t idx)
Clear the bit.
Definition: bitfield.h:79
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:146
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:277
static bool bf_isset(const uint8_t field[], size_t idx)
Check if the bet is set.
Definition: bitfield.h:127
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.