// twheel_bitops.c — ctz/clz for timing wheel (included by twheel.c) #include #if defined(__GNUC__) && !defined(TWHEEL_DISABLE_GNUC_BITOPS) #define ctz64(n) __builtin_ctzll(n) #define clz64(n) __builtin_clzll(n) #if LONG_BITS == 32 #define ctz32(n) __builtin_ctzl(n) #define clz32(n) __builtin_clzl(n) #else #define ctz32(n) __builtin_ctz(n) #define clz32(n) __builtin_clz(n) #endif #elif defined(_MSC_VER) && !defined(TWHEEL_DISABLE_MSVC_BITOPS) #include static __inline int ctz32(unsigned long val) { DWORD z=0; _BitScanForward(&z,val); return z; } static __inline int clz32(unsigned long val) { DWORD z=0; _BitScanReverse(&z,val); return z; } #ifdef _WIN64 static __inline int ctz64(uint64_t val) { DWORD z=0; _BitScanForward64(&z,val); return z; } static __inline int clz64(uint64_t val) { DWORD z=0; _BitScanReverse64(&z,val); return z; } #else static __inline int ctz64(uint64_t val) { uint32_t lo=(uint32_t)val,hi=(uint32_t)(val>>32); return lo?ctz32(lo):32+ctz32(hi); } static __inline int clz64(uint64_t val) { uint32_t lo=(uint32_t)val,hi=(uint32_t)(val>>32); return hi?clz32(hi):32+clz32(lo); } #endif #else #define process_(one, cz_bits, bits) if (x < ( one << (cz_bits - bits))) { rv += bits; x <<= bits; } static inline int clz64(uint64_t x) { int rv=0; process_(UINT64_C(1),64,32); process_(UINT64_C(1),64,16); process_(UINT64_C(1),64,8); process_(UINT64_C(1),64,4); process_(UINT64_C(1),64,2); process_(UINT64_C(1),64,1); return rv; } static inline int clz32(uint32_t x) { int rv=0; process_(UINT32_C(1),32,16); process_(UINT32_C(1),32,8); process_(UINT32_C(1),32,4); process_(UINT32_C(1),32,2); process_(UINT32_C(1),32,1); return rv; } #undef process_ #define process_(one, bits) if ((x & ((one << (bits))-1)) == 0) { rv += bits; x >>= bits; } static inline int ctz64(uint64_t x) { int rv=0; process_(UINT64_C(1),32); process_(UINT64_C(1),16); process_(UINT64_C(1),8); process_(UINT64_C(1),4); process_(UINT64_C(1),2); process_(UINT64_C(1),1); return rv; } static inline int ctz32(uint32_t x) { int rv=0; process_(UINT32_C(1),16); process_(UINT32_C(1),8); process_(UINT32_C(1),4); process_(UINT32_C(1),2); process_(UINT32_C(1),1); return rv; } #undef process_ #endif