1 #ifndef __LUNAIX_BITMAP_H
2 #define __LUNAIX_BITMAP_H
4 #include <lunaix/types.h>
5 #include <lunaix/spike.h>
6 #include <klibc/string.h>
8 // first bit of a bitmap chunk placed at the most significant bit
9 #define BMP_ORIENT_MSB 0
10 // first bit of a bitmap chunk placed at the least significant bit
11 #define BMP_ORIENT_LSB 1
13 #define BMP_NAME(name) bitmap_##name
14 #define BMP_PARAM_NAME bmp
15 #define BMP_PARAM(name) struct BMP_NAME(name) *BMP_PARAM_NAME
16 #define BMP_RAWBYTES(bits) (((bits) + 7) / 8)
17 #define BMP_SIZE(t, bits) \
18 (BMP_RAWBYTES(bits) + (BMP_RAWBYTES(bits) % sizeof(t)))
20 #define BMP_LEN(t, bits) (BMP_SIZE(t, bits) / sizeof(t))
22 #define _BITMAP_STRUCT(type, size, name, orient) struct BMP_NAME(name)
25 #define _DECLARE_BMP(type, size, name, orient) \
26 struct BMP_NAME(name) { \
28 unsigned long nr_bits; \
31 #define _DECLARE_BMP_STATIC(type, nr_bits, name, orient) \
32 struct BMP_NAME(name) { \
33 type _map[BMP_LEN(type, nr_bits)]; \
36 #define BMP_STRCUT_MAP BMP_PARAM_NAME->_map
37 #define BMP_STRCUT_NRB BMP_PARAM_NAME->nr_bits
39 #define _BMP_OP_CALL(type, size, name, orient, suffix, ...) \
40 bitmap_##name##_##suffix##(__VA_ARGS__)
42 #define _DEFINE_BMP_INIT_OP(type, size, name, orient, allocfn) \
44 bitmap_##name##_init_with(BMP_PARAM(name), unsigned long nr_bits, ptr_t map) \
46 (void)(is_const(size) ? ({ \
47 BMP_STRCUT_MAP = map; \
48 BMP_STRCUT_NRB = nr_bits; \
49 memset(BMP_STRCUT_MAP, 0, BMP_SIZE(type, nr_bits) * sizeof(type));0; \
51 memset(BMP_STRCUT_MAP, 0, sizeof(BMP_STRCUT_MAP));0; \
55 bitmap_##name##_init(BMP_PARAM(name), unsigned long nr_bits) \
57 (void)(is_const(size) ? ({ \
58 bitmap_##name##_init_with(BMP_PARAM_NAME, nr_bits, \
59 allocfn(BMP_SIZE(type, nr_bits)));0; \
61 bitmap_##name##_init_with(BMP_PARAM_NAME, nr_bits, NULL);0; \
66 #define _DEFINE_BMP_QUERY_OP(type, size, name, orient) \
68 bitmap_##name##_query(BMP_PARAM(name), unsigned long pos) \
71 unsigned long n = pos / (sizeof(type) * 8); \
72 int i = pos % (sizeof(type) * 8); \
73 type at = BMP_STRCUT_MAP[n]; \
74 type msk = 1 << select(orient == BMP_ORIENT_MSB, \
75 sizeof(type) * 8 - 1 - i, i ); \
76 return !!(at & msk); \
80 #define _DEFINE_BMP_SET_OP(type, size, name, orient) \
82 bitmap_##name##_set(BMP_PARAM(name), unsigned long pos, bool val) \
85 unsigned long n = pos / (sizeof(type) * 8); \
86 int i = pos % (sizeof(type) * 8); \
87 type at = BMP_STRCUT_MAP[n]; \
88 unsigned int off = select(orient == BMP_ORIENT_MSB, \
89 sizeof(type) * 8 - 1 - i, i ); \
90 BMP_STRCUT_MAP[n] = (at & ~(1 << off)) | (!!val << off); \
94 #define _DEFINE_BMP_ALLOCFROM_OP(type, size, name, orient) \
96 bitmap_##name##_alloc_from(BMP_PARAM(name), unsigned long start, \
97 unsigned long* _out) \
99 unsigned long i, p = 0; \
103 i = start / 8 / sizeof(type); \
104 shift = select(orient == BMP_ORIENT_MSB, sizeof(type) * 8 - 1, 0); \
106 while ((u = BMP_STRCUT_MAP[i]) == (type)-1) i++; \
107 while ((u & (type)(1U << shift)) && p++ < sizeof(type) * 8) \
108 select(orient == BMP_ORIENT_MSB, u <<= 1, u >>= 1); \
110 if (p < sizeof(type) * 8) \
113 BMP_STRCUT_MAP[i] |= 1UL << shift; \
114 *_out = (i * 8 + p); \
119 #define _DEFINE_BMP_ALLOCFROM_OP(type, size, name, orient) \
121 bitmap_##name##_alloc_between(BMP_PARAM(name), \
122 unsigned long start, unsigned long end, \
123 unsigned long* _out) \
125 unsigned long i, p = 0; \
126 unsigned long i_e, p_e = 0; \
130 i = start / 8 / sizeof(type); \
131 i_e = end / 8 / sizeof(type); \
132 p_e = end % (8 * sizeof(type)); \
133 shift = select(orient == BMP_ORIENT_MSB, sizeof(type) * 8 - 1, 0); \
135 while (i < i_e && (u = BMP_STRCUT_MAP[i]) == (type)-1) i++; \
136 while ((u & (type)(1U << shift)) && p++ < sizeof(type) * 8) \
137 select(orient == BMP_ORIENT_MSB, u <<= 1, u >>= 1); \
139 if (i >= i_e && p > p_e) \
142 BMP_STRCUT_MAP[i] |= 1UL << shift; \
143 *_out = (i * 8 + p); \
149 #define PREP_STATIC_BITMAP(type, name, nr_bits, orient) \
150 type, (nr_bits), name, orient
151 #define PREP_BITMAP(type, name, orient) \
152 type, (BMP_STRCUT_NRB), name, orient
155 #define DECLARE_BITMAP(bmpdef) _DECLARE_BMP(bmpdef)
156 #define DECLARE_STATIC_BITMAP(bmpdef) _DECLARE_BMP_STATIC(bmpdef)
157 #define BITMAP(bmpdef) _BITMAP_STRUCT(bmpdef)
159 #define DEFINE_BMP_INIT_OP(bmpdef, allocfn) _DEFINE_BMP_INIT_OP(bmpdef, allocfn)
161 #define DEFINE_BMP_QUERY_OP(bmpdef) _DEFINE_BMP_QUERY_OP(bmpdef)
162 #define DEFINE_BMP_SET_OP(bmpdef) _DEFINE_BMP_SET_OP(bmpdef)
163 #define DEFINE_BMP_ALLOCFROM_OP(bmpdef) _DEFINE_BMP_ALLOCFROM_OP(bmpdef)
165 #define bitmap_query(bitmap, bmp, pos) \
166 _BMP_OP_CALL(bitmap, query, bmp, pos)
168 #define bitmap_set(bitmap, bmp, pos, val) \
169 _BMP_OP_CALL(bitmap, set, bmp, pos, val)
171 #define bitmap_alloc(bitmap, bmp, start, out) \
172 _BMP_OP_CALL(bitmap, alloc_from, bmp, start, out)
174 #define bitmap_init(bitmap, bmp, nr_bits) \
175 _BMP_OP_CALL(bitmap, init, bmp, nr_bits)
177 #define bitmap_init_ptr(bitmap, bmp, nr_bits, ptr) \
178 _BMP_OP_CALL(bitmap, init_with, bmp, nr_bits, ptr)
180 #define bitmap_alloc_within(bitmap, bmp, start, end, out) \
181 _BMP_OP_CALL(bitmap, alloc_between, bmp, start, end, out)
183 #endif /* __LUNAIX_BITMAP_H */