a3433a45f5d693ead4c4034e1e936ae7ea271b36
[akaros.git] / kern / include / bitmask.h
1 #ifndef ROS_KERN_BITMASK_H
2 #define ROS_KERN_BITMASK_H
3
4 #include <arch/bitmask.h>
5
6 static inline bool BITMASK_IS_SET_IN_RANGE(uint8_t* m, size_t beg, size_t end)
7 {
8         for(size_t i=beg; i<end; i++) {
9                 if(!GET_BITMASK_BIT(m, i))
10                         return FALSE;
11         }
12         return TRUE;
13 }
14
15 static inline bool BITMASK_IS_CLR_IN_RANGE(uint8_t* m, size_t beg, size_t end)
16 {
17         for(size_t i=beg; i<end; i++) {
18                 if(GET_BITMASK_BIT(m, i))
19                         return FALSE;
20         }
21         return TRUE;
22 }
23
24 static inline void SET_BITMASK_RANGE(uint8_t* m, size_t beg, size_t end)
25 {
26         for(size_t i=beg; i<end; i++) {
27                 SET_BITMASK_BIT(m, i);
28         }
29 }
30
31 static inline void CLR_BITMASK_RANGE(uint8_t* m, size_t beg, size_t end)
32 {
33         for(size_t i=beg; i<end; i++) {
34                 CLR_BITMASK_BIT(m, i);
35         }
36 }
37
38 /* Runs *work on every bit in the bitmask, passing *work the value of the bit
39  * that is set.  Optionally clears the bit from the bitmask. 
40  *
41  * We need this to be a macro, so that the calling code doesn't need the
42  * address for work_fn.  This matters for code that has nested functions that
43  * use local variables, since taking the address of work_fn will force the
44  * compiler to put the function on the stack and incur icache coherency
45  * overheads. */
46 #define BITMASK_FOREACH_SET(name, size, work_fn, clear)                        \
47 {                                                                              \
48         for (int i = 0; i < (size); i++) {                                         \
49                 bool present = GET_BITMASK_BIT((name), i);                             \
50                 if (present && (clear))                                                \
51                         CLR_BITMASK_BIT_ATOMIC((name), i);                                 \
52                 if (present)                                                           \
53                         (work_fn)(i);                                                      \
54         }                                                                          \
55 }                                                                              
56
57 #endif /* ROS_KERN_BITMASK_H */