X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=lib%2Futil.h;h=8886a5490117202af5b668c0d8e7f0b2596bf27b;hb=4b0424809b823101c969a0691fc1db0c880ae64a;hp=4f8a29100608e73e8eb405deb7c03a7db2c73e05;hpb=d578065e7d9dd70ca6a81ddbc5e4ecb763d1152e;p=sliver-openvswitch.git diff --git a/lib/util.h b/lib/util.h index 4f8a29100..8886a5490 100644 --- a/lib/util.h +++ b/lib/util.h @@ -150,7 +150,7 @@ is_pow2(uintmax_t x) #define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) #endif -#define NOT_REACHED() abort() +#define OVS_NOT_REACHED() abort() /* Expands to a string that looks like ":", e.g. "tmp.c:10". * @@ -277,11 +277,26 @@ void ovs_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii); bool str_to_int(const char *, int base, int *); bool str_to_long(const char *, int base, long *); bool str_to_llong(const char *, int base, long long *); -bool str_to_uint(const char *, int base, unsigned int *); -bool str_to_ulong(const char *, int base, unsigned long *); -bool str_to_ullong(const char *, int base, unsigned long long *); -bool ovs_scan(const char *s, const char *template, ...) SCANF_FORMAT(2, 3); +static inline bool +str_to_uint(const char *s, int base, unsigned int *u) +{ + return str_to_int(s, base, (int *) u); +} + +static inline bool +str_to_ulong(const char *s, int base, unsigned long *ul) +{ + return str_to_long(s, base, (long *) ul); +} + +static inline bool +str_to_ullong(const char *s, int base, unsigned long long *ull) +{ + return str_to_llong(s, base, (long long *) ull); +} + +bool ovs_scan(const char *s, const char *format, ...) SCANF_FORMAT(2, 3); bool str_to_double(const char *, double *); @@ -302,10 +317,6 @@ void ignore(bool x OVS_UNUSED); /* Bitwise tests. */ -int log_2_floor(uint32_t); -int log_2_ceil(uint32_t); -unsigned int count_1bits(uint64_t); - /* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ #if __GNUC__ >= 4 static inline int @@ -318,9 +329,16 @@ raw_ctz(uint64_t n) ? __builtin_ctz(n) : __builtin_ctzll(n)); } + +static inline int +raw_clz64(uint64_t n) +{ + return __builtin_clzll(n); +} #else /* Defined in util.c. */ int raw_ctz(uint64_t n); +int raw_clz64(uint64_t n); #endif /* Returns the number of trailing 0-bits in 'n', or 32 if 'n' is 0. */ @@ -337,6 +355,87 @@ ctz64(uint64_t n) return n ? raw_ctz(n) : 64; } +/* Returns the number of leading 0-bits in 'n', or 32 if 'n' is 0. */ +static inline int +clz32(uint32_t n) +{ + return n ? raw_clz64(n) - 32 : 32; +} + +/* Returns the number of leading 0-bits in 'n', or 64 if 'n' is 0. */ +static inline int +clz64(uint64_t n) +{ + return n ? raw_clz64(n) : 64; +} + +/* Given a word 'n', calculates floor(log_2('n')). This is equivalent + * to finding the bit position of the most significant one bit in 'n'. It is + * an error to call this function with 'n' == 0. */ +static inline int +log_2_floor(uint64_t n) +{ + return 63 - raw_clz64(n); +} + +/* Given a word 'n', calculates ceil(log_2('n')). It is an error to + * call this function with 'n' == 0. */ +static inline int +log_2_ceil(uint64_t n) +{ + return log_2_floor(n) + !is_pow2(n); +} + +/* unsigned int count_1bits(uint64_t x): + * + * Returns the number of 1-bits in 'x', between 0 and 64 inclusive. */ +#if UINTPTR_MAX == UINT64_MAX +static inline unsigned int +count_1bits(uint64_t x) +{ +#if __GNUC__ >= 4 && __POPCNT__ + return __builtin_popcountll(x); +#else + /* This portable implementation is the fastest one we know of for 64 + * bits, and about 3x faster than GCC 4.7 __builtin_popcountll(). */ + const uint64_t h55 = UINT64_C(0x5555555555555555); + const uint64_t h33 = UINT64_C(0x3333333333333333); + const uint64_t h0F = UINT64_C(0x0F0F0F0F0F0F0F0F); + const uint64_t h01 = UINT64_C(0x0101010101010101); + x -= (x >> 1) & h55; /* Count of each 2 bits in-place. */ + x = (x & h33) + ((x >> 2) & h33); /* Count of each 4 bits in-place. */ + x = (x + (x >> 4)) & h0F; /* Count of each 8 bits in-place. */ + return (x * h01) >> 56; /* Sum of all bytes. */ +#endif +} +#else /* Not 64-bit. */ +#if __GNUC__ >= 4 && __POPCNT__ +static inline unsigned int +count_1bits_32__(uint32_t x) +{ + return __builtin_popcount(x); +} +#else +#define NEED_COUNT_1BITS_8 1 +extern const uint8_t count_1bits_8[256]; +static inline unsigned int +count_1bits_32__(uint32_t x) +{ + /* This portable implementation is the fastest one we know of for 32 bits, + * and faster than GCC __builtin_popcount(). */ + return (count_1bits_8[x & 0xff] + + count_1bits_8[(x >> 8) & 0xff] + + count_1bits_8[(x >> 16) & 0xff] + + count_1bits_8[x >> 24]); +} +#endif +static inline unsigned int +count_1bits(uint64_t x) +{ + return count_1bits_32__(x) + count_1bits_32__(x >> 32); +} +#endif + /* Returns the rightmost 1-bit in 'x' (e.g. 01011000 => 00001000), or 0 if 'x' * is 0. */ static inline uintmax_t