vmm: refactor userspace's emsr_fakewrite()
[akaros.git] / user / parlib / include / parlib / riscv / 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 <parlib/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 #define BYTES_FOR_BITMASK_WITH_CHECK(size) \
18         ((size) ? ((size) - (1)) / (8) + (1) : (0))
19
20 static bool GET_BITMASK_BIT(const uint8_t *name, size_t bit)
21 {
22         return (((name)[(bit)/8] & (1 << ((bit) % 8))) ? 1 : 0);
23 }
24
25 #define SET_BITMASK_BIT(name, bit) \
26         ((name)[(bit)/8] |= (1 << ((bit) % 8)));
27 /*
28 static void SET_BITMASK_BIT(uint8_t* name, size_t bit)
29 {
30         ((name)[(bit)/8] |= (1 << ((bit) % 8)));
31 }
32 */
33
34 #define CLR_BITMASK_BIT(name, bit) \
35         ((name)[(bit)/8] &= ~(1 << ((bit) % 8)));
36 /*
37 static void CLR_BITMASK_BIT(uint8_t* name, size_t bit) 
38 {
39         ((name)[(bit)/8] &= ~(1 << ((bit) % 8)));
40 }
41 */
42
43 static void SET_BITMASK_BIT_ATOMIC(uint8_t* name, size_t bit) 
44 {
45         (atomic_orb(&(name)[(bit)/8], (1 << ((bit) % 8))));
46 }
47
48 #define CLR_BITMASK_BIT_ATOMIC(name, bit) \
49         (atomic_andb(&(name)[(bit)/8], ~(1 << ((bit) % 8))))
50
51 #define CLR_BITMASK(name, size) \
52 ({ \
53         memset((void*)((uintptr_t)(name)), 0, BYTES_FOR_BITMASK((size))); \
54 })
55
56 #define FILL_BITMASK(name, size) \
57 ({ \
58         memset((void*)((uintptr_t)(name)), 255, BYTES_FOR_BITMASK((size))); \
59         (name)[BYTES_FOR_BITMASK((size))-1] >>= (((size) % 8) ? (8 - ((size) % 8)) : 0 ); \
60 }) 
61
62 #define COPY_BITMASK(newmask, oldmask, size) \
63 ({ \
64         memcpy((void*)((uintptr_t)(newmask)), \
65            (void*)((uintptr_t)(oldmask)), \
66            BYTES_FOR_BITMASK((size))); \
67 })
68
69 // this checks the entire last byte, so keep it 0 in the other macros
70 #define BITMASK_IS_CLEAR(name, size) ({ \
71         uint32_t __n = BYTES_FOR_BITMASK((size)); \
72         bool clear = 1; \
73         while (__n-- > 0) { \
74                 if ((name)[__n]) { \
75                         clear = 0; \
76                         break;\
77                 }\
78         } \
79         clear; })
80
81 static inline bool BITMASK_IS_FULL(const uint8_t *map, size_t size)
82 {
83         int _size = size;
84         for (int i = 0; i < BYTES_FOR_BITMASK(size); i++) {
85                 for (int j = 0; j < MIN(8,_size); j++)
86                         if(!((map[i] >> j) &1))
87                                 return FALSE;
88                         _size--;
89         }
90         return TRUE;
91 }
92
93 __END_DECLS