| 203 | } |
| 204 | |
| 205 | static inline void |
| 206 | bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) { |
| 207 | size_t goff; |
| 208 | bitmap_t *gp; |
| 209 | bitmap_t g; |
| 210 | |
| 211 | assert(bit < binfo->nbits); |
| 212 | assert(!bitmap_get(bitmap, binfo, bit)); |
| 213 | goff = bit >> LG_BITMAP_GROUP_NBITS; |
| 214 | gp = &bitmap[goff]; |
| 215 | g = *gp; |
| 216 | assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))); |
| 217 | g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK); |
| 218 | *gp = g; |
| 219 | assert(bitmap_get(bitmap, binfo, bit)); |
| 220 | #ifdef BITMAP_USE_TREE |
| 221 | /* Propagate group state transitions up the tree. */ |
| 222 | if (g == 0) { |
| 223 | unsigned i; |
| 224 | for (i = 1; i < binfo->nlevels; i++) { |
| 225 | bit = goff; |
| 226 | goff = bit >> LG_BITMAP_GROUP_NBITS; |
| 227 | gp = &bitmap[binfo->levels[i].group_offset + goff]; |
| 228 | g = *gp; |
| 229 | assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))); |
| 230 | g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK); |
| 231 | *gp = g; |
| 232 | if (g != 0) { |
| 233 | break; |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | #endif |
| 238 | } |
| 239 | |
| 240 | /* ffu: find first unset >= bit. */ |
| 241 | static inline size_t |