diff --git a/tlsf.c b/tlsf.c index af575737c7..c32ef875d0 100644 --- a/tlsf.c +++ b/tlsf.c @@ -40,6 +40,29 @@ #define TLSF_64BIT #endif +/* +** Returns one plus the index of the most significant 1-bit of n, +** or if n is zero, returns zero. +*/ +#ifdef TLSF_64BIT +#define TLSF_FLS(n) ((n) & 0xffffffff00000000ull ? 32 + TLSF_FLS32((size_t)(n) >> 32) : TLSF_FLS32(n)) +#else +#define TLSF_FLS(n) TLSF_FLS32(n) +#endif + +#define TLSF_FLS32(n) ((n) & 0xffff0000 ? 16 + TLSF_FLS16((n) >> 16) : TLSF_FLS16(n)) +#define TLSF_FLS16(n) ((n) & 0xff00 ? 8 + TLSF_FLS8 ((n) >> 8) : TLSF_FLS8 (n)) +#define TLSF_FLS8(n) ((n) & 0xf0 ? 4 + TLSF_FLS4 ((n) >> 4) : TLSF_FLS4 (n)) +#define TLSF_FLS4(n) ((n) & 0xc ? 2 + TLSF_FLS2 ((n) >> 2) : TLSF_FLS2 (n)) +#define TLSF_FLS2(n) ((n) & 0x2 ? 1 + TLSF_FLS1 ((n) >> 1) : TLSF_FLS1 (n)) +#define TLSF_FLS1(n) ((n) & 0x1 ? 1 : 0) + +/* +** Returns round up value of log2(n). +** Note: it is used at compile time. +*/ +#define TLSF_LOG2_CEIL(n) ((n) & (n - 1) ? TLSF_FLS(n) : TLSF_FLS(n) - 1) + /* ** gcc 3.4 and above have builtin support, specialized for architecture. ** Some compilers masquerade as gcc; patchlevel test filters them out. @@ -147,29 +170,16 @@ tlsf_decl int tlsf_fls(unsigned int word) #else /* Fall back to generic implementation. */ -tlsf_decl int tlsf_fls_generic(unsigned int word) -{ - int bit = 32; - - if (!word) bit -= 1; - if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; } - if (!(word & 0xff000000)) { word <<= 8; bit -= 8; } - if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; } - if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; } - if (!(word & 0x80000000)) { word <<= 1; bit -= 1; } - - return bit; -} - /* Implement ffs in terms of fls. */ tlsf_decl int tlsf_ffs(unsigned int word) { - return tlsf_fls_generic(word & (~word + 1)) - 1; + const unsigned int reverse = word & (~word + 1); + return TLSF_FLS32(reverse) - 1; } tlsf_decl int tlsf_fls(unsigned int word) { - return tlsf_fls_generic(word) - 1; + return TLSF_FLS32(word) - 1; } #endif @@ -234,7 +244,9 @@ enum tlsf_private ** blocks below that size into the 0th first-level list. */ -#if defined (TLSF_64BIT) +#if defined (TLSF_MAX_POOL_SIZE) + FL_INDEX_MAX = TLSF_LOG2_CEIL(TLSF_MAX_POOL_SIZE), +#elif defined (TLSF_64BIT) /* ** TODO: We can increase this to support larger sizes, at the expense ** of more overhead in the TLSF structure.