diff --git a/include/math.h b/include/math.h new file mode 100644 index 0000000..d86cf0a --- /dev/null +++ b/include/math.h @@ -0,0 +1,8 @@ +#ifndef _QUARK_UTIL_H +#define _QUARK_UTIL_H + +int ilog2(unsigned int x); + +int llog2(unsigned long x); + +#endif \ No newline at end of file diff --git a/src/heap.c b/src/heap.c index 9eec40e..488fa5a 100644 --- a/src/heap.c +++ b/src/heap.c @@ -1,6 +1,7 @@ #include #include "heap.h" #include "mmgr.h" +#include "math.h" #include "types/status.h" #define AVAIL 0 @@ -23,23 +24,6 @@ struct heap_node_t size_t state : 2; } __attribute__ ((packed)); -size_t ilog2(size_t n) -{ - size_t m = n; - size_t count = 0; - bool isPowerOfTwo = true; - while(m) - { - if((m & 1) == 1 && m > 1) - { - isPowerOfTwo = false; - } - count++; - m >>= 1; - } - return count - (isPowerOfTwo ? 1 : 0); -} - size_t find_free_block(struct heap_t *heap, size_t height) { if(height > heap->tree_height) @@ -95,7 +79,7 @@ int heap_contruct(struct heap_t *heap, void *base, void *start, size_t heap_size heap->header = (struct heap_node_t*) start; heap->heap_size = heap_size; heap->block_size = block_size; - heap->tree_height = ilog2(heap_size / block_size); + heap->tree_height = llog2(heap_size / block_size); size_t header_size = (heap_size / block_size) << 1; for(size_t i = 1; i <= (heap_size / block_size) * 2; i++) { @@ -136,7 +120,7 @@ void *heap_allocate(struct heap_t *heap, size_t size) { size += heap->block_size - 1; size -= size % heap->block_size; - size_t height = ilog2(size / heap->block_size); + size_t height = llog2(size / heap->block_size); size_t index = find_free_block(heap, height); if(index) { diff --git a/src/math.c b/src/math.c new file mode 100644 index 0000000..b8ec08e --- /dev/null +++ b/src/math.c @@ -0,0 +1,66 @@ +#include "math.h" + +int ilog2(unsigned int x) +{ +#if defined __GNUC__ + if(x <= 1) + return 0; + return 32 - __builtin_clzl(x - 1); +#else + static const int table[32] = { + 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return table[(x * 0x07C4ACDD) >> 27]; +#endif +} + +int llog2(unsigned long x) +{ +#if (defined __GNUC__) && (__SIZEOF_LONG__ == 4) + if(x <= 1) + return 0; + return 32 - __builtin_clzl(x - 1); +#elif (defined __GNUC__) && (__SIZEOF_LONG__ == 8) + if(x <= 1) + return 0; + return 64 - __buildin_clzl(x - 1); +#elif __SIZEOF_LONG__ == 8 + static const int table[64] = { + 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, + 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, + 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56, + 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63}; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + + return table[(x * 0x03f6eaf2cd271461) >> 58]; +#else + static const int table[32] = { + 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return table[(x * 0x07C4ACDD) >> 27]; +#endif +} \ No newline at end of file