| #pragma once |
| |
| #include <string.h> |
| #include <sys/types.h> |
| #include <atomic.h> |
| #include <stdio.h> |
| |
| #define DECL_BITMASK(name, size) \ |
| uint8_t (name)[BYTES_FOR_BITMASK((size))] |
| |
| #define BYTES_FOR_BITMASK(size) \ |
| (((size) - 1) / 8 + 1) |
| |
| #define BYTES_FOR_BITMASK_WITH_CHECK(size) \ |
| ((size) ? ((size) - (1)) / (8) + (1) : (0)) |
| |
| static bool GET_BITMASK_BIT(uint8_t* name, size_t bit) |
| { |
| return (((name)[(bit)/8] & (1 << ((bit) % 8))) ? 1 : 0); |
| } |
| |
| #define SET_BITMASK_BIT(name, bit) \ |
| ((name)[(bit)/8] |= (1 << ((bit) % 8))); |
| /* |
| static void SET_BITMASK_BIT(uint8_t* name, size_t bit) |
| { |
| ((name)[(bit)/8] |= (1 << ((bit) % 8))); |
| } |
| */ |
| |
| #define CLR_BITMASK_BIT(name, bit) \ |
| ((name)[(bit)/8] &= ~(1 << ((bit) % 8))); |
| /* |
| static void CLR_BITMASK_BIT(uint8_t* name, size_t bit) |
| { |
| ((name)[(bit)/8] &= ~(1 << ((bit) % 8))); |
| } |
| */ |
| |
| static void SET_BITMASK_BIT_ATOMIC(uint8_t* name, size_t bit) |
| { |
| (atomic_orb(&(name)[(bit)/8], (1 << ((bit) % 8)))); |
| } |
| |
| #define CLR_BITMASK_BIT_ATOMIC(name, bit) \ |
| (atomic_andb(&(name)[(bit)/8], ~(1 << ((bit) % 8)))) |
| |
| #define CLR_BITMASK(name, size) \ |
| ({ \ |
| memset((void*)((uintptr_t)(name)), 0, BYTES_FOR_BITMASK((size))); \ |
| }) |
| |
| #define FILL_BITMASK(name, size) \ |
| ({ \ |
| memset((void*)((uintptr_t)(name)), 255, BYTES_FOR_BITMASK((size))); \ |
| (name)[BYTES_FOR_BITMASK((size))-1] >>= (((size) % 8) ? (8 - ((size) % 8)) : 0 ); \ |
| }) |
| |
| #define COPY_BITMASK(newmask, oldmask, size) \ |
| ({ \ |
| memcpy((void*)((uintptr_t)(newmask)), \ |
| (void*)((uintptr_t)(oldmask)), \ |
| BYTES_FOR_BITMASK((size))); \ |
| }) |
| |
| // this checks the entire last byte, so keep it 0 in the other macros |
| #define BITMASK_IS_CLEAR(name, size) ({ \ |
| uint32_t __n = BYTES_FOR_BITMASK((size)); \ |
| bool clear = 1; \ |
| while (__n-- > 0) { \ |
| if ((name)[__n]) { \ |
| clear = 0; \ |
| break;\ |
| }\ |
| } \ |
| clear; }) |
| |
| static inline bool BITMASK_IS_FULL(volatile uint8_t *map, size_t size) |
| { |
| int _size = size; |
| for (int i = 0; i < BYTES_FOR_BITMASK(size); i++) { |
| for (int j = 0; j < MIN(8, _size); j++) { |
| if(!((map[i] >> j) &1)) |
| return FALSE; |
| _size--; |
| } |
| } |
| return TRUE; |
| } |
| |
| #define PRINT_BITMASK(name, size) { \ |
| int i; \ |
| int _size = size; \ |
| print_lock(); \ |
| for (i = 0; i < BYTES_FOR_BITMASK(size); i++) { \ |
| int j; \ |
| for (j = 0; j < MIN(8, _size); j++) { \ |
| printk("%x", ((name)[i] >> j) & 1); \ |
| _size--; \ |
| } \ |
| } \ |
| printk("\n"); \ |
| print_unlock(); \ |
| } |