/* * @file tfe_utils.h * This file provides common usage marcos and helper functions. */ #pragma once #include #define TFE_STRING_MAX 2048 #define TFE_SYMBOL_MAX 64 #define TFE_THREAD_MAX 128 #ifndef TFE_CONFIG_BACKLOG_DEFAULT #define TFE_CONFIG_BACKLOG_DEFAULT 20 #endif #define ALLOC(type, number) ((type *)calloc(sizeof(type), number)) #define FREE(p) {free(*p);*p=NULL} #define TFE_STRUCT_ALLOC(struct_type) __extension__ \ ({ \ ((struct_type) * ) __struct_ptr; \ __struct_ptr = ((struct_type) *)malloc(sizeof((struct_type))); \ __struct_ptr; \ }) #define likely(expr) __builtin_expect((expr), 1) #define unlikely(expr) __builtin_expect((expr), 0) #define TFE_LOG_ERROR(handler, fmt, ...) \ do { fprintf(stderr, fmt "\n" , ##__VA_ARGS__); \ MESA_handle_runtime_log(handler, RLOG_LV_FATAL, "tfe", fmt, ##__VA_ARGS__); } while(0) #define TFE_LOG_INFO(handler, fmt, ...) \ do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); \ MESA_handle_runtime_log(handler, RLOG_LV_INFO, "tfe", fmt, ##__VA_ARGS__); } while(0) \ #define TFE_LOG_DEBUG(handler, fmt, ...) \ do { MESA_handle_runtime_log(handler, RLOG_LV_DEBUG, "tfe", fmt, ##__VA_ARGS__); } while(0) \ #define TFE_STREAM_LOG_DEBUG(stream, fmt, ...) #define TFE_STREAM_LOG_INFO(stream, fmt, ...) #define TFE_STREAM_LOG_ERROR(stream, fmt, ...) #define TFE_STREAM_TRACE_TAG_INFO(stream, tag, fmt, ...) #define TFE_STREAM_TRACE_TAG_VERBOSE(stream, tag, fmt, ...) #ifndef offsetof /** Return the offset of a field in a structure. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) #endif /** * Return pointer to the wrapping struct instance. * * Example: * * struct wrapper { * ... * struct child c; * ... * }; * * struct child *x = obtain(...); * struct wrapper *w = container_of(x, struct wrapper, c); */ #ifndef container_of #define container_of(ptr, type, member) __extension__ ({ \ const typeof(((type *)0)->member) *_ptr = (ptr); \ __attribute__((unused)) type *_target_ptr = (type *)(ptr); \ (type *)(((uintptr_t)_ptr) - offsetof(type, member)); \ }) #endif #define ATOMIC_INC(x) __atomic_fetch_add(x,1,__ATOMIC_RELAXED) #define ATOMIC_READ(x) __atomic_fetch_add(x,0,__ATOMIC_RELAXED) int addr_sock_to_layer(struct sockaddr * sock_addr, int sockaddrlen, struct layer_addr * layer_addr); int addr_layer_to_sock(struct layer_addr * layer_addr, struct sockaddr * sock_addr); char* tfe_strdup(const char* s); #define TFE_SET_USED(x) (void)(x) #define TFE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x))) #define TFE_PTR_SUB(ptr, x) ((void*)((uintptr_t)ptr - (x))) #define TFE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2)) #define TFE_DIM(x) (sizeof (x) / sizeof ((x)[0])) #include static inline void tfe_hexdump(FILE *f, const char * title, const void * buf, unsigned int len) { unsigned int i, out, ofs; const unsigned char *data = (const unsigned char *)buf; #define LINE_LEN 80 char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */ fprintf(f, "%s at [%p], len=%u\n", (title)? title : " Dump data", data, len); ofs = 0; while (ofs < len) { /* format the line in the buffer, then use printf to output to screen */ out = snprintf(line, LINE_LEN, "%08X:", ofs); for (i = 0; ((ofs + i) < len) && (i < 16); i++) out += snprintf(line+out, LINE_LEN - out, " %02X", (data[ofs+i] & 0xff)); for(; i <= 16; i++) out += snprintf(line+out, LINE_LEN - out, " | "); for(i = 0; (ofs < len) && (i < 16); i++, ofs++) { unsigned char c = data[ofs]; if ( (c < ' ') || (c > '~')) c = '.'; out += snprintf(line+out, LINE_LEN - out, "%c", c); } fprintf(f, "%s\n", line); } fflush(f); #undef LINE_LEN }