1 #ifndef JEMALLOC_INTERNAL_BIT_UTIL_H 2 #define JEMALLOC_INTERNAL_BIT_UTIL_H 3 4 #include "jemalloc/internal/assert.h" 5 6 #define BIT_UTIL_INLINE static inline 7 8 /* Sanity check. */ 9 #if !defined(JEMALLOC_INTERNAL_FFSLL) || !defined(JEMALLOC_INTERNAL_FFSL) \ 10 || !defined(JEMALLOC_INTERNAL_FFS) 11 # error JEMALLOC_INTERNAL_FFS{,L,LL} should have been defined by configure 12 #endif 13 14 15 BIT_UTIL_INLINE unsigned ffs_llu(unsigned long long bitmap)16ffs_llu(unsigned long long bitmap) { 17 return JEMALLOC_INTERNAL_FFSLL(bitmap); 18 } 19 20 BIT_UTIL_INLINE unsigned ffs_lu(unsigned long bitmap)21ffs_lu(unsigned long bitmap) { 22 return JEMALLOC_INTERNAL_FFSL(bitmap); 23 } 24 25 BIT_UTIL_INLINE unsigned ffs_u(unsigned bitmap)26ffs_u(unsigned bitmap) { 27 return JEMALLOC_INTERNAL_FFS(bitmap); 28 } 29 30 BIT_UTIL_INLINE unsigned ffs_zu(size_t bitmap)31ffs_zu(size_t bitmap) { 32 #if LG_SIZEOF_PTR == LG_SIZEOF_INT 33 return ffs_u(bitmap); 34 #elif LG_SIZEOF_PTR == LG_SIZEOF_LONG 35 return ffs_lu(bitmap); 36 #elif LG_SIZEOF_PTR == LG_SIZEOF_LONG_LONG 37 return ffs_llu(bitmap); 38 #else 39 #error No implementation for size_t ffs() 40 #endif 41 } 42 43 BIT_UTIL_INLINE unsigned ffs_u64(uint64_t bitmap)44ffs_u64(uint64_t bitmap) { 45 #if LG_SIZEOF_LONG == 3 46 return ffs_lu(bitmap); 47 #elif LG_SIZEOF_LONG_LONG == 3 48 return ffs_llu(bitmap); 49 #else 50 #error No implementation for 64-bit ffs() 51 #endif 52 } 53 54 BIT_UTIL_INLINE unsigned ffs_u32(uint32_t bitmap)55ffs_u32(uint32_t bitmap) { 56 #if LG_SIZEOF_INT == 2 57 return ffs_u(bitmap); 58 #else 59 #error No implementation for 32-bit ffs() 60 #endif 61 return ffs_u(bitmap); 62 } 63 64 BIT_UTIL_INLINE uint64_t pow2_ceil_u64(uint64_t x)65pow2_ceil_u64(uint64_t x) { 66 x--; 67 x |= x >> 1; 68 x |= x >> 2; 69 x |= x >> 4; 70 x |= x >> 8; 71 x |= x >> 16; 72 x |= x >> 32; 73 x++; 74 return x; 75 } 76 77 BIT_UTIL_INLINE uint32_t pow2_ceil_u32(uint32_t x)78pow2_ceil_u32(uint32_t x) { 79 x--; 80 x |= x >> 1; 81 x |= x >> 2; 82 x |= x >> 4; 83 x |= x >> 8; 84 x |= x >> 16; 85 x++; 86 return x; 87 } 88 89 /* Compute the smallest power of 2 that is >= x. */ 90 BIT_UTIL_INLINE size_t pow2_ceil_zu(size_t x)91pow2_ceil_zu(size_t x) { 92 #if (LG_SIZEOF_PTR == 3) 93 return pow2_ceil_u64(x); 94 #else 95 return pow2_ceil_u32(x); 96 #endif 97 } 98 99 #if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) 100 BIT_UTIL_INLINE unsigned lg_floor(size_t x)101lg_floor(size_t x) { 102 size_t ret; 103 assert(x != 0); 104 105 asm ("bsr %1, %0" 106 : "=r"(ret) // Outputs. 107 : "r"(x) // Inputs. 108 ); 109 assert(ret < UINT_MAX); 110 return (unsigned)ret; 111 } 112 #elif (defined(_MSC_VER)) 113 BIT_UTIL_INLINE unsigned lg_floor(size_t x)114lg_floor(size_t x) { 115 unsigned long ret; 116 117 assert(x != 0); 118 119 #if (LG_SIZEOF_PTR == 3) 120 _BitScanReverse64(&ret, x); 121 #elif (LG_SIZEOF_PTR == 2) 122 _BitScanReverse(&ret, x); 123 #else 124 # error "Unsupported type size for lg_floor()" 125 #endif 126 assert(ret < UINT_MAX); 127 return (unsigned)ret; 128 } 129 #elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ)) 130 BIT_UTIL_INLINE unsigned lg_floor(size_t x)131lg_floor(size_t x) { 132 assert(x != 0); 133 134 #if (LG_SIZEOF_PTR == LG_SIZEOF_INT) 135 return ((8 << LG_SIZEOF_PTR) - 1) - __builtin_clz(x); 136 #elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG) 137 return ((8 << LG_SIZEOF_PTR) - 1) - __builtin_clzl(x); 138 #else 139 # error "Unsupported type size for lg_floor()" 140 #endif 141 } 142 #else 143 BIT_UTIL_INLINE unsigned lg_floor(size_t x)144lg_floor(size_t x) { 145 assert(x != 0); 146 147 x |= (x >> 1); 148 x |= (x >> 2); 149 x |= (x >> 4); 150 x |= (x >> 8); 151 x |= (x >> 16); 152 #if (LG_SIZEOF_PTR == 3) 153 x |= (x >> 32); 154 #endif 155 if (x == SIZE_T_MAX) { 156 return (8 << LG_SIZEOF_PTR) - 1; 157 } 158 x++; 159 return ffs_zu(x) - 2; 160 } 161 #endif 162 163 #undef BIT_UTIL_INLINE 164 165 #endif /* JEMALLOC_INTERNAL_BIT_UTIL_H */ 166