123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- /*
- * category: [core for memory]
- * apply status:
- * edit status:
- * build status:
- * description: debug_trace would be invoked by stm, but stm is not used anywhere...
- *
- */
- #ifndef __MEMUTIL_H__
- #define __MEMUTIL_H__
- #pragma once
- #include "config.h"
- #ifdef _WIN32
- #define _CRTDBG_MAP_ALLOC
- #include <stdlib.h>
- #include <crtdbg.h>
- #include <WinSock2.h> //for struct timeval
- #else
- //TODO: remove #else macro.
- //because error C2039 would occur: “int8_t”: is not the member of “`global namespace'”
- #include <winpr/wtypes.h>
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
- #include <malloc.h>
- #ifdef _WIN32
- static __inline void prefetch(void* p)
- {
- _asm
- {
- //NTA(non-temporal data with respect to all cache levels) prefetch data into non-temporal cache structure and
- //into a location close to the processor, minimizing cache pollution.
- prefetchnta p
- }
- }
- #else
- //rw, locality: 1(w), 0(r), temporal locality(0-3, 3 is default)
- #define prefetch(x) __builtin_prefetch(x, 0)
- #endif
- #define INT64_GET_HIGH_PART(x) (*((int*)(&(x)) + 1))
- #define INT64_GET_LOW_PART(x) (*(int*)&(x))
- static __inline int int64_get_high_part(__int64 x)
- {
- return INT64_GET_HIGH_PART(x);
- }
- static __inline int int64_get_low_part(__int64 x)
- {
- return INT64_GET_LOW_PART(x);
- }
- struct __i8_helper {
- union {
- __int64 i;
- struct {
- int l;
- int h;
- };
- };
- };
- static __inline __int64 int64_make(int low_part, int high_part)
- {
- struct __i8_helper t;
- t.l = low_part;
- t.h = high_part;
- return t.i;
- }
- #define offset_of(type, member) \
- (((char*)(&((type*)0)->member)) - (char*)0)
- #define container_of(ptr, type, member) \
- ((type*)((char*)(ptr) - offset_of(type, member)))
- #define field_size(type, member) \
- sizeof(((type*)0)->member)
- #define array_size(x) \
- (sizeof(x)/sizeof((x)[0]))
- #define FLAG_BIT(f) f##_BIT
- /* for compatility at different platform [3/31/2020 Gifur] */
- #ifndef PARAM_SIZE_DEFINED
- #define PARAM_SIZE_DEFINED
- #ifdef _WIN32
- typedef int param_size_t;
- #else
- #if (defined(__x86_64__) || defined(__aarch64__))
- typedef intptr_t param_size_t;
- #elif defined(__i386__)
- typedef int param_size_t;
- #else
- typedef intptr_t param_size_t;
- #endif
- #endif //_WIN32
- #endif // !PARAM_SIZE_DEFINED
- #ifdef DEBUD_MEM_TRACE
- #include "memtrace.h"
- #define ZALLOC(size) zalloc(size)
- #define ZCALLOC(num, size) czalloc(num, size)
- #define MALLOC_T(type) (type*)malloc(sizeof(type))
- #define ZALLOC_T(type) (type*)zalloc(sizeof(type))
- #define CALLOC_T(num, type) (type*)calloc(num, sizeof(type))
- #define REALLOC realloc
- #define FREE(x) do {free(x); x = NULL;} while(0)
- #define STRDUP(str) strdup(str)
- #else /** DEBUD_MEM_TRACE*/
- #if 0
- static __inline void* zalloc(size_t size)
- {
- void* buf = malloc(size);
- if (buf) {
- memset(buf, 0, size);
- }
- return buf;
- }
- static __inline void* zcalloc(size_t num, size_t size)
- {
- void* buf = calloc(num, size);
- if (buf) {
- memset(buf, 0, num * size);
- }
- return buf;
- }
- #define ZALLOC(size) zalloc(size)
- #define ZCALLOC(num, size) czalloc(num, size)
- #define MALLOC_T(type) (type*)malloc(sizeof(type))
- #define ZALLOC_T(type) (type*)zalloc(sizeof(type))
- #define CALLOC_T(num, type) (type*)calloc(num, sizeof(type))
- #define REALLOC realloc
- #define FREE(x) do {free(x); x = NULL;} while(0)
- #define STRDUP(str) _strdup(str)
- #else
- #define ZALLOC(size) toolkit_zalloc(size)
- #define ZCALLOC(num, size) toolkit_calloc(num, size)
- #define MALLOC_T(type) (type*)toolkit_malloc(sizeof(type))
- #define ZALLOC_T(type) (type*)toolkit_zalloc(sizeof(type))
- #define CALLOC_T(num, type) (type*)toolkit_calloc(num, sizeof(type))
- #define REALLOC toolkit_realloc
- #define FREE(x) do {toolkit_free(x); x = NULL;} while(0)
- #define STRDUP(str) toolkit_strdup(str)
- #endif
- #endif /** DEBUD_MEM_TRACE*/
- #define SAFE_INVOKE_0(lpfn) if(lpfn) lpfn()
- #define SAFE_INVOKE_1(lpfn, param1) if(lpfn) lpfn(param1)
- #define SAFE_INVOKE_2(lpfn, param1, param2) if(lpfn) lpfn(param1, param2)
- #define SAFE_INVOKE_3(lpfn, param1, param2, param3) if(lpfn) lpfn(param1, param2, param3)
- #define SAFE_INVOKE_4(lpfn, param1, param2, param3, param4) if(lpfn) lpfn(param1, param2, param3, param4)
- #define SAFE_INVOKE_5(lpfn, param1, param2, param3, param4, param5) if(lpfn) lpfn(param1, param2, param3, param4, param5)
- #define SAFE_INVOKE_6(lpfn, param1, param2, param3, param4, param5, param6) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6)
- #define SAFE_INVOKE_7(lpfn, param1, param2, param3, param4, param5, param6, param7) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6, param7)
- #define SAFE_INVOKE_8(lpfn, param1, param2, param3, param4, param5, param6, param7, param8) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6, param7, param8)
- #define SAFE_INVOKE_9(lpfn, param1, param2, param3, param4, param5, param6, param7, param8, param9) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6, param7, param8, param9)
- #define INIT_COUNTER(name, x) enum { name = __LINE__ + x }
- #define DEF_COUNTER(name) (__LINE__ - name)
- /**
- * resize buffer with data preserved
- * @param old pointer to old buffer
- * @param elemsize element size
- * @param oldcnt the old element count
- * @param newcnt the new element count
- * @return return new buffer, if failed, original buffer is returned, if success old buffer will be freed
- */
- TOOLKIT_API void *buffer_resize(void* old, int elemsize, int oldcnt, int newcnt);
- TOOLKIT_API void *shm_buffer_resize(void* old, int elemsize, int oldcnt, int newcnt);
- /**
- * check expand
- */
- TOOLKIT_API int array_check_expand(void **old, int elemsize, int cnt, int *capacity);
- TOOLKIT_API int shm_array_check_expand(void **old, int elemsize, int cnt, int *capacity);
- typedef struct toolkit_allocator_t tk_allocator_t;
- typedef void* (*toolkit_malloc_func)(size_t size);
- typedef void* (*toolkit_realloc_func)(void* ptr, size_t size);
- typedef void* (*toolkit_calloc_func)(size_t count, size_t size);
- typedef void (*toolkit_free_func)(void* ptr);
- TOOLKIT_API int toolkit_replace_allocator(toolkit_malloc_func malloc_func,
- toolkit_realloc_func realloc_func,
- toolkit_calloc_func calloc_func,
- toolkit_free_func free_func);
- TOOLKIT_API void* toolkit_malloc(size_t size);
- TOOLKIT_API void* toolkit_calloc(size_t num, size_t size);
- TOOLKIT_API void* toolkit_realloc(void* ptr, size_t size);
- TOOLKIT_API void toolkit_free(void *p);
- TOOLKIT_API void *toolkit_zalloc(size_t size);
- TOOLKIT_API void *toolkit_zcalloc(size_t num, size_t size);
- TOOLKIT_API char *toolkit_strdup(const char *s);
- TOOLKIT_API char* toolkit_strndup(const char* s, size_t n);
- TOOLKIT_API wchar_t *toolkit_wcsdup(const wchar_t *s);
- #if !defined(_DEBUG) || !defined(DEBUG)
- #define ASSERT_RETURN(cond, ret) \
- if (!(cond)) \
- return ret;
- #else
- #define ASSERT_RETURN(cond, ret) assert(cond);
- #endif
- TOOLKIT_API void debug_trace(const char *fmt, ...);
- #if defined(_DEBUG) || defined(DEBUG)
- #define DEBUG_TRACE(fmt, ...) debug_trace(fmt, __VA_ARGS__);
- #else
- #define DEBUG_TRACE(fmt, ...)
- #endif /*defined(_DEBUG) || defined(DEBUG)*/
- #if defined(_WIN32) && ( defined(_DEBUG) || defined(DEBUG))
- #define LEAK_TRACE_SNAPSHOT_BEGIN() _CrtMemState s1, s2, s3; \
- do { \
- _CrtMemCheckpoint(&s1); \
- } while (false)
- #define LEAK_TRACE_SNAPSHOT_END() \
- do { \
- _CrtMemCheckpoint(&s2); \
- if (_CrtMemDifference(&s3, &s1, &s2)) \
- _CrtMemDumpStatistics(&s3); \
- } while (false)
- #else
- #define LEAK_TRACE_SNAPSHOT_BEGIN() ((void)0)
- #define LEAK_TRACE_SNAPSHOT_END() ((void)0)
- #endif //#if defined(_WIN32) && ( defined(_DEBUG) || defined(DEBUG))
- /*
- * -1: x < y
- * 1: x > y
- * 0: x == y
- */
- static __inline int timeval_cmp(struct timeval *x, struct timeval *y)
- {
- if (x->tv_sec < y->tv_sec) {
- return -1;
- } else if (x->tv_sec > y->tv_sec) {
- return 1;
- } else {
- if (x->tv_usec < y->tv_usec) {
- return -1;
- } else if (x->tv_usec > y->tv_usec) {
- return 1;
- } else {
- return 0;
- }
- }
- }
- static __inline void timeval_diff(struct timeval *x, struct timeval *y, struct timeval *out)
- {
- out->tv_sec = x->tv_sec - y->tv_sec;
- out->tv_usec = x->tv_usec - y->tv_usec;
- if (out->tv_usec < 0) {
- out->tv_sec --;
- out->tv_usec = 1000000 + out->tv_usec;
- }
- }
- static __inline void timeval_add_sec(struct timeval *tm, unsigned int sec)
- {
- tm->tv_sec += sec;
- }
- static __inline void timeval_add_msec(struct timeval *tm, unsigned int msec)
- {
- tm->tv_sec += msec / 1000;
- msec = msec % 1000;
- tm->tv_usec += msec*1000;
- if (tm->tv_usec > 1000000) {
- tm->tv_usec -= 1000000;
- tm->tv_sec++;
- }
- }
- // return msec of x - y
- static __inline int timeval_sub(struct timeval *x, struct timeval *y)
- {
- return (x->tv_sec - y->tv_sec) * 1000 + (1000000 + x->tv_usec - y->tv_usec)/1000 - 1000;
- }
- #ifdef __cplusplus
- } // extern "C" {
- #endif
- #endif //__MEMUTIL_H__
|