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