Count bits set in a range of `n` bits.
| 1148 | |
| 1149 | // Count bits set in a range of `n` bits. |
| 1150 | size_t mi_bitmap_popcountN( mi_bitmap_t* bitmap, size_t idx, size_t n) { |
| 1151 | mi_assert_internal(n>0); |
| 1152 | const size_t maxbits = mi_bitmap_max_bits(bitmap); |
| 1153 | mi_assert_internal(idx + n <= maxbits); |
| 1154 | if (idx+n > maxbits) { // paranoia |
| 1155 | if (idx >= maxbits) return 0; |
| 1156 | n = maxbits - idx; |
| 1157 | } |
| 1158 | |
| 1159 | // iterate through the chunks |
| 1160 | size_t chunk_idx = idx / MI_BCHUNK_BITS; |
| 1161 | size_t cidx = idx % MI_BCHUNK_BITS; |
| 1162 | size_t popcount = 0; |
| 1163 | while (n > 0) { |
| 1164 | const size_t m = (cidx + n > MI_BCHUNK_BITS ? MI_BCHUNK_BITS - cidx : n); |
| 1165 | popcount += mi_bchunk_popcountN(&bitmap->chunks[chunk_idx], cidx, m); |
| 1166 | mi_assert_internal(m <= n); |
| 1167 | n -= m; |
| 1168 | cidx = 0; |
| 1169 | chunk_idx++; |
| 1170 | } |
| 1171 | return popcount; |
| 1172 | } |
| 1173 | |
| 1174 | |
| 1175 | // Set/clear a bit in the bitmap; returns `true` if atomically transitioned from 0 to 1 (or 1 to 0) |
no test coverage detected