memutil.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * category: [core for memory]
  3. * apply status:
  4. * edit status:
  5. * build status:
  6. * description: debug_trace would be invoked by stm, but stm is not used anywhere...
  7. *
  8. */
  9. #ifndef __MEMUTIL_H__
  10. #define __MEMUTIL_H__
  11. #pragma once
  12. #include "config.h"
  13. #ifdef _WIN32
  14. #include <WinSock2.h> //for struct timeval
  15. #else
  16. //TODO: remove #else macro.
  17. //because error C2039 would occur: ¡°int8_t¡±: is not the member of ¡°`global namespace'¡±
  18. #include <winpr/wtypes.h>
  19. #endif
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #ifdef _WIN32
  26. static __inline void prefetch(void* p)
  27. {
  28. _asm
  29. {
  30. //NTA(non-temporal data with respect to all cache levels) prefetch data into non-temporal cache structure and
  31. //into a location close to the processor, minimizing cache pollution.
  32. prefetchnta p
  33. }
  34. }
  35. #else
  36. //rw, locality: 1(w), 0(r), temporal locality(0-3, 3 is default)
  37. #define prefetch(x) __builtin_prefetch(x, 0)
  38. #endif
  39. #define INT64_GET_HIGH_PART(x) (*((int*)(&(x)) + 1))
  40. #define INT64_GET_LOW_PART(x) (*(int*)&(x))
  41. static __inline int int64_get_high_part(__int64 x)
  42. {
  43. return INT64_GET_HIGH_PART(x);
  44. }
  45. static __inline int int64_get_low_part(__int64 x)
  46. {
  47. return INT64_GET_LOW_PART(x);
  48. }
  49. struct __i8_helper {
  50. union {
  51. __int64 i;
  52. struct {
  53. int l;
  54. int h;
  55. };
  56. };
  57. };
  58. static __inline __int64 int64_make(int low_part, int high_part)
  59. {
  60. struct __i8_helper t;
  61. t.l = low_part;
  62. t.h = high_part;
  63. return t.i;
  64. }
  65. #define offset_of(type, member) \
  66. (((char*)(&((type*)0)->member)) - (char*)0)
  67. #define container_of(ptr, type, member) \
  68. ((type*)((char*)(ptr) - offset_of(type, member)))
  69. #define field_size(type, member) \
  70. sizeof(((type*)0)->member)
  71. #define array_size(x) \
  72. (sizeof(x)/sizeof((x)[0]))
  73. #define FLAG_BIT(f) f##_BIT
  74. /* for compatility at different platform [3/31/2020 Gifur] */
  75. #ifndef PARAM_SIZE_DEFINED
  76. #define PARAM_SIZE_DEFINED
  77. #ifdef _WIN32
  78. typedef int param_size_t;
  79. #else
  80. #if defined(__x86_64__)
  81. typedef intptr_t param_size_t;
  82. #elif defined(__i386__)
  83. typedef int param_size_t;
  84. #else
  85. typedef intptr_t param_size_t;
  86. #endif
  87. #endif //_WIN32
  88. #endif // !PARAM_SIZE_DEFINED
  89. #define SAFE_INVOKE_0(lpfn) if(lpfn) lpfn()
  90. #define SAFE_INVOKE_1(lpfn, param1) if(lpfn) lpfn(param1)
  91. #define SAFE_INVOKE_2(lpfn, param1, param2) if(lpfn) lpfn(param1, param2)
  92. #define SAFE_INVOKE_3(lpfn, param1, param2, param3) if(lpfn) lpfn(param1, param2, param3)
  93. #define SAFE_INVOKE_4(lpfn, param1, param2, param3, param4) if(lpfn) lpfn(param1, param2, param3, param4)
  94. #define SAFE_INVOKE_5(lpfn, param1, param2, param3, param4, param5) if(lpfn) lpfn(param1, param2, param3, param4, param5)
  95. #define SAFE_INVOKE_6(lpfn, param1, param2, param3, param4, param5, param6) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6)
  96. #define SAFE_INVOKE_7(lpfn, param1, param2, param3, param4, param5, param6, param7) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6, param7)
  97. #define SAFE_INVOKE_8(lpfn, param1, param2, param3, param4, param5, param6, param7, param8) if(lpfn) lpfn(param1, param2, param3, param4, param5, param6, param7, param8)
  98. #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)
  99. #define INIT_COUNTER(name, x) enum { name = __LINE__ + x }
  100. #define DEF_COUNTER(name) (__LINE__ - name)
  101. /**
  102. * resize buffer with data preserved
  103. * @param old pointer to old buffer
  104. * @param elemsize element size
  105. * @param oldcnt the old element count
  106. * @param newcnt the new element count
  107. * @return return new buffer, if failed, original buffer is returned, if success old buffer will be freed
  108. */
  109. TOOLKIT_API void *buffer_resize(void* old, int elemsize, int oldcnt, int newcnt);
  110. TOOLKIT_API void *shm_buffer_resize(void* old, int elemsize, int oldcnt, int newcnt);
  111. /**
  112. * check expand
  113. */
  114. TOOLKIT_API int array_check_expand(void **old, int elemsize, int cnt, int *capacity);
  115. TOOLKIT_API int shm_array_check_expand(void **old, int elemsize, int cnt, int *capacity);
  116. static __inline void* zalloc(size_t size)
  117. {
  118. void *buf = malloc(size);
  119. if (buf) {
  120. memset(buf, 0, size);
  121. }
  122. return buf;
  123. }
  124. static __inline void* zcalloc(size_t num, size_t size)
  125. {
  126. void *buf = calloc(num, size);
  127. if (buf) {
  128. memset(buf, 0, num * size);
  129. }
  130. return buf;
  131. }
  132. TOOLKIT_API void toolkit_free(void *p);
  133. TOOLKIT_API void *toolkit_malloc(size_t size);
  134. TOOLKIT_API void *toolkit_calloc(size_t num, size_t size);
  135. TOOLKIT_API void *toolkit_zalloc(size_t size);
  136. TOOLKIT_API void *toolkit_zcalloc(size_t num, size_t size);
  137. TOOLKIT_API char *toolkit_strdup(const char *s);
  138. TOOLKIT_API wchar_t *toolkit_wcsdup(const wchar_t *s);
  139. #define ZALLOC(size) zalloc(size)
  140. #define ZCALLOC(num, size) czalloc(num, size)
  141. #define MALLOC_T(type) (type*)malloc(sizeof(type))
  142. #define ZALLOC_T(type) (type*)zalloc(sizeof(type))
  143. #define CALLOC_T(num, type) (type*)calloc(num, sizeof(type))
  144. #define FREE(x) do {free(x); x = NULL;} while(0)
  145. #if !defined(_DEBUG) || !defined(DEBUG)
  146. #define ASSERT_RETURN(cond, ret) \
  147. if (!(cond)) \
  148. return ret;
  149. #else
  150. #define ASSERT_RETURN(cond, ret) assert(cond);
  151. #endif
  152. TOOLKIT_API void debug_trace(const char *fmt, ...);
  153. #if defined(_DEBUG) || defined(DEBUG)
  154. #define DEBUG_TRACE(fmt, ...) debug_trace(fmt, __VA_ARGS__);
  155. #else
  156. #define DEBUG_TRACE(fmt, ...)
  157. #endif
  158. /*
  159. * -1: x < y
  160. * 1: x > y
  161. * 0: x == y
  162. */
  163. static __inline int timeval_cmp(struct timeval *x, struct timeval *y)
  164. {
  165. if (x->tv_sec < y->tv_sec) {
  166. return -1;
  167. } else if (x->tv_sec > y->tv_sec) {
  168. return 1;
  169. } else {
  170. if (x->tv_usec < y->tv_usec) {
  171. return -1;
  172. } else if (x->tv_usec > y->tv_usec) {
  173. return 1;
  174. } else {
  175. return 0;
  176. }
  177. }
  178. }
  179. static __inline void timeval_diff(struct timeval *x, struct timeval *y, struct timeval *out)
  180. {
  181. out->tv_sec = x->tv_sec - y->tv_sec;
  182. out->tv_usec = x->tv_usec - y->tv_usec;
  183. if (out->tv_usec < 0) {
  184. out->tv_sec --;
  185. out->tv_usec = 1000000 + out->tv_usec;
  186. }
  187. }
  188. static __inline void timeval_add_sec(struct timeval *tm, unsigned int sec)
  189. {
  190. tm->tv_sec += sec;
  191. }
  192. static __inline void timeval_add_msec(struct timeval *tm, unsigned int msec)
  193. {
  194. tm->tv_sec += msec / 1000;
  195. msec = msec % 1000;
  196. tm->tv_usec += msec*1000;
  197. if (tm->tv_usec > 1000000) {
  198. tm->tv_usec -= 1000000;
  199. tm->tv_sec++;
  200. }
  201. }
  202. // return msec of x - y
  203. static __inline int timeval_sub(struct timeval *x, struct timeval *y)
  204. {
  205. return (x->tv_sec - y->tv_sec) * 1000 + (1000000 + x->tv_usec - y->tv_usec)/1000 - 1000;
  206. }
  207. TOOLKIT_API int GetSystemErrorDesc(int error_code, char *buf, int n);
  208. #ifdef __cplusplus
  209. } // extern "C" {
  210. #endif
  211. #endif //__MEMUTIL_H__