@@ -462,6 +462,9 @@ void bitset_debug(unsigned char *bitset, size_t length);
462462/* Returns the number of set bits in the given byte */
463463static unsigned int popcount_byte (unsigned char b );
464464
465+ /* Count the number of trailing zeroes in the given value */
466+ static unsigned char count_trailing_zeroes (size_t val );
467+
465468/* Returns the index of the highest bit set (1-based) */
466469static size_t highest_bit_position (size_t value );
467470
@@ -760,6 +763,7 @@ static unsigned int is_valid_alignment(size_t alignment) {
760763}
761764
762765static size_t buddy_tree_order_for_memory (size_t memory_size , size_t alignment ) {
766+ // cppcheck-suppress zerodiv
763767 size_t blocks = memory_size / alignment ;
764768 return highest_bit_position (ceiling_power_of_two (blocks ));
765769}
@@ -1106,16 +1110,16 @@ void buddy_enable_change_tracking(struct buddy* buddy, void* context, void (*tra
11061110
11071111
11081112static size_t depth_for_size (struct buddy * buddy , size_t requested_size ) {
1109- size_t depth , effective_memory_size ;
1113+ size_t depth , effective_memory_size , p2_of_requested_size ;
11101114 if (requested_size < buddy -> alignment ) {
11111115 requested_size = buddy -> alignment ;
11121116 }
11131117 depth = 1 ;
11141118 effective_memory_size = buddy_effective_memory_size (buddy );
1115- while (( effective_memory_size / requested_size ) >> 1u ) {
1116- depth ++ ;
1117- effective_memory_size >>= 1u ;
1118- }
1119+
1120+ p2_of_requested_size = ceiling_power_of_two ( requested_size ) ;
1121+ depth = count_trailing_zeroes ( effective_memory_size ) + 1
1122+ - count_trailing_zeroes ( p2_of_requested_size );
11191123 return depth ;
11201124}
11211125
@@ -2133,21 +2137,35 @@ void bitset_debug(unsigned char *bitset, size_t length) {
21332137 Bits
21342138*/
21352139
2136- static const unsigned char popcount_lookup [256 ] = {
2137- 0 ,1 ,1 ,2 ,1 ,2 ,2 ,3 ,1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,
2138- 1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
2139- 1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
2140- 2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
2141- 1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
2142- 2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
2143- 2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
2144- 3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,5 ,6 ,6 ,7 ,6 ,7 ,7 ,8
2145- };
2146-
21472140static inline unsigned int popcount_byte (unsigned char b ) {
2141+ static const unsigned char popcount_lookup [256 ] = {
2142+ 0 ,1 ,1 ,2 ,1 ,2 ,2 ,3 ,1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,
2143+ 1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
2144+ 1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
2145+ 2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
2146+ 1 ,2 ,2 ,3 ,2 ,3 ,3 ,4 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,
2147+ 2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
2148+ 2 ,3 ,3 ,4 ,3 ,4 ,4 ,5 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,
2149+ 3 ,4 ,4 ,5 ,4 ,5 ,5 ,6 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,4 ,5 ,5 ,6 ,5 ,6 ,6 ,7 ,5 ,6 ,6 ,7 ,6 ,7 ,7 ,8
2150+ };
21482151 return popcount_lookup [b ];
21492152}
21502153
2154+ static unsigned char count_trailing_zeroes (size_t val ) {
2155+ /* Implementation from https://www.chessprogramming.org/BitScan */
2156+ static const signed char lookup67 [67 + 1 ] = {
2157+ 64 , 0 , 1 , 39 , 2 , 15 , 40 , 23 ,
2158+ 3 , 12 , 16 , 59 , 41 , 19 , 24 , 54 ,
2159+ 4 , -1 , 13 , 10 , 17 , 62 , 60 , 28 ,
2160+ 42 , 30 , 20 , 51 , 25 , 44 , 55 , 47 ,
2161+ 5 , 32 , -1 , 38 , 14 , 22 , 11 , 58 ,
2162+ 18 , 53 , 63 , 9 , 61 , 27 , 29 , 50 ,
2163+ 43 , 46 , 31 , 37 , 21 , 57 , 52 , 8 ,
2164+ 26 , 49 , 45 , 36 , 56 , 7 , 48 , 35 ,
2165+ 6 , 34 , 33 , -1 };
2166+ return ((unsigned char ) lookup67 [(val & - val ) % 67 ]);
2167+ }
2168+
21512169/* Returns the highest set bit position for the given value. Returns zero for zero. */
21522170static size_t highest_bit_position (size_t value ) {
21532171 size_t result = 0 ;
0 commit comments