Last active
June 11, 2020 09:49
-
-
Save ayende/54b078d39aa540a9a90a0a4646f5605f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static bool find_clear_range(uint64_t* bitmap, size_t bitmapsize, | |
size_t start_search, size_t size_requested, | |
size_t* bit_pos, size_t* available_size){ | |
uint64_t bitset; | |
uint64_t previous_set_bit = ULONG_MAX; | |
uint64_t current; | |
size_t k = start_search/64; | |
if(k >= bitmapsize) | |
return false; | |
bitset = bitmap[k]; | |
uint64_t mask = ~(ULONG_MAX << (start_search%64)); | |
bitset ^= mask; | |
do { | |
if (bitset == 0) { | |
if(previous_set_bit == ULONG_MAX){ | |
previous_set_bit = k*64; | |
} | |
current = (k+1)*64; | |
if(current > previous_set_bit + size_requested && | |
current > start_search){ | |
*bit_pos = previous_set_bit+1; | |
*available_size = (current + 64 - previous_set_bit); | |
return true; | |
} | |
} | |
while(bitset != 0){ | |
int r = __builtin_ctzl(bitset); | |
current = k*64 + (uint64_t)r; | |
if(current > previous_set_bit + size_requested && | |
current > start_search){ | |
*bit_pos = previous_set_bit+1; | |
*available_size = (current - previous_set_bit -1); | |
return true; | |
} | |
previous_set_bit = current; | |
bitset ^= (bitset & -bitset); | |
} | |
if(++k >= bitmapsize) | |
break; | |
bitset = bitmap[k]; | |
} while(true); | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment