Changes BITMASK_FOR_EACH to a macro
[akaros.git] / user / parlib / include / i686 / 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         {TRUSTEDBLOCK \
53         memset((void*)((uintptr_t)(name)), 0, BYTES_FOR_BITMASK((size))); \
54         } \
55 })
56
57 #define FILL_BITMASK(name, size) \
58 ({ \
59         {TRUSTEDBLOCK \
60         memset((void*)((uintptr_t)(name)), 255, BYTES_FOR_BITMASK((size))); \
61         } \
62         (name)[BYTES_FOR_BITMASK((size))-1] >>= (((size) % 8) ? (8 - ((size) % 8)) : 0 ); \
63 }) 
64
65 #define COPY_BITMASK(newmask, oldmask, size) \
66 ({ \
67         {TRUSTEDBLOCK \
68         memcpy((void*)((uintptr_t)(newmask)), \
69            (void*)((uintptr_t)(oldmask)), \
70            BYTES_FOR_BITMASK((size))); \
71         } \
72 })
73
74 // this checks the entire last byte, so keep it 0 in the other macros
75 #define BITMASK_IS_CLEAR(name, size) ({ \
76         uint32_t __n = BYTES_FOR_BITMASK((size)); \
77         bool clear = 1; \
78         while (__n-- > 0) { \
79                 if ((name)[__n]) { \
80                         clear = 0; \
81                         break;\
82                 }\
83         } \
84         clear; })
85
86 static inline bool BITMASK_IS_FULL(uint8_t* map, size_t size)
87 {
88         int _size = size;
89         for (int i = 0; i < BYTES_FOR_BITMASK(size); i++) {
90                 for (int j = 0; j < MIN(8,_size); j++)
91                         if(!((map[i] >> j) &1))
92                                 return FALSE;
93                         _size--;
94         }
95         return TRUE;
96 }
97
98 #define PRINT_BITMASK(name, size) { \
99         int i;  \
100         int _size = size; \
101         for (i = 0; i < BYTES_FOR_BITMASK(size); i++) { \
102                 int j;  \
103                 for (j = 0; j < MIN(8,_size); j++) \
104                         printf("%x", ((name)[i] >> j) & 1);     \
105                         _size--; \
106         } \
107         printf("\n"); \
108 }
109
110 #endif /* PARLIB_ARCH_BITMASK_H */