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