log_multi_thread.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #ifndef LOG_MULTI_THREAD_UTIL_H
  2. #define LOG_MULTI_THREAD_UTIL_H
  3. #include "stdint.h"
  4. #include "log_inner_include.h"
  5. //不同操作系统资源相关的工具宏定义
  6. #ifdef _WIN32
  7. //临界区资源
  8. #define CRITICALSECTION LPCRITICAL_SECTION
  9. #define INVALID_CRITSECT NULL
  10. /**
  11. ********************************************************************
  12. * 创建互斥锁
  13. ********************************************************************
  14. */
  15. static inline CRITICALSECTION CreateCriticalSection()
  16. {
  17. CRITICALSECTION cs = (CRITICALSECTION)malloc(sizeof(RTL_CRITICAL_SECTION));
  18. InitializeCriticalSection(cs);
  19. return cs;
  20. }
  21. /**
  22. ********************************************************************
  23. * 删除互斥锁
  24. ********************************************************************
  25. */
  26. static inline void ReleaseCriticalSection(CRITICALSECTION cs) {
  27. if (cs != INVALID_CRITSECT) {
  28. DeleteCriticalSection(cs);
  29. free(cs);
  30. }
  31. }
  32. /// * @brief 加锁
  33. #define CS_ENTER(cs) EnterCriticalSection(cs)
  34. /// * @brief 解锁
  35. #define CS_LEAVE(cs) LeaveCriticalSection(cs)
  36. /// * @brief 互斥锁
  37. #define MUTEX CRITICAL_SECTION
  38. /// * @brief 加锁
  39. #define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex)
  40. /// * @brief 解锁
  41. #define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex)
  42. /// * @brief 互斥锁初始化
  43. #define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex)
  44. /// * @brief 互斥锁销毁
  45. #define MUTEX_DESTROY(mutex) ReleaseCriticalSection(&mutex)
  46. //信号量资源
  47. /// * @brief 信号量
  48. typedef HANDLE SEMA;
  49. /// * @brief 等待信号量一定时间
  50. #define SEMA_WAIT_TIME(sema, delay) WaitForSingleObject(sema, delay)
  51. /// * @brief 一直阻塞地进行等待信号量
  52. #define SEMA_WAIT(sema) WaitForSingleObject(sema, INFINITE)
  53. /// * @brief 释放信号量
  54. #define SEMA_POST(sema) ReleaseSemaphore(sema, 1, NULL)
  55. /// * @brief 尝试获取一个信号量
  56. #define SEMA_TRYWAIT(sema) WaitForSingleObject(sema, 0)
  57. /// * @brief 销毁信号量
  58. #define SEMA_DESTROY(sema) CloseHandle(sema)
  59. /// * @brief 初始化信号量, 输入的为:信号量的最大值,初始信号量个数
  60. #define SEMA_INIT(sema, initCount, maxCount) sema = CreateSemaphore(NULL, initCount, maxCount, NULL)
  61. /// * @brief 初始一个带有名称的信号量,用于多进程交互
  62. #define SEMA_INIT_NAME(sema, initCount, maxCount, semaName) sema = CreateSemaphore(NULL, initCount, maxCount, semaName)
  63. /// * @brief 信号量等待超时
  64. #define SEMA_WAIT_TIMEOUT WAIT_TIMEOUT
  65. /// * @brief 等待到信号量
  66. #define SEMA_WAIT_OK WAIT_OBJECT_0
  67. //条件量
  68. typedef struct windows_event{
  69. HANDLE event;
  70. }*COND;
  71. //typedef PRTL_CONDITION_VARIABLE COND;
  72. typedef int COND_WAIT_T;
  73. #define COND_WAIT_OK 0
  74. #define COND_WAIT_TIMEOUT ETIMEDOUT
  75. #define INVALID_COND NULL
  76. static inline COND CreateCond() {
  77. COND cond = NULL;
  78. if (!(cond = (COND)malloc(sizeof(struct windows_event))))
  79. return cond;
  80. if ((cond->event = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
  81. free(cond);
  82. return NULL;
  83. }
  84. return cond;
  85. }
  86. static inline void DeleteCond(COND cond) {
  87. if (cond != INVALID_COND) {
  88. CloseHandle(cond->event);
  89. free(cond);
  90. }
  91. }
  92. #define COND_SIGNAL(cond) COND_WAKE(cond)
  93. static inline COND_WAIT_T COND_WAIT_TIME(COND cond, CRITICALSECTION cs, int32_t waitMs) {
  94. DWORD ret;
  95. int result = -1;
  96. if (cond == INVALID_COND)
  97. {
  98. return EINVAL;
  99. }
  100. LeaveCriticalSection(cs);
  101. ret = WaitForSingleObject((HANDLE)cond->event, waitMs);
  102. if (ret == WAIT_TIMEOUT)
  103. {
  104. result = ETIMEDOUT;
  105. }
  106. else if (ret != WAIT_OBJECT_0)
  107. {
  108. result = EINVAL;
  109. }
  110. EnterCriticalSection(cs);
  111. return result;
  112. }
  113. static inline COND_WAIT_T COND_WAKE(COND cond) {
  114. if (cond == INVALID_COND)
  115. {
  116. return EINVAL;
  117. }
  118. if (!SetEvent((HANDLE)cond->event))
  119. return EINVAL;
  120. return 0;
  121. }
  122. typedef HANDLE THREAD;
  123. static inline void Win32CreateThread(HANDLE* hpThread, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ __drv_aliasesMem LPVOID lpParameter) {
  124. *hpThread = CreateThread(NULL, 0, lpStartAddress, lpParameter, 0, NULL);
  125. }
  126. #define THREAD_INIT(thread, func, param) Win32CreateThread((HANDLE *)&thread, func, param)
  127. #define THREAD_JOIN(thread) WaitForSingleObject(thread, INFINITE)
  128. #define snprintf sprintf_s
  129. #define ATOMICINT volatile long
  130. #define ATOMICINT_INC(pAtopicInt) InterlockedIncrement(pAtopicInt)
  131. #define ATOMICINT_DEC(pAtopicInt) InterlockedDecrement(pAtopicInt)
  132. #define ATOMICINT_ADD(pAtopicInt, addVal) InterlockedAdd(pAtopicInt, addVal)
  133. #define ATOMICINT_EXCHANGEADD(pAtopicInt, addVal) InterlockedExchangeAdd(pAtopicInt, addVal)
  134. #define ATOMICINT_EXCHANGE(pAtopicInt, exchangeVal) InterlockedExchange(pAtopicInt, exchangeVal)
  135. #define ATOMICINT_COMPAREEXCAHNGE(pAtopicInt, exchangeVal, cmpVal) InterlockedCompareExchange(pAtopicInt, exchangeVal, cmpVal)
  136. #elif defined(_VXWORKS)
  137. //临界区资源
  138. typedef SEM_ID CRITICALSECTION;
  139. #define INVALID_CRITSECT NULL
  140. static inline CRITICALSECTION CreateCriticalSection(int spinCount = 0)
  141. {
  142. CRITICALSECTION cs = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
  143. if (cs == NULL)
  144. {
  145. perror("vxworks create MUTUAL EXCLUSION SEMAPHORE failed\n");
  146. }
  147. return cs;
  148. }
  149. static inline void ReleaseCriticalSection(CRITICALSECTION & cs)
  150. {
  151. semDelete(cs);
  152. cs = INVALID_CRITSECT;
  153. }
  154. #define CS_ENTER(cs) semTake(cs, WAIT_FOREVER)
  155. #define CS_LEAVE(cs) semGive(cs)
  156. #define MUTEX SEM_ID
  157. #define MUTEX_LOCK(mutex) semTake(mutex, WAIT_FOREVER)
  158. #define MUTEX_UNLOCK(mutex) semGive(mutex)
  159. #define MUTEX_INIT(mutex) mutex = semBCreate(SEM_Q_FIFO,SEM_FULL)
  160. #define MUTEX_DESTROY(mutex) semDelete(mutex)
  161. //信号量资源
  162. #define SEMA SEM_ID
  163. #define SEMA_WAIT_TIME(sema,delay) semTake(sema, delay)
  164. #define SEMA_WAIT(sema) semTake(sema, WAIT_FOREVER)
  165. #define SEMA_POST(sema) semGive(sema)
  166. #define SEMA_DESTROY(sema) semDelete(sema)
  167. #define SEMA_INIT(sema, initCount, maxCount) sema = semCCreate(SEM_Q_FIFO,initCount)
  168. #define SEMA_WAIT_TIMEOUT ERROR
  169. //线程资源
  170. #define THREADID int
  171. #define SOCKET int
  172. #define closesocket(s_) close(s_)
  173. #define SOCKET_ERROR -1
  174. #else
  175. //临界区资源
  176. typedef pthread_mutex_t* CRITICALSECTION;
  177. #define INVALID_CRITSECT NULL
  178. static inline CRITICALSECTION CreateCriticalSection() {
  179. CRITICALSECTION cs = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
  180. assert(cs != INVALID_CRITSECT);
  181. pthread_mutex_init(cs, NULL);
  182. return cs;
  183. }
  184. static inline void ReleaseCriticalSection(CRITICALSECTION cs) {
  185. if (cs != INVALID_CRITSECT) {
  186. pthread_mutex_destroy(cs);
  187. free(cs);
  188. }
  189. }
  190. #define CS_ENTER(cs) pthread_mutex_lock(cs)
  191. #define CS_LEAVE(cs) pthread_mutex_unlock(cs)
  192. typedef pthread_cond_t* COND;
  193. typedef int COND_WAIT_T;
  194. #define COND_WAIT_OK 0
  195. #define COND_WAIT_TIMEOUT ETIMEDOUT
  196. #define INVALID_COND NULL
  197. static inline COND CreateCond() {
  198. COND cond = (COND)malloc(sizeof(pthread_cond_t));
  199. assert(cond != INVALID_CRITSECT);
  200. pthread_cond_init(cond, NULL);
  201. return cond;
  202. }
  203. static inline void DeleteCond(COND cond) {
  204. if (cond != INVALID_COND) {
  205. pthread_cond_destroy(cond);
  206. free(cond);
  207. }
  208. }
  209. #define COND_SIGNAL(cond) pthread_cond_signal(cond)
  210. #define COND_SIGNAL_ALL(cond) pthread_cond_broadcast(cond)
  211. static inline COND_WAIT_T COND_WAIT_TIME(COND cond, CRITICALSECTION cs, int32_t waitMs) {
  212. struct timeval now;
  213. struct timespec outTime;
  214. gettimeofday(&now, NULL);
  215. now.tv_usec += ((waitMs) % 1000) * 1000;
  216. if (now.tv_usec > 1000000)
  217. {
  218. now.tv_usec -= 1000000;
  219. ++now.tv_sec;
  220. }
  221. outTime.tv_sec = now.tv_sec + (waitMs) / 1000;
  222. outTime.tv_nsec = now.tv_usec * 1000;
  223. return pthread_cond_timedwait(cond, cs, &outTime);
  224. }
  225. static inline int64_t GET_TIME_US() {
  226. struct timeval now;
  227. gettimeofday(&now, NULL);
  228. return (int64_t)now.tv_sec * 1000000 + now.tv_usec;
  229. }
  230. #define MUTEX pthread_mutex_t
  231. #define SEMA sem_t
  232. #define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex)
  233. #define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex)
  234. #define MUTEX_INIT(mutex) pthread_mutex_init(&mutex,NULL)
  235. #define MUTEX_DESTROY(mutex) pthread_mutex_destroy(&mutex)
  236. // not supported in mac os
  237. #ifdef __linux__
  238. static inline int sema_wait_time_(sem_t* sema, unsigned int delayMs)
  239. {
  240. struct timespec ts;
  241. struct timeval tv;
  242. gettimeofday(&tv, NULL);
  243. tv.tv_usec += (delayMs % 1000) * 1000;
  244. tv.tv_sec += delayMs / 1000;
  245. if (tv.tv_usec > 1000000) {
  246. tv.tv_usec -= 1000000;
  247. ++tv.tv_sec;
  248. }
  249. ts.tv_sec = tv.tv_sec;
  250. ts.tv_nsec = tv.tv_usec * 1000;
  251. return sem_timedwait(sema, &ts) == 0 ? 0 : ETIMEDOUT;
  252. }
  253. #define SEMA_WAIT_TIME(sema,delay) sema_wait_time_(&sema,delay)
  254. #endif
  255. #define SEMA_WAIT(sema) sem_wait(&sema)
  256. #define SEMA_POST(sema) sem_post(&sema)
  257. #define SEMA_TRYWAIT(sema) sem_trywait(&sema)
  258. #define SEMA_DESTROY(sema) sem_destroy(&sema)
  259. #define SEMA_INIT(sema, initCount, maxCount) sem_init(&sema,0,initCount)
  260. #define SEMA_INIT_NAME(sema, initCount, maxCount, semaName) sema = sem_open(semaName, O_CREAT, 0, initCount)
  261. #define WAIT_OBJECT_0 0
  262. #if defined(_MSC_VER)
  263. #define WAIT_TIMEOUT ETIMEDOUT
  264. #endif //_MSC_VER
  265. #define SEMA_WAIT_TIMEOUT ETIMEDOUT
  266. #define SEMA_WAIT_OK 0
  267. typedef pthread_t THREAD;
  268. #define THREAD_INIT(thread, func, param) pthread_create((thread), NULL, func, param)
  269. #define THREAD_JOIN(thread) pthread_join(*(thread), NULL)
  270. #define ATOMICINT volatile long
  271. #define ATOMICINT_INC(pAtopicInt) __sync_add_and_fetch(pAtopicInt, 1)
  272. #define ATOMICINT_DEC(pAtopicInt) __sync_add_and_fetch(pAtopicInt, -1)
  273. #define ATOMICINT_ADD(pAtopicInt, addVal) __sync_add_and_fetch(pAtopicInt, addVal)
  274. #define ATOMICINT_EXCHANGEADD(pAtopicInt, addVal) __sync_fetch_and_add(pAtopicInt, addVal)
  275. #define ATOMICINT_EXCHANGE(pAtopicInt, exchangeVal) __sync_val_compare_and_swap(pAtopicInt, *pAtopicInt, exchangeVal)
  276. #define ATOMICINT_COMPAREEXCAHNGE(pAtopicInt, exchangeVal, cmpVal) __sync_val_compare_and_swap(pAtopicInt, cmpVal, exchangeVal)
  277. #if defined(_MSC_VER)
  278. typedef struct _FILETIME
  279. {
  280. unsigned long dwLowDateTime;
  281. unsigned long dwHighDateTime;
  282. } FILETIME;
  283. #endif //_MSC_VER
  284. #endif //WIN32
  285. #endif //LOG_MULTI_THREAD_UTIL_H