ua_util.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #ifndef UA_UTIL_H_
  2. #define UA_UTIL_H_
  3. #include "ua_config.h"
  4. #include <assert.h>
  5. #define UA_assert(ignore) assert(ignore)
  6. /*********************/
  7. /* Memory Management */
  8. /*********************/
  9. /* Replace the macros with functions for custom allocators if necessary */
  10. #include <stdlib.h> // malloc, free
  11. #ifdef _WIN32
  12. # include <malloc.h>
  13. #endif
  14. #ifndef UA_free
  15. # define UA_free(ptr) free(ptr)
  16. #endif
  17. #ifndef UA_malloc
  18. # define UA_malloc(size) malloc(size)
  19. #endif
  20. #ifndef UA_calloc
  21. # define UA_calloc(num, size) calloc(num, size)
  22. #endif
  23. #ifndef UA_realloc
  24. # define UA_realloc(ptr, size) realloc(ptr, size)
  25. #endif
  26. #ifndef NO_ALLOCA
  27. # ifdef __GNUC__
  28. # define UA_alloca(size) __builtin_alloca (size)
  29. # elif defined(_WIN32)
  30. # define UA_alloca(SIZE) _alloca(SIZE)
  31. # else
  32. # include <alloca.h>
  33. # define UA_alloca(SIZE) alloca(SIZE)
  34. # endif
  35. #endif
  36. #define container_of(ptr, type, member) \
  37. (type *)((uintptr_t)ptr - offsetof(type,member))
  38. /************************/
  39. /* Thread Local Storage */
  40. /************************/
  41. #ifdef UA_ENABLE_MULTITHREADING
  42. # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
  43. # define UA_THREAD_LOCAL _Thread_local /* C11 */
  44. # elif defined(__GNUC__)
  45. # define UA_THREAD_LOCAL __thread /* GNU extension */
  46. # elif defined(_MSC_VER)
  47. # define UA_THREAD_LOCAL __declspec(thread) /* MSVC extension */
  48. # else
  49. # warning The compiler does not allow thread-local variables. The library can be built, but will not be thread safe.
  50. # endif
  51. #endif
  52. #ifndef UA_THREAD_LOCAL
  53. # define UA_THREAD_LOCAL
  54. #endif
  55. /*************************/
  56. /* External Dependencies */
  57. /*************************/
  58. #include "queue.h"
  59. #ifdef UA_ENABLE_MULTITHREADING
  60. # define _LGPL_SOURCE
  61. # include <urcu.h>
  62. # include <urcu/wfcqueue.h>
  63. # include <urcu/uatomic.h>
  64. # include <urcu/rculfhash.h>
  65. # include <urcu/lfstack.h>
  66. # ifdef NDEBUG
  67. # define UA_RCU_LOCK() rcu_read_lock()
  68. # define UA_RCU_UNLOCK() rcu_read_unlock()
  69. # define UA_ASSERT_RCU_LOCKED()
  70. # define UA_ASSERT_RCU_UNLOCKED()
  71. # else
  72. extern UA_THREAD_LOCAL bool rcu_locked;
  73. # define UA_ASSERT_RCU_LOCKED() assert(rcu_locked)
  74. # define UA_ASSERT_RCU_UNLOCKED() assert(!rcu_locked)
  75. # define UA_RCU_LOCK() do { \
  76. UA_ASSERT_RCU_UNLOCKED(); \
  77. rcu_locked = true; \
  78. rcu_read_lock(); } while(0)
  79. # define UA_RCU_UNLOCK() do { \
  80. UA_ASSERT_RCU_LOCKED(); \
  81. rcu_locked = false; \
  82. rcu_read_lock(); } while(0)
  83. # endif
  84. #else
  85. # define UA_RCU_LOCK()
  86. # define UA_RCU_UNLOCK()
  87. # define UA_ASSERT_RCU_LOCKED()
  88. # define UA_ASSERT_RCU_UNLOCKED()
  89. #endif
  90. #endif /* UA_UTIL_H_ */