Find contiguous sequence of at least size set bits at or after start */
| 277 | |
| 278 | /* Find contiguous sequence of at least size set bits at or after start */ |
| 279 | static inline void |
| 280 | bit_ffs_area_at(bitstr_t *_bitstr, int _start, int _nbits, int _size, |
| 281 | int *_result) |
| 282 | { |
| 283 | bitstr_t *_curbitstr; |
| 284 | bitstr_t _test; |
| 285 | int _value, _offset, _logsize, _b; |
| 286 | |
| 287 | if (_start + _size > _nbits || _nbits <= 0) { |
| 288 | *_result = -1; |
| 289 | return; |
| 290 | } |
| 291 | |
| 292 | _logsize = fls(_size - 1); |
| 293 | _value = _start; |
| 294 | _curbitstr = _bitstr + _bit_idx(_start); |
| 295 | _test = ~*_curbitstr; |
| 296 | if (_bit_offset(_start) != 0) |
| 297 | _test |= _bit_make_mask(0, _start - 1); |
| 298 | for (_offset = 0;; _offset -= _BITSTR_BITS, _test = ~*++_curbitstr) { |
| 299 | if (_test != 0) { |
| 300 | /* If leading 0s in _test can finish 0-area, stop. */ |
| 301 | if (_offset + _size < (int)_BITSTR_BITS && |
| 302 | (_test & _bit_make_mask(0, _offset + _size)) == 0) |
| 303 | break; |
| 304 | /* Shrink-left every 0-area in _test by size-1 bits. */ |
| 305 | _b = _logsize; |
| 306 | while ((_test & (_test + 1)) != 0 && _b-- > 0) |
| 307 | _test |= _test >> (((_size - 1) >> _b) + 1) / 2; |
| 308 | /* Find the start of the first 0-area in _test. */ |
| 309 | _offset = (~_test == 0) ? (int)_BITSTR_BITS : |
| 310 | ffsl(~_test) - 1; |
| 311 | _value = (_curbitstr - _bitstr) * _BITSTR_BITS + |
| 312 | _offset; |
| 313 | /* If there's insufficient space left, give up. */ |
| 314 | if (_value + _size > _nbits) { |
| 315 | _value = -1; |
| 316 | break; |
| 317 | } |
| 318 | } |
| 319 | if (_offset + _size <= (int)_BITSTR_BITS) |
| 320 | break; |
| 321 | } |
| 322 | *_result = _value; |
| 323 | } |
| 324 | |
| 325 | /* Find contiguous sequence of at least size cleared bits at or after start */ |
| 326 | static inline void |
no test coverage detected