[164] | 1 | #ifndef INCLUDED_tlsfbits
|
---|
| 2 | #define INCLUDED_tlsfbits
|
---|
| 3 |
|
---|
| 4 | #if defined(__cplusplus)
|
---|
| 5 | #define tlsf_decl inline
|
---|
| 6 | #else
|
---|
| 7 | #define tlsf_decl static
|
---|
| 8 | #endif
|
---|
| 9 |
|
---|
| 10 | /*
|
---|
| 11 | ** Architecture-specific bit manipulation routines.
|
---|
| 12 | **
|
---|
| 13 | ** TLSF achieves O(1) cost for malloc and free operations by limiting
|
---|
| 14 | ** the search for a free block to a free list of guaranteed size
|
---|
| 15 | ** adequate to fulfill the request, combined with efficient free list
|
---|
| 16 | ** queries using bitmasks and architecture-specific bit-manipulation
|
---|
| 17 | ** routines.
|
---|
| 18 | **
|
---|
| 19 | ** Most modern processors provide instructions to count leading zeroes
|
---|
| 20 | ** in a word, find the lowest and highest set bit, etc. These
|
---|
| 21 | ** specific implementations will be used when available, falling back
|
---|
| 22 | ** to a reasonably efficient generic implementation.
|
---|
| 23 | **
|
---|
| 24 | ** NOTE: TLSF spec relies on ffs/fls returning value 0..31.
|
---|
| 25 | ** ffs/fls return 1-32 by default, returning 0 for error.
|
---|
| 26 | */
|
---|
| 27 |
|
---|
| 28 | /*
|
---|
| 29 | ** Detect whether or not we are building for a 32- or 64-bit (LP/LLP)
|
---|
| 30 | ** architecture. There is no reliable portable method at compile-time.
|
---|
| 31 | */
|
---|
| 32 | #if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \
|
---|
| 33 | || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__)
|
---|
| 34 | #define TLSF_64BIT
|
---|
| 35 | #endif
|
---|
| 36 |
|
---|
| 37 | /*
|
---|
| 38 | ** gcc 3.4 and above have builtin support, specialized for architecture.
|
---|
| 39 | ** Some compilers masquerade as gcc; patchlevel test filters them out.
|
---|
| 40 | */
|
---|
| 41 | #if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
|
---|
| 42 | && defined (__GNUC_PATCHLEVEL__)
|
---|
| 43 |
|
---|
| 44 | tlsf_decl int tlsf_ffs(unsigned int word)
|
---|
| 45 | {
|
---|
| 46 | return __builtin_ffs(word) - 1;
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | tlsf_decl int tlsf_fls(unsigned int word)
|
---|
| 50 | {
|
---|
| 51 | const int bit = word ? 32 - __builtin_clz(word) : 0;
|
---|
| 52 | return bit - 1;
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | #elif defined (_MSC_VER) && (_MSC_VER >= 1400) && (defined (_M_IX86) || defined (_M_X64))
|
---|
| 56 | /* Microsoft Visual C++ support on x86/X64 architectures. */
|
---|
| 57 |
|
---|
| 58 | #include <intrin.h>
|
---|
| 59 |
|
---|
| 60 | #pragma intrinsic(_BitScanReverse)
|
---|
| 61 | #pragma intrinsic(_BitScanForward)
|
---|
| 62 |
|
---|
| 63 | tlsf_decl int tlsf_fls(unsigned int word)
|
---|
| 64 | {
|
---|
| 65 | unsigned long index;
|
---|
| 66 | return _BitScanReverse(&index, word) ? index : -1;
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | tlsf_decl int tlsf_ffs(unsigned int word)
|
---|
| 70 | {
|
---|
| 71 | unsigned long index;
|
---|
| 72 | return _BitScanForward(&index, word) ? index : -1;
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | #elif defined (_MSC_VER) && defined (_M_PPC)
|
---|
| 76 | /* Microsoft Visual C++ support on PowerPC architectures. */
|
---|
| 77 |
|
---|
| 78 | #include <ppcintrinsics.h>
|
---|
| 79 |
|
---|
| 80 | tlsf_decl int tlsf_fls(unsigned int word)
|
---|
| 81 | {
|
---|
| 82 | const int bit = 32 - _CountLeadingZeros(word);
|
---|
| 83 | return bit - 1;
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | tlsf_decl int tlsf_ffs(unsigned int word)
|
---|
| 87 | {
|
---|
| 88 | const unsigned int reverse = word & (~word + 1);
|
---|
| 89 | const int bit = 32 - _CountLeadingZeros(reverse);
|
---|
| 90 | return bit - 1;
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 | #elif defined (__ARMCC_VERSION)
|
---|
| 94 | /* RealView Compilation Tools for ARM */
|
---|
| 95 |
|
---|
| 96 | tlsf_decl int tlsf_ffs(unsigned int word)
|
---|
| 97 | {
|
---|
| 98 | const unsigned int reverse = word & (~word + 1);
|
---|
| 99 | const int bit = 32 - __clz(reverse);
|
---|
| 100 | return bit - 1;
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | tlsf_decl int tlsf_fls(unsigned int word)
|
---|
| 104 | {
|
---|
| 105 | const int bit = word ? 32 - __clz(word) : 0;
|
---|
| 106 | return bit - 1;
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | #elif defined (__ghs__)
|
---|
| 110 | /* Green Hills support for PowerPC */
|
---|
| 111 |
|
---|
| 112 | #include <ppc_ghs.h>
|
---|
| 113 |
|
---|
| 114 | tlsf_decl int tlsf_ffs(unsigned int word)
|
---|
| 115 | {
|
---|
| 116 | const unsigned int reverse = word & (~word + 1);
|
---|
| 117 | const int bit = 32 - __CLZ32(reverse);
|
---|
| 118 | return bit - 1;
|
---|
| 119 | }
|
---|
| 120 |
|
---|
| 121 | tlsf_decl int tlsf_fls(unsigned int word)
|
---|
| 122 | {
|
---|
| 123 | const int bit = word ? 32 - __CLZ32(word) : 0;
|
---|
| 124 | return bit - 1;
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | #else
|
---|
| 128 | /* Fall back to generic implementation. */
|
---|
| 129 |
|
---|
| 130 | tlsf_decl int tlsf_fls_generic(unsigned int word)
|
---|
| 131 | {
|
---|
| 132 | int bit = 32;
|
---|
| 133 |
|
---|
| 134 | if (!word) bit -= 1;
|
---|
| 135 | if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; }
|
---|
| 136 | if (!(word & 0xff000000)) { word <<= 8; bit -= 8; }
|
---|
| 137 | if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; }
|
---|
| 138 | if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; }
|
---|
| 139 | if (!(word & 0x80000000)) { word <<= 1; bit -= 1; }
|
---|
| 140 |
|
---|
| 141 | return bit;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | /* Implement ffs in terms of fls. */
|
---|
| 145 | tlsf_decl int tlsf_ffs(unsigned int word)
|
---|
| 146 | {
|
---|
| 147 | return tlsf_fls_generic(word & (~word + 1)) - 1;
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | tlsf_decl int tlsf_fls(unsigned int word)
|
---|
| 151 | {
|
---|
| 152 | return tlsf_fls_generic(word) - 1;
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | #endif
|
---|
| 156 |
|
---|
| 157 | /* Possibly 64-bit version of tlsf_fls. */
|
---|
| 158 | #if defined (TLSF_64BIT)
|
---|
| 159 | tlsf_decl int tlsf_fls_sizet(size_t size)
|
---|
| 160 | {
|
---|
| 161 | int high = (int)(size >> 32);
|
---|
| 162 | int bits = 0;
|
---|
| 163 | if (high)
|
---|
| 164 | {
|
---|
| 165 | bits = 32 + tlsf_fls(high);
|
---|
| 166 | }
|
---|
| 167 | else
|
---|
| 168 | {
|
---|
| 169 | bits = tlsf_fls((int)size & 0xffffffff);
|
---|
| 170 |
|
---|
| 171 | }
|
---|
| 172 | return bits;
|
---|
| 173 | }
|
---|
| 174 | #else
|
---|
| 175 | #define tlsf_fls_sizet tlsf_fls
|
---|
| 176 | #endif
|
---|
| 177 |
|
---|
| 178 | #undef tlsf_decl
|
---|
| 179 |
|
---|
| 180 | #endif
|
---|