Demacro-ify the user BITMASK helpers
[akaros.git] / user / parlib / include / parlib / x86 / bitmask.h
1 #pragma once
2
3 #include <string.h>
4 #include <sys/types.h>
5 #include <sys/param.h>
6 #include <parlib/arch/atomic.h>
7 #include <stdio.h>
8
9 __BEGIN_DECLS
10
11 #define DECL_BITMASK(name, size) \
12         uint8_t (name)[BYTES_FOR_BITMASK((size))]
13
14 #define BYTES_FOR_BITMASK(size) \
15         (((size) - 1) / 8 + 1)
16
17 static inline bool GET_BITMASK_BIT(uint8_t *name, size_t bit)
18 {
19         return name[bit / 8] & (1 << (bit % 8)) ? TRUE : FALSE;
20 }
21
22 static inline void SET_BITMASK_BIT(uint8_t *name, size_t bit)
23 {
24         name[bit / 8] |= 1 << (bit % 8);
25 }
26
27 static inline void CLR_BITMASK_BIT(uint8_t *name, size_t bit)
28 {
29         name[bit / 8] &= ~(1 << (bit % 8));
30 }
31
32 static inline void SET_BITMASK_BIT_ATOMIC(uint8_t *name, size_t bit)
33 {
34         atomic_orb(&name[bit / 8], 1 << (bit % 8));
35 }
36
37 static inline void CLR_BITMASK_BIT_ATOMIC(uint8_t *name, size_t bit)
38 {
39         atomic_andb(&name[bit / 8], ~(1 << (bit % 8)));
40 }
41
42 static inline void CLR_BITMASK(uint8_t *name, size_t size)
43 {
44         memset(name, 0, BYTES_FOR_BITMASK(size));
45 }
46
47 static inline void FILL_BITMASK(uint8_t *name, size_t size)
48 {
49         memset(name, 255, BYTES_FOR_BITMASK(size));
50         name[BYTES_FOR_BITMASK(size) - 1] >>= ((size % 8) ? (8 - (size % 8)) : 0);
51 }
52
53 static inline void COPY_BITMASK(uint8_t *newmask, uint8_t *oldmask, size_t size)
54 {
55         memcpy(newmask, oldmask, BYTES_FOR_BITMASK(size));
56 }
57
58 /* this checks the entire last byte, so keep it 0 in the other functions */
59 static bool BITMASK_IS_CLEAR(uint8_t *name, size_t size)
60 {
61         uint32_t __n = BYTES_FOR_BITMASK(size);
62         bool clear = TRUE;
63
64         while (__n-- > 0) {
65                 if (name[__n]) {
66                         clear = FALSE;
67                         break;
68                 }
69         }
70         return clear;
71 }
72
73 static inline bool BITMASK_IS_FULL(uint8_t *map, size_t size)
74 {
75         size_t nr_bytes = BYTES_FOR_BITMASK(size);
76
77         for (int i = 0; i < nr_bytes; i++) {
78                 for (int j = 0; j < MIN(8, size); j++) {
79                         if (!((map[i] >> j) & 1))
80                                 return FALSE;
81                         size--;
82                 }
83         }
84         return TRUE;
85 }
86
87 static inline void PRINT_BITMASK(uint8_t *name, size_t size)
88 {
89         size_t nr_bytes = BYTES_FOR_BITMASK(size);
90
91         for (int i = 0; i < nr_bytes; i++) {
92                 for (int j = 0; j < MIN(8, size); j++) {
93                         printf("%x", (name[i] >> j) & 1);
94                         size--;
95                 }
96         }
97         printf("\n");
98 }
99
100 __END_DECLS