OS.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #ifndef ZT_OS_HPP
  14. #define ZT_OS_HPP
  15. #include <cstdint>
  16. //
  17. // This include file also auto-detects and canonicalizes some environment
  18. // information defines:
  19. //
  20. // __LINUX__
  21. // __APPLE__
  22. // __BSD__ (OSX also defines this)
  23. // __UNIX_LIKE__ (Linux, BSD, etc.)
  24. // __WINDOWS__
  25. //
  26. // Also makes sure __BYTE_ORDER is defined reasonably.
  27. //
  28. #ifndef __GCC__
  29. #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__INTEL_COMPILER) || defined(__clang__)
  30. #define __GCC__
  31. #endif
  32. #endif
  33. #if defined(__GCC__) && !defined(__GNUC__)
  34. #define __GNUC__
  35. #endif
  36. #if defined(__SIZEOF_INT128__) || ((defined(__GCC__) || defined(__GNUC__) || defined(__clang)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(__aarch64__)))
  37. #if defined(__SIZEOF_INT128__)
  38. #define ZT_HAVE_UINT128 1
  39. typedef unsigned __int128 uint128_t;
  40. #else
  41. #define ZT_HAVE_UINT128 1
  42. typedef unsigned uint128_t __attribute__((mode(TI)));
  43. #endif
  44. #endif
  45. #if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64))
  46. #define ZT_ARCH_X64 1
  47. #endif
  48. // As far as we know it's only generally safe to do unaligned type casts in all
  49. // cases on x86 and x64 architectures. Others such as ARM and MIPS will generate
  50. // a fault or exhibit undefined behavior that varies by vendor.
  51. #if (!(defined(ZT_ARCH_X64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) || defined(__386)))
  52. #ifndef ZT_NO_UNALIGNED_ACCESS
  53. #define ZT_NO_UNALIGNED_ACCESS 1
  54. #endif
  55. #endif
  56. #if defined(_WIN32) || defined(_WIN64)
  57. #ifdef _MSC_VER
  58. #pragma warning(disable : 4290)
  59. #pragma warning(disable : 4996)
  60. #pragma warning(disable : 4101)
  61. #endif
  62. #ifndef __WINDOWS__
  63. #define __WINDOWS__ 1
  64. #endif
  65. #ifndef NOMINMAX
  66. #define NOMINMAX
  67. #endif
  68. #undef __UNIX_LIKE__
  69. #undef __BSD__
  70. #include <WinSock2.h>
  71. #include <Windows.h>
  72. #endif
  73. #if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
  74. #ifndef __LINUX__
  75. #define __LINUX__ 1
  76. #endif
  77. #ifndef __UNIX_LIKE__
  78. #define __UNIX_LIKE__ 1
  79. #endif
  80. #include <endian.h>
  81. #endif
  82. #ifdef __APPLE__
  83. #include <TargetConditionals.h>
  84. #ifndef __UNIX_LIKE__
  85. #define __UNIX_LIKE__ 1
  86. #endif
  87. #ifndef __BSD__
  88. #define __BSD__ 1
  89. #endif
  90. #include <machine/endian.h>
  91. #ifndef __BYTE_ORDER
  92. #define __BYTE_ORDER __DARWIN_BYTE_ORDER
  93. #define __BIG_ENDIAN __DARWIN_BIG_ENDIAN
  94. #define __LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
  95. #endif
  96. #endif
  97. #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
  98. #ifndef __UNIX_LIKE__
  99. #define __UNIX_LIKE__ 1
  100. #endif
  101. #ifndef __BSD__
  102. #define __BSD__ 1
  103. #endif
  104. #include <sys/endian.h>
  105. #ifndef RTF_MULTICAST
  106. #define RTF_MULTICAST 0x20000000
  107. #endif
  108. #endif
  109. // It would probably be safe to assume LE everywhere except on very specific architectures as there
  110. // are few BE chips remaining in the wild that are powerful enough to run this, but for now we'll
  111. // try to include endian.h and error out if it doesn't exist.
  112. #ifndef __BYTE_ORDER
  113. #ifdef _BYTE_ORDER
  114. #define __BYTE_ORDER _BYTE_ORDER
  115. #define __LITTLE_ENDIAN _LITTLE_ENDIAN
  116. #define __BIG_ENDIAN _BIG_ENDIAN
  117. #else
  118. #include <endian.h>
  119. #endif
  120. #endif
  121. #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
  122. #ifdef ZT_DEBUG
  123. #define ZT_ALWAYS_INLINE
  124. #else
  125. #define ZT_ALWAYS_INLINE __attribute__((always_inline)) inline
  126. #endif
  127. #ifndef restrict
  128. #define restrict __restrict__
  129. #endif
  130. #ifndef likely
  131. #define likely(x) __builtin_expect((x),1)
  132. #endif
  133. #ifndef unlikely
  134. #define unlikely(x) __builtin_expect((x),0)
  135. #endif
  136. #else /* not GCC-like */
  137. #ifndef restrict
  138. #define restrict
  139. #endif
  140. #ifndef likely
  141. #define likely(x) (x)
  142. #endif
  143. #ifndef unlikely
  144. #define unlikely(x) (x)
  145. #endif
  146. #endif
  147. #if __cplusplus > 199711L
  148. #include <atomic>
  149. #ifndef __CPP11__
  150. #define __CPP11__
  151. #endif
  152. #endif
  153. #ifndef __CPP11__
  154. // TODO: we'll need to "polyfill" a subset of std::atomic for integers if we want to build on pre-C++11 compilers.
  155. // Beyond that defining nullptr, constexpr, and noexcept should allow us to still build on these. So far we've
  156. // avoided deeper C++11 features like lambdas in the core until we're 100% sure all the ancient targets are gone.
  157. #error need pre-c++11 std::atomic implementation
  158. #define nullptr (0)
  159. #define constexpr ZT_ALWAYS_INLINE
  160. #define noexcept throw()
  161. #endif
  162. #ifdef SOCKET
  163. #define ZT_SOCKET SOCKET
  164. #else
  165. #define ZT_SOCKET int
  166. #endif
  167. #ifdef INVALID_SOCKET
  168. #define ZT_INVALID_SOCKET INVALID_SOCKET
  169. #else
  170. #define ZT_INVALID_SOCKET -1
  171. #endif
  172. #ifdef __WINDOWS__
  173. #define ZT_PATH_SEPARATOR '\\'
  174. #define ZT_PATH_SEPARATOR_S "\\"
  175. #define ZT_EOL_S "\r\n"
  176. #else
  177. #define ZT_PATH_SEPARATOR '/'
  178. #define ZT_PATH_SEPARATOR_S "/"
  179. #define ZT_EOL_S "\n"
  180. #endif
  181. #ifndef ZT_ALWAYS_INLINE
  182. #ifdef ZT_DEBUG
  183. #define ZT_ALWAYS_INLINE
  184. #else
  185. #define ZT_ALWAYS_INLINE inline
  186. #endif
  187. #endif
  188. // Macro to avoid calling hton() on values known at compile time.
  189. #if __BYTE_ORDER == __LITTLE_ENDIAN
  190. #define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)((uint16_t)((uint16_t)(x) << 8U) | (uint16_t)((uint16_t)(x) >> 8U)))
  191. #else
  192. #define ZT_CONST_TO_BE_UINT16(x) ((uint16_t)(x))
  193. #endif
  194. #endif