diff options
| author | root <root> | 2011-06-17 18:55:42 +0000 | 
|---|---|---|
| committer | root <root> | 2011-06-17 18:55:42 +0000 | 
| commit | 12aa2cfa32f0275b0a6249330af90ea6b2d44d56 (patch) | |
| tree | 2a1bc43862bf3b86f07292b7068ef4abcca38fbe | |
| parent | 06ed79f5b01b509d7d3003922ca91714c7f3e083 (diff) | |
*** empty log message ***
| -rw-r--r-- | ecb.h | 319 | ||||
| -rw-r--r-- | eio.c | 4 | 
2 files changed, 217 insertions, 106 deletions
| @@ -30,7 +30,23 @@  #ifndef ECB_H  #define ECB_H -#include <inttypes.h> +#ifdef _WIN32 +  typedef   signed char   int8_t; +  typedef unsigned char  uint8_t; +  typedef   signed short  int16_t; +  typedef unsigned short uint16_t; +  typedef   signed int    int32_t; +  typedef unsigned int   uint32_t; +  #if __GNUC__ +    typedef   signed long long int64_t; +    typedef unsigned long long uint64_t; +  #else +    typedef   signed __int64   int64_t; +    typedef unsigned __int64   uint64_t; +  #endif +#else +  #include <inttypes.h> +#endif  /* many compilers define _GNUC_ to some versions but then only implement   * what their idiot authors think are the "more important" extensions, @@ -40,182 +56,277 @@   * an issue with that they should have done it right in the first place.   */  #ifndef ECB_GCC_VERSION -# if defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__llvm__) -#  define ECB_GCC_VERSION(major,minor) 0 -# else -#  define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) -# endif +  #if !defined(__GNUC_MINOR__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__llvm__) || defined(__clang__) +    #define ECB_GCC_VERSION(major,minor) 0 +  #else +    #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +  #endif  #endif -#ifndef __cplusplus -# if __STDC_VERSION__ >= 199901L -#  define ECB_INLINE static inline -typedef _Bool ecb_bool; -# else -#  define ECB_INLINE static inline /* yeah! */ -typedef int ecb_bool; -# endif +#define ECB_C99 (__STDC_VERSION__ >= 199901L) + +#if __cplusplus +  #define ecb_inline static inline +#elif ECB_GCC_VERSION(2,5) +  #define ecb_inline static __inline__ +#elif ECB_C99 +  #define ecb_inline static inline +#else +  #define ecb_inline static +#endif + +#if ECB_GCC_VERSION(3,3) +  #define ecb_restrict __restrict__ +#elif ECB_C99 +  #define ecb_restrict restrict  #else -# define ECB_INLINE static inline -typedef bool ecb_bool; +  #define ecb_restrict  #endif +typedef int ecb_bool; +  #define ECB_CONCAT_(a, b) a ## b  #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)  #define ECB_STRINGIFY_(a) # a  #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a) -#define ECB_HEADER_INLINE ECB_INLINE +#define ecb_function_ ecb_inline  #if ECB_GCC_VERSION(3,1) -# define ecb_attribute(attrlist)        __attribute__(attrlist) -# define ecb_is_constant(expr)          __builtin_constant_p (expr) -# define ecb_expect(expr,value)         __builtin_expect ((expr),(value)) -# define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) +  #define ecb_attribute(attrlist)        __attribute__(attrlist) +  #define ecb_is_constant(expr)          __builtin_constant_p (expr) +  #define ecb_expect(expr,value)         __builtin_expect ((expr),(value)) +  #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)  #else -# define ecb_attribute(attrlist) -# define ecb_is_constant(expr)          0 -# define ecb_expect(expr,value)         (expr) -# define ecb_prefetch(addr,rw,locality) +  #define ecb_attribute(attrlist) +  #define ecb_is_constant(expr)          0 +  #define ecb_expect(expr,value)         (expr) +  #define ecb_prefetch(addr,rw,locality)  #endif  /* no emulation for ecb_decltype */  #if ECB_GCC_VERSION(4,5) -# define ecb_decltype(x) __decltype(x) +  #define ecb_decltype(x) __decltype(x)  #elif ECB_GCC_VERSION(3,0) -# define ecb_decltype(x) typeof(x) +  #define ecb_decltype(x) __typeof(x)  #endif -#define ecb_artificial ecb_attribute ((__artificial__)) /* 4.3 */  #define ecb_noinline   ecb_attribute ((__noinline__))  #define ecb_noreturn   ecb_attribute ((__noreturn__))  #define ecb_unused     ecb_attribute ((__unused__))  #define ecb_const      ecb_attribute ((__const__))  #define ecb_pure       ecb_attribute ((__pure__)) -#define ecb_hot        ecb_attribute ((__hot__))	/* 4.3 */ -#define ecb_cold       ecb_attribute ((__cold__))	/* 4.3 */ -/* put into if's if you are very sure that the expression */ -/* is mostly true or mostly false. note that these return */ -/* booleans, not the expression. */ +#if ECB_GCC_VERSION(4,3) +  #define ecb_artificial ecb_attribute ((__artificial__)) +  #define ecb_hot        ecb_attribute ((__hot__)) +  #define ecb_cold       ecb_attribute ((__cold__)) +#else +  #define ecb_artificial +  #define ecb_hot +  #define ecb_cold +#endif + +/* put around conditional expressions if you are very sure that the  */ +/* expression is mostly true or mostly false. note that these return */ +/* booleans, not the expression.                                     */  #define ecb_expect_false(expr) ecb_expect (!!(expr), 0)  #define ecb_expect_true(expr)  ecb_expect (!!(expr), 1) +/* for compatibility to the rest of the world */  #define ecb_likely(expr)   ecb_expect_true  (expr)  #define ecb_unlikely(expr) ecb_expect_false (expr) -/* try to tell the compiler that some condition is definitely true */ -#define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0) -  /* count trailing zero bits and count # of one bits */  #if ECB_GCC_VERSION(3,4) -#define ecb_ctz32(x)      __builtin_ctz      (x) -#define ecb_popcount32(x) __builtin_popcount (x) +  /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */ +  #define ecb_ld32(x)      (__builtin_clz      (x) ^ 31) +  #define ecb_ld64(x)      (__builtin_clzll    (x) ^ 63) +  #define ecb_ctz32(x)      __builtin_ctz      (x) +  #define ecb_ctz64(x)      __builtin_ctzll    (x) +  #define ecb_popcount32(x) __builtin_popcount (x) +  /* no popcountll */  #else -ECB_HEADER_INLINE int ecb_ctz32 (uint32_t x) ecb_const; -ECB_HEADER_INLINE int -ecb_ctz32 (uint32_t x) -{ -  int r = 0; +  ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const; +  ecb_function_ int +  ecb_ctz32 (uint32_t x) +  { +    int r = 0; -  x &= -x; /* this isolates the lowest bit */ +    x &= ~x + 1; /* this isolates the lowest bit */ -  if (x & 0xaaaaaaaa) r +=  1; -  if (x & 0xcccccccc) r +=  2; -  if (x & 0xf0f0f0f0) r +=  4; -  if (x & 0xff00ff00) r +=  8; -  if (x & 0xffff0000) r += 16; +    if (x & 0xaaaaaaaa) r +=  1; +    if (x & 0xcccccccc) r +=  2; +    if (x & 0xf0f0f0f0) r +=  4; +    if (x & 0xff00ff00) r +=  8; +    if (x & 0xffff0000) r += 16; -  return r; -} +    return r; +  } -ECB_HEADER_INLINE int ecb_popcount32 (uint32_t x) ecb_const; -ECB_HEADER_INLINE int -ecb_popcount32 (uint32_t x) -{ -  x -=  (x >> 1) & 0x55555555; -  x  = ((x >> 2) & 0x33333333) + (x & 0x33333333); -  x  = ((x >> 4) + x) & 0x0f0f0f0f; -  x *= 0x01010101; +  ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const; +  ecb_function_ int +  ecb_ctz64 (uint64_t x) +  { +    int shift = x & 0xffffffffU ? 0 : 32; +    return ecb_ctz (x >> shift) + shift; +  } -  return x >> 24; -} +  ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const; +  ecb_function_ int +  ecb_popcount32 (uint32_t x) +  { +    x -=  (x >> 1) & 0x55555555; +    x  = ((x >> 2) & 0x33333333) + (x & 0x33333333); +    x  = ((x >> 4) + x) & 0x0f0f0f0f; +    x *= 0x01010101; + +    return x >> 24; +  } + +  /* you have the choice beetween something with a table lookup, */ +  /* something using lots of bit arithmetic and a simple loop */ +  /* we went for the loop */ +  ecb_function_ int ecb_ld32 (uint32_t x) ecb_const; +  ecb_function_ int ecb_ld32 (uint32_t x) +  { +    int r = -1; + +    do +      { +        x >>= 1; +        ++r; +      } +    while (x); + +    return r; +  } + +  ecb_function_ int ecb_ld64 (uint64_t x) ecb_const; +  ecb_function_ int ecb_ld64 (uint64_t x) +  { +    int r = -1; + +    do +      { +        x >>= 1; +        ++r; +      } +    while (x); + +    return r; +  }  #endif -#if ECB_GCC_VERSION(4,3) -# define ecb_bswap32(x) __builtin_bswap32 (x) -# define ecb_bswap16(x) (__builtin_bswap32(x) >> 16) -#else -ECB_HEADER_INLINE uint32_t ecb_bswap32 (uint32_t x) ecb_const; -ECB_HEADER_INLINE uint32_t -ecb_bswap32 (uint32_t x) +/* popcount64 is only available on 64 bit cpus as gcc builtin */ +/* so for this version we are lazy */ +ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const; +ecb_function_ int +ecb_popcount64 (uint64_t x)  { -  return (x >> 24) -      | ((x >>  8) & 0x0000ff00) -      | ((x <<  8) & 0x00ff0000) -      |  (x << 24); +  return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);  } -ECB_HEADER_INLINE uint32_t ecb_bswap16 (uint32_t x) ecb_const; -ECB_HEADER_INLINE uint32_t -ecb_bswap16 (uint32_t x) -{ -  return ((x >>  8) & 0xff) -      |  ((x <<  8) & 0x00ff0000) -      |  (x << 24); -} +#if ECB_GCC_VERSION(4,3) +  #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16) +  #define ecb_bswap32(x)  __builtin_bswap32 (x) +  #define ecb_bswap64(x)  __builtin_bswap64 (x) +#else +  ecb_function_ uint32_t ecb_bswap16 (uint32_t x) ecb_const; +  ecb_function_ uint32_t +  ecb_bswap16 (uint32_t x) +  { +    return ((x >>  8) & 0xff) +        |  ((x <<  8) & 0x00ff0000) +        |  (x << 24); +  } + +  ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const; +  ecb_function_ uint32_t +  ecb_bswap32 (uint32_t x) +  { +    return (x >> 24) +        | ((x >>  8) & 0x0000ff00) +        | ((x <<  8) & 0x00ff0000) +        |  (x << 24); +  } + +  ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const; +  ecb_function_ uint64_t +  ecb_bswap64 (uint64_t x) +  { +    return (((uint64_t)ecb_bswap32 (x)) << 32) +         | ecb_bswap32 (x >> 32); +  }  #endif  #if ECB_GCC_VERSION(4,5) -# define ecb_unreachable() __builtin_unreachable () +  #define ecb_unreachable() __builtin_unreachable ()  #else -/* this seems to work fine, but gcc always emits a warning for it :/ */ -ECB_HEADER_INLINE void ecb_unreachable (void) ecb_noreturn; -ECB_HEADER_INLINE void ecb_unreachable (void) { } +  /* this seems to work fine, but gcc always emits a warning for it :/ */ +  ecb_function_ void ecb_unreachable (void) ecb_noreturn; +  ecb_function_ void ecb_unreachable (void) { }  #endif -ECB_HEADER_INLINE unsigned char ecb_byteorder_helper (void) ecb_const; -ECB_HEADER_INLINE unsigned char +/* try to tell the compiler that some condition is definitely true */ +#define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0) + +ecb_function_ unsigned char ecb_byteorder_helper (void) ecb_const; +ecb_function_ unsigned char  ecb_byteorder_helper (void)  {    const uint32_t u = 0x11223344;    return *(unsigned char *)&u;  } -ECB_HEADER_INLINE ecb_bool ecb_big_endian    (void) ecb_const; -ECB_HEADER_INLINE ecb_bool ecb_big_endian    (void) { return ecb_byteorder_helper () == 0x11; }; -ECB_HEADER_INLINE ecb_bool ecb_little_endian (void) ecb_const; -ECB_HEADER_INLINE ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }; +ecb_function_ ecb_bool ecb_big_endian    (void) ecb_const; +ecb_function_ ecb_bool ecb_big_endian    (void) { return ecb_byteorder_helper () == 0x11; } +ecb_function_ ecb_bool ecb_little_endian (void) ecb_const; +ecb_function_ ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; } -#if ECB_GCC_VERSION(3,0) -# define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) +#if ECB_GCC_VERSION(3,0) || ECB_C99 +  #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))  #else -# define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) +  #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))  #endif  #if ecb_cplusplus_does_not_suck -// does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) -template<typename T, int N> -static inline int ecb_array_length (const T (&arr)[N]) -{ -  return N; -} +  /* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */ +  template<typename T, int N> +  static inline int ecb_array_length (const T (&arr)[N]) +  { +    return N; +  }  #else -#define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) +  #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))  #endif -ECB_INLINE uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const; -ECB_INLINE uint32_t +ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const; +ecb_inline uint32_t  ecb_rotr32 (uint32_t x, unsigned int count)  {    return (x << (32 - count)) | (x >> count);  } -ECB_INLINE uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const; -ECB_INLINE uint32_t +ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const; +ecb_inline uint32_t  ecb_rotl32 (uint32_t x, unsigned int count)  {    return (x >> (32 - count)) | (x << count);  } +ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const; +ecb_inline uint64_t +ecb_rotr64 (uint64_t x, unsigned int count) +{ +  return (x << (64 - count)) | (x >> count); +} + +ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const; +ecb_inline uint64_t +ecb_rotl64 (uint64_t x, unsigned int count) +{ +  return (x >> (64 - count)) | (x << count); +} +  #endif @@ -202,7 +202,7 @@ static void eio_execute (struct etp_worker *self, eio_req *req);  #define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1)  /* calculate time difference in ~1/EIO_TICKS of a second */ -ECB_INLINE int +ecb_inline int  tvdiff (struct timeval *tv1, struct timeval *tv2)  {    return  (tv2->tv_sec  - tv1->tv_sec ) * EIO_TICKS @@ -1697,7 +1697,7 @@ eio_init (void (*want_poll)(void), void (*done_poll)(void))    return etp_init (want_poll, done_poll);  } -ECB_INLINE void +ecb_inline void  eio_api_destroy (eio_req *req)  {    free (req); | 
