#ifndef UC_UTILS_H_ #define UC_UTILS_H_ #include #include #include #include "backtrace.h" //Gnerate a compiler error if the compile time //constant expression fails #define UC_STATIC_ASSERT(expr) \ enum { assert_static__ = 1/(expr) }; //MAX of a and b #define UC_MAX(a,b) \ ({ __typeof__ (a) _amx = (a); \ __typeof__ (b) _bmx = (b); \ _amx > _bmx ? _amx : _bmx; }) //min of a and b #define UC_MIN(a,b) \ ({ __typeof__ (a) _amn = (a); \ __typeof__ (b) _bmn = (b); \ _amn < _bmn ? _amn : _bmn; }) #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) //given 'ptr' as a pointer to a struct 'member', //find the struct that ptr is the member of, where //'type' is the type of the containing struct //e.g. //struct foo { // int i; // struct bar zap; //}; // ... //struct bar *p = ..; //the local p is a pointer to //a 'zap' member inside a struct foo. //give us the struct foo*: //struct foo *f = CONTAINER_OF(p, struct foo, zap); #define UC_CONTAINER_OF(ptr, type, member) ({ \ typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)((void *)(unsigned char *)__mptr - offsetof(type, member) ); }) //the void* cast is to suppress alignment warnings //Same as UC_CONTAINER_OF, but for a const pointer to avoid gcc warnings.. #define UC_CONST_CONTAINER_OF(ptr, type, member) ({ \ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \ (const type *)((const void *)(const unsigned char *)__mptr - offsetof(const type, member) ); }) /** Align a value. * @param val value to align * @param align alignment, must be power of 2 * @return the aligned val */ #define UC_ALIGN(val,align) (((val)+(align)-1UL)&~((align)-1UL)) /** * Test if x is a power of 2 * * @param x value, must be an unsigned type * @return 1 if x is a power of 20, 0 if it is not */ #define UC_IS_POW2(x) ((x) && !((x) & (x) - 1)) /** * Expands @x and turns it into a string. */ #define UC_STRINGIFY(x) UC_STRINGIFY_HLP(x) #define UC_STRINGIFY_HLP(x) #x /** Macro that expands to a string for the current file:line */ #define UC_SRC_LOCATION __FILE__ ":" UC_STRINGIFY(__LINE__) /** * assert() that is not affected by NDEBUG define */ #define UC_ASSERT(expr)\ do {\ if (!(expr) ) {\ fprintf(stderr,\ "UC_ASSERT failed '%s' %s\n", UC_STRINGIFY(expr), UC_SRC_LOCATION);\ uc_backtrace_fd(2);\ abort();\ }\ } while (0) #ifdef DEBUG #define TRACEF(fmt, ...)\ do { \ fprintf(stdout, "%s (%s)\t" fmt, UC_SRC_LOCATION, __FUNCTION__, ##__VA_ARGS__);\ fflush(stdout);\ } while(0) #else #define TRACEF(fmt, ...) do {} while(0) #endif /** * Macro for asserting code that should not be reached, * terminates the program if executed */ #define UC_NOT_REACED()\ do {\ fprintf(stderr, "UC_NOT_REACED at %s\n", UC_SRC_LOCATION);\ uc_backtrace_fd(2);\ abort();\ while (0) /** * Round up x / y * (e.g 100/9 == 12, 3/2 == 2) * x + y must not overflow. * * @param x numerator, must be positive * @param y denominator * @return x/y rounded up */ #define UC_DIV_ROUND_UP(x, y) (((x) + ((y) - 1))/(y)) /** * Round x down to nearest multiple of y * * @param x numerator, must be positive * @param y denominator * @return x rounded to nearest multiple of y */ #define UC_ROUND_UP(x, y) (((x) / (y)) * (y)) /** * Round x down to nearest multiple of y * * @param x numerator, must be positive * @param y denominator * @return x rounded to nearest multiple of y */ #define UC_ROUND_DOWN(x, y) ((x) / (y) * (y)) #endif