X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Futil.h;h=bff6153a8daf354f8325394db035789be4d6f57b;hb=4c21aa063fa1c7f95800c95fafebedcd577ce674;hp=7c5eacbd89c73c965426db33198757301682ef9c;hpb=c3cc4d2dd265823828d93278b5d1ead4faad85ba;p=sliver-openvswitch.git diff --git a/lib/util.h b/lib/util.h index 7c5eacbd8..bff6153a8 100644 --- a/lib/util.h +++ b/lib/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #ifndef UTIL_H #define UTIL_H 1 +#include #include #include #include @@ -111,6 +112,9 @@ extern const char *program_name; /* Returns X rounded up to the nearest multiple of Y. */ #define ROUND_UP(X, Y) (DIV_ROUND_UP(X, Y) * (Y)) +/* Returns the least number that, when added to X, yields a multiple of Y. */ +#define PAD_SIZE(X, Y) (ROUND_UP(X, Y) - (X)) + /* Returns X rounded down to the nearest multiple of Y. */ #define ROUND_DOWN(X, Y) ((X) / (Y) * (Y)) @@ -142,6 +146,11 @@ is_pow2(uintmax_t x) #define RDP2_4(X) (RDP2_5(X) | (RDP2_5(X) >> 2)) #define RDP2_5(X) ( (X) | ( (X) >> 1)) +/* This system's cache line size, in bytes. + * Being wrong hurts performance but not correctness. */ +#define CACHE_LINE_SIZE 64 +BUILD_ASSERT_DECL(IS_POW2(CACHE_LINE_SIZE)); + #ifndef MIN #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #endif @@ -150,7 +159,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". * @@ -256,6 +265,10 @@ char *xasprintf(const char *format, ...) PRINTF_FORMAT(1, 2) MALLOC_LIKE; char *xvasprintf(const char *format, va_list) PRINTF_FORMAT(1, 0) MALLOC_LIKE; void *x2nrealloc(void *p, size_t *n, size_t s); +void *xmalloc_cacheline(size_t) MALLOC_LIKE; +void *xzalloc_cacheline(size_t) MALLOC_LIKE; +void free_cacheline(void *); + void ovs_strlcpy(char *dst, const char *src, size_t size); void ovs_strzcpy(char *dst, const char *src, size_t size); @@ -278,10 +291,8 @@ 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); +bool ovs_scan(const char *s, const char *format, ...) SCANF_FORMAT(2, 3); bool str_to_double(const char *, double *); @@ -295,7 +306,6 @@ char *dir_name(const char *file_name); char *base_name(const char *file_name); char *abs_file_name(const char *dir, const char *file_name); -char *xreadlink(const char *filename); char *follow_symlinks(const char *filename); void ignore(bool x OVS_UNUSED); @@ -371,48 +381,55 @@ log_2_ceil(uint64_t n) return log_2_floor(n) + !is_pow2(n); } -/* Returns the number of 1-bits in 'x', between 0 and 32 inclusive. */ +/* 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) +count_1bits_32__(uint32_t x) { -#if __GNUC__ >= 4 && defined(__corei7) - /* __builtin_popcount() is fast only when supported by the CPU. */ return __builtin_popcount(x); +} #else - extern const uint8_t count_1bits_8[256]; +#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 } - -/* Returns the number of 1-bits in 'x', between 0 and 64 inclusive. */ +#endif static inline unsigned int count_1bits(uint64_t x) { - if (sizeof(void *) == 8) { /* 64-bit CPU */ -#if __GNUC__ >= 4 && defined(__corei7) - /* __builtin_popcountll() is fast only when supported by the CPU. */ - 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 { /* 32-bit CPU */ - return count_1bits_32(x) + count_1bits_32(x >> 32); - } + 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. */ @@ -468,6 +485,14 @@ void bitwise_put(uint64_t value, uint64_t bitwise_get(const void *src, unsigned int src_len, unsigned int src_ofs, unsigned int n_bits); +void xsleep(unsigned int seconds); +#ifdef _WIN32 + +char *ovs_format_message(int error); +char *ovs_lasterror_to_string(void); +int ftruncate(int fd, off_t length); +#endif + #ifdef __cplusplus } #endif