2018-08-22 19:30:06 +08:00
|
|
|
/*
|
|
|
|
|
* @file tfe_utils.h
|
|
|
|
|
* This file provides common usage marcos and helper functions.
|
|
|
|
|
*/
|
2018-08-21 16:11:50 +08:00
|
|
|
|
2018-08-22 19:30:06 +08:00
|
|
|
#pragma once
|
|
|
|
|
#include <MESA/MESA_handle_logger.h>
|
2018-10-18 12:13:41 +08:00
|
|
|
#include <time.h>
|
2018-08-22 19:30:06 +08:00
|
|
|
|
2018-08-30 15:53:41 +08:00
|
|
|
#define TFE_STRING_MAX 2048
|
2018-10-05 18:30:58 +08:00
|
|
|
#define TFE_PATH_MAX 256
|
2018-08-30 15:53:41 +08:00
|
|
|
#define TFE_SYMBOL_MAX 64
|
|
|
|
|
#define TFE_THREAD_MAX 128
|
2018-08-22 19:30:06 +08:00
|
|
|
|
|
|
|
|
#ifndef TFE_CONFIG_BACKLOG_DEFAULT
|
|
|
|
|
#define TFE_CONFIG_BACKLOG_DEFAULT 20
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define ALLOC(type, number) ((type *)calloc(sizeof(type), number))
|
2018-09-14 16:33:36 +08:00
|
|
|
#define FREE(p) {free(*p);*p=NULL;}
|
2018-08-21 16:11:50 +08:00
|
|
|
|
2018-08-27 21:10:45 +08:00
|
|
|
#define TFE_STRUCT_ALLOC(struct_type) __extension__ \
|
|
|
|
|
({ \
|
|
|
|
|
((struct_type) * ) __struct_ptr; \
|
|
|
|
|
__struct_ptr = ((struct_type) *)malloc(sizeof((struct_type))); \
|
|
|
|
|
__struct_ptr; \
|
|
|
|
|
})
|
|
|
|
|
|
2018-08-21 16:11:50 +08:00
|
|
|
#define likely(expr) __builtin_expect((expr), 1)
|
|
|
|
|
#define unlikely(expr) __builtin_expect((expr), 0)
|
|
|
|
|
|
2018-08-22 19:30:06 +08:00
|
|
|
#define TFE_LOG_ERROR(handler, fmt, ...) \
|
2018-08-30 15:53:41 +08:00
|
|
|
do { fprintf(stderr, fmt "\n" , ##__VA_ARGS__); \
|
|
|
|
|
MESA_handle_runtime_log(handler, RLOG_LV_FATAL, "tfe", fmt, ##__VA_ARGS__); } while(0)
|
2018-08-22 19:30:06 +08:00
|
|
|
|
|
|
|
|
#define TFE_LOG_INFO(handler, fmt, ...) \
|
2018-08-30 15:53:41 +08:00
|
|
|
do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
|
|
|
|
|
MESA_handle_runtime_log(handler, RLOG_LV_INFO, "tfe", fmt, ##__VA_ARGS__); } while(0) \
|
2018-08-22 19:30:06 +08:00
|
|
|
|
|
|
|
|
#define TFE_LOG_DEBUG(handler, fmt, ...) \
|
2018-08-30 15:53:41 +08:00
|
|
|
do { MESA_handle_runtime_log(handler, RLOG_LV_DEBUG, "tfe", fmt, ##__VA_ARGS__); } while(0) \
|
|
|
|
|
|
2018-10-19 19:50:27 +08:00
|
|
|
#define CHECK_OR_EXIT(condition, fmt, ...) \
|
|
|
|
|
do { if(!(condition)) { TFE_LOG_ERROR(g_default_logger, fmt, ##__VA_ARGS__); exit(EXIT_FAILURE); } } while(0) \
|
|
|
|
|
|
|
|
|
|
#define CHECK_OR_DIE(condition, fmt, ...) \
|
|
|
|
|
do { if(!(condition)) { TFE_LOG_ERROR(g_default_logger, fmt, ##__VA_ARGS__); abort(); } } while(0) \
|
|
|
|
|
|
2018-08-30 15:53:41 +08:00
|
|
|
#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, ...)
|
2018-08-22 19:30:06 +08:00
|
|
|
|
2018-08-27 21:10:45 +08:00
|
|
|
#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
|
|
|
|
|
|
2018-10-17 20:21:21 +08:00
|
|
|
#define ATOMIC_INC(x) __atomic_fetch_add(x,1,__ATOMIC_RELAXED)
|
|
|
|
|
#define ATOMIC_DEC(x) __atomic_fetch_sub(x,1,__ATOMIC_RELAXED)
|
|
|
|
|
#define ATOMIC_READ(x) __atomic_fetch_add(x,0,__ATOMIC_RELAXED)
|
|
|
|
|
#define ATOMIC_ADD(x, y) __atomic_fetch_add(x,y,__ATOMIC_RELAXED)
|
2018-09-06 10:12:08 +08:00
|
|
|
|
2018-09-14 18:43:28 +08:00
|
|
|
|
|
|
|
|
#ifndef MAX
|
|
|
|
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef MIN
|
|
|
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
2018-08-21 16:11:50 +08:00
|
|
|
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);
|
2018-10-18 12:13:41 +08:00
|
|
|
char *tfe_thread_safe_ctime(const time_t *tp, char *buf, int len);
|
2018-09-06 10:12:08 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#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]))
|
2018-09-07 17:27:23 +08:00
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
2018-10-05 21:34:57 +08:00
|
|
|
static inline void tfe_hexdump2file(FILE *f, const char * title, const void * buf, unsigned int len)
|
2018-09-07 17:27:23 +08:00
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
}
|
2018-10-05 21:34:57 +08:00
|
|
|
static inline unsigned char* tfe_hexdump(unsigned char *dst, unsigned char *src, size_t len)
|
|
|
|
|
{
|
|
|
|
|
static unsigned char hex[] = "0123456789abcdef";
|
|
|
|
|
|
|
|
|
|
while (len--) {
|
|
|
|
|
*dst++ = hex[*src >> 4];
|
|
|
|
|
*dst++ = hex[*src++ & 0xf];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|