kmp_os.h 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. /*
  2. * kmp_os.h -- KPTS runtime header file.
  3. */
  4. //===----------------------------------------------------------------------===//
  5. //
  6. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  7. // See https://llvm.org/LICENSE.txt for license information.
  8. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #ifndef KMP_OS_H
  12. #define KMP_OS_H
  13. #include "kmp_config.h"
  14. #include <atomic>
  15. #include <stdarg.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #define KMP_FTN_PLAIN 1
  19. #define KMP_FTN_APPEND 2
  20. #define KMP_FTN_UPPER 3
  21. /*
  22. #define KMP_FTN_PREPEND 4
  23. #define KMP_FTN_UAPPEND 5
  24. */
  25. #define KMP_PTR_SKIP (sizeof(void *))
  26. /* -------------------------- Compiler variations ------------------------ */
  27. #define KMP_OFF 0
  28. #define KMP_ON 1
  29. #define KMP_MEM_CONS_VOLATILE 0
  30. #define KMP_MEM_CONS_FENCE 1
  31. #ifndef KMP_MEM_CONS_MODEL
  32. #define KMP_MEM_CONS_MODEL KMP_MEM_CONS_VOLATILE
  33. #endif
  34. #ifndef __has_cpp_attribute
  35. #define __has_cpp_attribute(x) 0
  36. #endif
  37. #ifndef __has_attribute
  38. #define __has_attribute(x) 0
  39. #endif
  40. /* ------------------------- Compiler recognition ---------------------- */
  41. #define KMP_COMPILER_ICC 0
  42. #define KMP_COMPILER_GCC 0
  43. #define KMP_COMPILER_CLANG 0
  44. #define KMP_COMPILER_MSVC 0
  45. #define KMP_COMPILER_ICX 0
  46. #if __INTEL_CLANG_COMPILER
  47. #undef KMP_COMPILER_ICX
  48. #define KMP_COMPILER_ICX 1
  49. #elif defined(__INTEL_COMPILER)
  50. #undef KMP_COMPILER_ICC
  51. #define KMP_COMPILER_ICC 1
  52. #elif defined(__clang__)
  53. #undef KMP_COMPILER_CLANG
  54. #define KMP_COMPILER_CLANG 1
  55. #elif defined(__GNUC__)
  56. #undef KMP_COMPILER_GCC
  57. #define KMP_COMPILER_GCC 1
  58. #elif defined(_MSC_VER)
  59. #undef KMP_COMPILER_MSVC
  60. #define KMP_COMPILER_MSVC 1
  61. #else
  62. #error Unknown compiler
  63. #endif
  64. #if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD)
  65. #define KMP_AFFINITY_SUPPORTED 1
  66. #if KMP_OS_WINDOWS && KMP_ARCH_X86_64
  67. #define KMP_GROUP_AFFINITY 1
  68. #else
  69. #define KMP_GROUP_AFFINITY 0
  70. #endif
  71. #else
  72. #define KMP_AFFINITY_SUPPORTED 0
  73. #define KMP_GROUP_AFFINITY 0
  74. #endif
  75. #if (KMP_OS_LINUX || (KMP_OS_FREEBSD && __FreeBSD_version >= 1301000))
  76. #define KMP_HAVE_SCHED_GETCPU 1
  77. #else
  78. #define KMP_HAVE_SCHED_GETCPU 0
  79. #endif
  80. /* Check for quad-precision extension. */
  81. #define KMP_HAVE_QUAD 0
  82. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  83. #if KMP_COMPILER_ICC || KMP_COMPILER_ICX
  84. /* _Quad is already defined for icc */
  85. #undef KMP_HAVE_QUAD
  86. #define KMP_HAVE_QUAD 1
  87. #elif KMP_COMPILER_CLANG
  88. /* Clang doesn't support a software-implemented
  89. 128-bit extended precision type yet */
  90. typedef long double _Quad;
  91. #elif KMP_COMPILER_GCC
  92. /* GCC on NetBSD lacks __multc3/__divtc3 builtins needed for quad */
  93. #if !KMP_OS_NETBSD
  94. typedef __float128 _Quad;
  95. #undef KMP_HAVE_QUAD
  96. #define KMP_HAVE_QUAD 1
  97. #endif
  98. #elif KMP_COMPILER_MSVC
  99. typedef long double _Quad;
  100. #endif
  101. #else
  102. #if __LDBL_MAX_EXP__ >= 16384 && KMP_COMPILER_GCC
  103. typedef long double _Quad;
  104. #undef KMP_HAVE_QUAD
  105. #define KMP_HAVE_QUAD 1
  106. #endif
  107. #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
  108. #define KMP_USE_X87CONTROL 0
  109. #if KMP_OS_WINDOWS
  110. #define KMP_END_OF_LINE "\r\n"
  111. typedef char kmp_int8;
  112. typedef unsigned char kmp_uint8;
  113. typedef short kmp_int16;
  114. typedef unsigned short kmp_uint16;
  115. typedef int kmp_int32;
  116. typedef unsigned int kmp_uint32;
  117. #define KMP_INT32_SPEC "d"
  118. #define KMP_UINT32_SPEC "u"
  119. #ifndef KMP_STRUCT64
  120. typedef __int64 kmp_int64;
  121. typedef unsigned __int64 kmp_uint64;
  122. #define KMP_INT64_SPEC "I64d"
  123. #define KMP_UINT64_SPEC "I64u"
  124. #else
  125. struct kmp_struct64 {
  126. kmp_int32 a, b;
  127. };
  128. typedef struct kmp_struct64 kmp_int64;
  129. typedef struct kmp_struct64 kmp_uint64;
  130. /* Not sure what to use for KMP_[U]INT64_SPEC here */
  131. #endif
  132. #if KMP_ARCH_X86 && KMP_MSVC_COMPAT
  133. #undef KMP_USE_X87CONTROL
  134. #define KMP_USE_X87CONTROL 1
  135. #endif
  136. #if KMP_ARCH_X86_64 || KMP_ARCH_AARCH64
  137. #define KMP_INTPTR 1
  138. typedef __int64 kmp_intptr_t;
  139. typedef unsigned __int64 kmp_uintptr_t;
  140. #define KMP_INTPTR_SPEC "I64d"
  141. #define KMP_UINTPTR_SPEC "I64u"
  142. #endif
  143. #endif /* KMP_OS_WINDOWS */
  144. #if KMP_OS_UNIX
  145. #define KMP_END_OF_LINE "\n"
  146. typedef char kmp_int8;
  147. typedef unsigned char kmp_uint8;
  148. typedef short kmp_int16;
  149. typedef unsigned short kmp_uint16;
  150. typedef int kmp_int32;
  151. typedef unsigned int kmp_uint32;
  152. typedef long long kmp_int64;
  153. typedef unsigned long long kmp_uint64;
  154. #define KMP_INT32_SPEC "d"
  155. #define KMP_UINT32_SPEC "u"
  156. #define KMP_INT64_SPEC "lld"
  157. #define KMP_UINT64_SPEC "llu"
  158. #endif /* KMP_OS_UNIX */
  159. #if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS
  160. #define KMP_SIZE_T_SPEC KMP_UINT32_SPEC
  161. #elif KMP_ARCH_X86_64 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || \
  162. KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64
  163. #define KMP_SIZE_T_SPEC KMP_UINT64_SPEC
  164. #else
  165. #error "Can't determine size_t printf format specifier."
  166. #endif
  167. #if KMP_ARCH_X86
  168. #define KMP_SIZE_T_MAX (0xFFFFFFFF)
  169. #else
  170. #define KMP_SIZE_T_MAX (0xFFFFFFFFFFFFFFFF)
  171. #endif
  172. typedef size_t kmp_size_t;
  173. typedef float kmp_real32;
  174. typedef double kmp_real64;
  175. #ifndef KMP_INTPTR
  176. #define KMP_INTPTR 1
  177. typedef long kmp_intptr_t;
  178. typedef unsigned long kmp_uintptr_t;
  179. #define KMP_INTPTR_SPEC "ld"
  180. #define KMP_UINTPTR_SPEC "lu"
  181. #endif
  182. #ifdef BUILD_I8
  183. typedef kmp_int64 kmp_int;
  184. typedef kmp_uint64 kmp_uint;
  185. #else
  186. typedef kmp_int32 kmp_int;
  187. typedef kmp_uint32 kmp_uint;
  188. #endif /* BUILD_I8 */
  189. #define KMP_INT_MAX ((kmp_int32)0x7FFFFFFF)
  190. #define KMP_INT_MIN ((kmp_int32)0x80000000)
  191. // stdarg handling
  192. #if (KMP_ARCH_ARM || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64) && \
  193. (KMP_OS_FREEBSD || KMP_OS_LINUX)
  194. typedef va_list *kmp_va_list;
  195. #define kmp_va_deref(ap) (*(ap))
  196. #define kmp_va_addr_of(ap) (&(ap))
  197. #else
  198. typedef va_list kmp_va_list;
  199. #define kmp_va_deref(ap) (ap)
  200. #define kmp_va_addr_of(ap) (ap)
  201. #endif
  202. #ifdef __cplusplus
  203. // macros to cast out qualifiers and to re-interpret types
  204. #define CCAST(type, var) const_cast<type>(var)
  205. #define RCAST(type, var) reinterpret_cast<type>(var)
  206. //-------------------------------------------------------------------------
  207. // template for debug prints specification ( d, u, lld, llu ), and to obtain
  208. // signed/unsigned flavors of a type
  209. template <typename T> struct traits_t {};
  210. // int
  211. template <> struct traits_t<signed int> {
  212. typedef signed int signed_t;
  213. typedef unsigned int unsigned_t;
  214. typedef double floating_t;
  215. static char const *spec;
  216. static const signed_t max_value = 0x7fffffff;
  217. static const signed_t min_value = 0x80000000;
  218. static const int type_size = sizeof(signed_t);
  219. };
  220. // unsigned int
  221. template <> struct traits_t<unsigned int> {
  222. typedef signed int signed_t;
  223. typedef unsigned int unsigned_t;
  224. typedef double floating_t;
  225. static char const *spec;
  226. static const unsigned_t max_value = 0xffffffff;
  227. static const unsigned_t min_value = 0x00000000;
  228. static const int type_size = sizeof(unsigned_t);
  229. };
  230. // long
  231. template <> struct traits_t<signed long> {
  232. typedef signed long signed_t;
  233. typedef unsigned long unsigned_t;
  234. typedef long double floating_t;
  235. static char const *spec;
  236. static const int type_size = sizeof(signed_t);
  237. };
  238. // long long
  239. template <> struct traits_t<signed long long> {
  240. typedef signed long long signed_t;
  241. typedef unsigned long long unsigned_t;
  242. typedef long double floating_t;
  243. static char const *spec;
  244. static const signed_t max_value = 0x7fffffffffffffffLL;
  245. static const signed_t min_value = 0x8000000000000000LL;
  246. static const int type_size = sizeof(signed_t);
  247. };
  248. // unsigned long long
  249. template <> struct traits_t<unsigned long long> {
  250. typedef signed long long signed_t;
  251. typedef unsigned long long unsigned_t;
  252. typedef long double floating_t;
  253. static char const *spec;
  254. static const unsigned_t max_value = 0xffffffffffffffffLL;
  255. static const unsigned_t min_value = 0x0000000000000000LL;
  256. static const int type_size = sizeof(unsigned_t);
  257. };
  258. //-------------------------------------------------------------------------
  259. #else
  260. #define CCAST(type, var) (type)(var)
  261. #define RCAST(type, var) (type)(var)
  262. #endif // __cplusplus
  263. #define KMP_EXPORT extern /* export declaration in guide libraries */
  264. #if __GNUC__ >= 4 && !defined(__MINGW32__)
  265. #define __forceinline __inline
  266. #endif
  267. /* Check if the OS/arch can support user-level mwait */
  268. // All mwait code tests for UMWAIT first, so it should only fall back to ring3
  269. // MWAIT for KNL.
  270. #define KMP_HAVE_MWAIT \
  271. ((KMP_ARCH_X86 || KMP_ARCH_X86_64) && (KMP_OS_LINUX || KMP_OS_WINDOWS) && \
  272. !KMP_MIC2)
  273. #define KMP_HAVE_UMWAIT \
  274. ((KMP_ARCH_X86 || KMP_ARCH_X86_64) && (KMP_OS_LINUX || KMP_OS_WINDOWS) && \
  275. !KMP_MIC)
  276. #if KMP_OS_WINDOWS
  277. #include <windows.h>
  278. static inline int KMP_GET_PAGE_SIZE(void) {
  279. SYSTEM_INFO si;
  280. GetSystemInfo(&si);
  281. return si.dwPageSize;
  282. }
  283. #else
  284. #define KMP_GET_PAGE_SIZE() getpagesize()
  285. #endif
  286. #define PAGE_ALIGNED(_addr) \
  287. (!((size_t)_addr & (size_t)(KMP_GET_PAGE_SIZE() - 1)))
  288. #define ALIGN_TO_PAGE(x) \
  289. (void *)(((size_t)(x)) & ~((size_t)(KMP_GET_PAGE_SIZE() - 1)))
  290. /* ---------- Support for cache alignment, padding, etc. ----------------*/
  291. #ifdef __cplusplus
  292. extern "C" {
  293. #endif // __cplusplus
  294. #define INTERNODE_CACHE_LINE 4096 /* for multi-node systems */
  295. /* Define the default size of the cache line */
  296. #ifndef CACHE_LINE
  297. #define CACHE_LINE 128 /* cache line size in bytes */
  298. #else
  299. #if (CACHE_LINE < 64) && !defined(KMP_OS_DARWIN)
  300. // 2006-02-13: This produces too many warnings on OS X*. Disable for now
  301. #warning CACHE_LINE is too small.
  302. #endif
  303. #endif /* CACHE_LINE */
  304. #define KMP_CACHE_PREFETCH(ADDR) /* nothing */
  305. // Define attribute that indicates that the fall through from the previous
  306. // case label is intentional and should not be diagnosed by a compiler
  307. // Code from libcxx/include/__config
  308. // Use a function like macro to imply that it must be followed by a semicolon
  309. #if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
  310. #define KMP_FALLTHROUGH() [[fallthrough]]
  311. // icc cannot properly tell this attribute is absent so force off
  312. #elif KMP_COMPILER_ICC
  313. #define KMP_FALLTHROUGH() ((void)0)
  314. #elif __has_cpp_attribute(clang::fallthrough)
  315. #define KMP_FALLTHROUGH() [[clang::fallthrough]]
  316. #elif __has_attribute(fallthrough) || __GNUC__ >= 7
  317. #define KMP_FALLTHROUGH() __attribute__((__fallthrough__))
  318. #else
  319. #define KMP_FALLTHROUGH() ((void)0)
  320. #endif
  321. #if KMP_HAVE_ATTRIBUTE_WAITPKG
  322. #define KMP_ATTRIBUTE_TARGET_WAITPKG __attribute__((target("waitpkg")))
  323. #else
  324. #define KMP_ATTRIBUTE_TARGET_WAITPKG /* Nothing */
  325. #endif
  326. #if KMP_HAVE_ATTRIBUTE_RTM
  327. #define KMP_ATTRIBUTE_TARGET_RTM __attribute__((target("rtm")))
  328. #else
  329. #define KMP_ATTRIBUTE_TARGET_RTM /* Nothing */
  330. #endif
  331. // Define attribute that indicates a function does not return
  332. #if __cplusplus >= 201103L
  333. #define KMP_NORETURN [[noreturn]]
  334. #elif KMP_OS_WINDOWS
  335. #define KMP_NORETURN __declspec(noreturn)
  336. #else
  337. #define KMP_NORETURN __attribute__((noreturn))
  338. #endif
  339. #if KMP_OS_WINDOWS && KMP_MSVC_COMPAT
  340. #define KMP_ALIGN(bytes) __declspec(align(bytes))
  341. #define KMP_THREAD_LOCAL __declspec(thread)
  342. #define KMP_ALIAS /* Nothing */
  343. #else
  344. #define KMP_ALIGN(bytes) __attribute__((aligned(bytes)))
  345. #define KMP_THREAD_LOCAL __thread
  346. #define KMP_ALIAS(alias_of) __attribute__((alias(alias_of)))
  347. #endif
  348. #if KMP_HAVE_WEAK_ATTRIBUTE && !KMP_DYNAMIC_LIB
  349. #define KMP_WEAK_ATTRIBUTE_EXTERNAL __attribute__((weak))
  350. #else
  351. #define KMP_WEAK_ATTRIBUTE_EXTERNAL /* Nothing */
  352. #endif
  353. #if KMP_HAVE_WEAK_ATTRIBUTE
  354. #define KMP_WEAK_ATTRIBUTE_INTERNAL __attribute__((weak))
  355. #else
  356. #define KMP_WEAK_ATTRIBUTE_INTERNAL /* Nothing */
  357. #endif
  358. // Define KMP_VERSION_SYMBOL and KMP_EXPAND_NAME
  359. #ifndef KMP_STR
  360. #define KMP_STR(x) _KMP_STR(x)
  361. #define _KMP_STR(x) #x
  362. #endif
  363. #ifdef KMP_USE_VERSION_SYMBOLS
  364. // If using versioned symbols, KMP_EXPAND_NAME prepends
  365. // __kmp_api_ to the real API name
  366. #define KMP_EXPAND_NAME(api_name) _KMP_EXPAND_NAME(api_name)
  367. #define _KMP_EXPAND_NAME(api_name) __kmp_api_##api_name
  368. #define KMP_VERSION_SYMBOL(api_name, ver_num, ver_str) \
  369. _KMP_VERSION_SYMBOL(api_name, ver_num, ver_str, "VERSION")
  370. #define _KMP_VERSION_SYMBOL(api_name, ver_num, ver_str, default_ver) \
  371. __typeof__(__kmp_api_##api_name) __kmp_api_##api_name##_##ver_num##_alias \
  372. __attribute__((alias(KMP_STR(__kmp_api_##api_name)))); \
  373. __asm__( \
  374. ".symver " KMP_STR(__kmp_api_##api_name##_##ver_num##_alias) "," KMP_STR( \
  375. api_name) "@" ver_str "\n\t"); \
  376. __asm__(".symver " KMP_STR(__kmp_api_##api_name) "," KMP_STR( \
  377. api_name) "@@" default_ver "\n\t")
  378. #define KMP_VERSION_OMPC_SYMBOL(apic_name, api_name, ver_num, ver_str) \
  379. _KMP_VERSION_OMPC_SYMBOL(apic_name, api_name, ver_num, ver_str, "VERSION")
  380. #define _KMP_VERSION_OMPC_SYMBOL(apic_name, api_name, ver_num, ver_str, \
  381. default_ver) \
  382. __typeof__(__kmp_api_##apic_name) __kmp_api_##apic_name##_##ver_num##_alias \
  383. __attribute__((alias(KMP_STR(__kmp_api_##apic_name)))); \
  384. __asm__(".symver " KMP_STR(__kmp_api_##apic_name) "," KMP_STR( \
  385. apic_name) "@@" default_ver "\n\t"); \
  386. __asm__( \
  387. ".symver " KMP_STR(__kmp_api_##apic_name##_##ver_num##_alias) "," KMP_STR( \
  388. api_name) "@" ver_str "\n\t")
  389. #else // KMP_USE_VERSION_SYMBOLS
  390. #define KMP_EXPAND_NAME(api_name) api_name
  391. #define KMP_VERSION_SYMBOL(api_name, ver_num, ver_str) /* Nothing */
  392. #define KMP_VERSION_OMPC_SYMBOL(apic_name, api_name, ver_num, \
  393. ver_str) /* Nothing */
  394. #endif // KMP_USE_VERSION_SYMBOLS
  395. /* Temporary note: if performance testing of this passes, we can remove
  396. all references to KMP_DO_ALIGN and replace with KMP_ALIGN. */
  397. #define KMP_DO_ALIGN(bytes) KMP_ALIGN(bytes)
  398. #define KMP_ALIGN_CACHE KMP_ALIGN(CACHE_LINE)
  399. #define KMP_ALIGN_CACHE_INTERNODE KMP_ALIGN(INTERNODE_CACHE_LINE)
  400. /* General purpose fence types for memory operations */
  401. enum kmp_mem_fence_type {
  402. kmp_no_fence, /* No memory fence */
  403. kmp_acquire_fence, /* Acquire (read) memory fence */
  404. kmp_release_fence, /* Release (write) memory fence */
  405. kmp_full_fence /* Full (read+write) memory fence */
  406. };
  407. // Synchronization primitives
  408. #if KMP_ASM_INTRINS && KMP_OS_WINDOWS
  409. #if KMP_MSVC_COMPAT && !KMP_COMPILER_CLANG
  410. #pragma intrinsic(InterlockedExchangeAdd)
  411. #pragma intrinsic(InterlockedCompareExchange)
  412. #pragma intrinsic(InterlockedExchange)
  413. #if !(KMP_COMPILER_ICX && KMP_32_BIT_ARCH)
  414. #pragma intrinsic(InterlockedExchange64)
  415. #endif
  416. #endif
  417. // Using InterlockedIncrement / InterlockedDecrement causes a library loading
  418. // ordering problem, so we use InterlockedExchangeAdd instead.
  419. #define KMP_TEST_THEN_INC32(p) InterlockedExchangeAdd((volatile long *)(p), 1)
  420. #define KMP_TEST_THEN_INC_ACQ32(p) \
  421. InterlockedExchangeAdd((volatile long *)(p), 1)
  422. #define KMP_TEST_THEN_ADD4_32(p) InterlockedExchangeAdd((volatile long *)(p), 4)
  423. #define KMP_TEST_THEN_ADD4_ACQ32(p) \
  424. InterlockedExchangeAdd((volatile long *)(p), 4)
  425. #define KMP_TEST_THEN_DEC32(p) InterlockedExchangeAdd((volatile long *)(p), -1)
  426. #define KMP_TEST_THEN_DEC_ACQ32(p) \
  427. InterlockedExchangeAdd((volatile long *)(p), -1)
  428. #define KMP_TEST_THEN_ADD32(p, v) \
  429. InterlockedExchangeAdd((volatile long *)(p), (v))
  430. #define KMP_COMPARE_AND_STORE_RET32(p, cv, sv) \
  431. InterlockedCompareExchange((volatile long *)(p), (long)(sv), (long)(cv))
  432. #define KMP_XCHG_FIXED32(p, v) \
  433. InterlockedExchange((volatile long *)(p), (long)(v))
  434. #define KMP_XCHG_FIXED64(p, v) \
  435. InterlockedExchange64((volatile kmp_int64 *)(p), (kmp_int64)(v))
  436. inline kmp_real32 KMP_XCHG_REAL32(volatile kmp_real32 *p, kmp_real32 v) {
  437. kmp_int32 tmp = InterlockedExchange((volatile long *)p, *(long *)&v);
  438. return *(kmp_real32 *)&tmp;
  439. }
  440. #define KMP_TEST_THEN_OR8(p, v) __kmp_test_then_or8((p), (v))
  441. #define KMP_TEST_THEN_AND8(p, v) __kmp_test_then_and8((p), (v))
  442. #define KMP_TEST_THEN_OR32(p, v) __kmp_test_then_or32((p), (v))
  443. #define KMP_TEST_THEN_AND32(p, v) __kmp_test_then_and32((p), (v))
  444. #define KMP_TEST_THEN_OR64(p, v) __kmp_test_then_or64((p), (v))
  445. #define KMP_TEST_THEN_AND64(p, v) __kmp_test_then_and64((p), (v))
  446. extern kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 v);
  447. extern kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 v);
  448. extern kmp_int32 __kmp_test_then_add32(volatile kmp_int32 *p, kmp_int32 v);
  449. extern kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 v);
  450. extern kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 v);
  451. extern kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 v);
  452. extern kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 v);
  453. extern kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 v);
  454. #if KMP_ARCH_AARCH64 && KMP_COMPILER_MSVC && !KMP_COMPILER_CLANG
  455. #define KMP_TEST_THEN_INC64(p) _InterlockedExchangeAdd64((p), 1LL)
  456. #define KMP_TEST_THEN_INC_ACQ64(p) _InterlockedExchangeAdd64_acq((p), 1LL)
  457. #define KMP_TEST_THEN_ADD4_64(p) _InterlockedExchangeAdd64((p), 4LL)
  458. // #define KMP_TEST_THEN_ADD4_ACQ64(p) _InterlockedExchangeAdd64_acq((p), 4LL)
  459. // #define KMP_TEST_THEN_DEC64(p) _InterlockedExchangeAdd64((p), -1LL)
  460. // #define KMP_TEST_THEN_DEC_ACQ64(p) _InterlockedExchangeAdd64_acq((p), -1LL)
  461. // #define KMP_TEST_THEN_ADD8(p, v) _InterlockedExchangeAdd8((p), (v))
  462. #define KMP_TEST_THEN_ADD64(p, v) _InterlockedExchangeAdd64((p), (v))
  463. #define KMP_COMPARE_AND_STORE_ACQ8(p, cv, sv) \
  464. __kmp_compare_and_store_acq8((p), (cv), (sv))
  465. #define KMP_COMPARE_AND_STORE_REL8(p, cv, sv) \
  466. __kmp_compare_and_store_rel8((p), (cv), (sv))
  467. #define KMP_COMPARE_AND_STORE_ACQ16(p, cv, sv) \
  468. __kmp_compare_and_store_acq16((p), (cv), (sv))
  469. /*
  470. #define KMP_COMPARE_AND_STORE_REL16(p, cv, sv) \
  471. __kmp_compare_and_store_rel16((p), (cv), (sv))
  472. */
  473. #define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv) \
  474. __kmp_compare_and_store_acq32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  475. (kmp_int32)(sv))
  476. #define KMP_COMPARE_AND_STORE_REL32(p, cv, sv) \
  477. __kmp_compare_and_store_rel32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  478. (kmp_int32)(sv))
  479. #define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) \
  480. __kmp_compare_and_store_acq64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  481. (kmp_int64)(sv))
  482. #define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) \
  483. __kmp_compare_and_store_rel64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  484. (kmp_int64)(sv))
  485. #define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) \
  486. __kmp_compare_and_store_ptr((void *volatile *)(p), (void *)(cv), (void *)(sv))
  487. // KMP_COMPARE_AND_STORE expects this order: pointer, compare, exchange
  488. // _InterlockedCompareExchange expects this order: pointer, exchange, compare
  489. // KMP_COMPARE_AND_STORE also returns a bool indicating a successful write. A
  490. // write is successful if the return value of _InterlockedCompareExchange is the
  491. // same as the compare value.
  492. inline kmp_int8 __kmp_compare_and_store_acq8(volatile kmp_int8 *p, kmp_int8 cv,
  493. kmp_int8 sv) {
  494. return _InterlockedCompareExchange8_acq(p, sv, cv) == cv;
  495. }
  496. inline kmp_int8 __kmp_compare_and_store_rel8(volatile kmp_int8 *p, kmp_int8 cv,
  497. kmp_int8 sv) {
  498. return _InterlockedCompareExchange8_rel(p, sv, cv) == cv;
  499. }
  500. inline kmp_int16 __kmp_compare_and_store_acq16(volatile kmp_int16 *p,
  501. kmp_int16 cv, kmp_int16 sv) {
  502. return _InterlockedCompareExchange16_acq(p, sv, cv) == cv;
  503. }
  504. inline kmp_int16 __kmp_compare_and_store_rel16(volatile kmp_int16 *p,
  505. kmp_int16 cv, kmp_int16 sv) {
  506. return _InterlockedCompareExchange16_rel(p, sv, cv) == cv;
  507. }
  508. inline kmp_int32 __kmp_compare_and_store_acq32(volatile kmp_int32 *p,
  509. kmp_int32 cv, kmp_int32 sv) {
  510. return _InterlockedCompareExchange_acq((volatile long *)p, sv, cv) == cv;
  511. }
  512. inline kmp_int32 __kmp_compare_and_store_rel32(volatile kmp_int32 *p,
  513. kmp_int32 cv, kmp_int32 sv) {
  514. return _InterlockedCompareExchange_rel((volatile long *)p, sv, cv) == cv;
  515. }
  516. inline kmp_int32 __kmp_compare_and_store_acq64(volatile kmp_int64 *p,
  517. kmp_int64 cv, kmp_int64 sv) {
  518. return _InterlockedCompareExchange64_acq(p, sv, cv) == cv;
  519. }
  520. inline kmp_int32 __kmp_compare_and_store_rel64(volatile kmp_int64 *p,
  521. kmp_int64 cv, kmp_int64 sv) {
  522. return _InterlockedCompareExchange64_rel(p, sv, cv) == cv;
  523. }
  524. inline kmp_int32 __kmp_compare_and_store_ptr(void *volatile *p, void *cv,
  525. void *sv) {
  526. return _InterlockedCompareExchangePointer(p, sv, cv) == cv;
  527. }
  528. // The _RET versions return the value instead of a bool
  529. /*
  530. #define KMP_COMPARE_AND_STORE_RET8(p, cv, sv) \
  531. _InterlockedCompareExchange8((p), (sv), (cv))
  532. #define KMP_COMPARE_AND_STORE_RET16(p, cv, sv) \
  533. _InterlockedCompareExchange16((p), (sv), (cv))
  534. */
  535. #define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) \
  536. _InterlockedCompareExchange64((volatile kmp_int64 *)(p), (kmp_int64)(sv), \
  537. (kmp_int64)(cv))
  538. /*
  539. #define KMP_XCHG_FIXED8(p, v) \
  540. _InterlockedExchange8((volatile kmp_int8 *)(p), (kmp_int8)(v));
  541. */
  542. // #define KMP_XCHG_FIXED16(p, v) _InterlockedExchange16((p), (v));
  543. // #define KMP_XCHG_REAL64(p, v) __kmp_xchg_real64((p), (v)));
  544. // inline kmp_real64 __kmp_xchg_real64(volatile kmp_real64 *p, kmp_real64 v) {
  545. // kmp_int64 tmp = _InterlockedExchange64((volatile kmp_int64 *)p, *(kmp_int64
  546. // *)&v); return *(kmp_real64 *)&tmp;
  547. // }
  548. #else // !KMP_ARCH_AARCH64
  549. // Routines that we still need to implement in assembly.
  550. extern kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 v);
  551. extern kmp_int8 __kmp_compare_and_store8(volatile kmp_int8 *p, kmp_int8 cv,
  552. kmp_int8 sv);
  553. extern kmp_int16 __kmp_compare_and_store16(volatile kmp_int16 *p, kmp_int16 cv,
  554. kmp_int16 sv);
  555. extern kmp_int32 __kmp_compare_and_store32(volatile kmp_int32 *p, kmp_int32 cv,
  556. kmp_int32 sv);
  557. extern kmp_int32 __kmp_compare_and_store64(volatile kmp_int64 *p, kmp_int64 cv,
  558. kmp_int64 sv);
  559. extern kmp_int8 __kmp_compare_and_store_ret8(volatile kmp_int8 *p, kmp_int8 cv,
  560. kmp_int8 sv);
  561. extern kmp_int16 __kmp_compare_and_store_ret16(volatile kmp_int16 *p,
  562. kmp_int16 cv, kmp_int16 sv);
  563. extern kmp_int32 __kmp_compare_and_store_ret32(volatile kmp_int32 *p,
  564. kmp_int32 cv, kmp_int32 sv);
  565. extern kmp_int64 __kmp_compare_and_store_ret64(volatile kmp_int64 *p,
  566. kmp_int64 cv, kmp_int64 sv);
  567. extern kmp_int8 __kmp_xchg_fixed8(volatile kmp_int8 *p, kmp_int8 v);
  568. extern kmp_int16 __kmp_xchg_fixed16(volatile kmp_int16 *p, kmp_int16 v);
  569. extern kmp_int32 __kmp_xchg_fixed32(volatile kmp_int32 *p, kmp_int32 v);
  570. extern kmp_int64 __kmp_xchg_fixed64(volatile kmp_int64 *p, kmp_int64 v);
  571. extern kmp_real32 __kmp_xchg_real32(volatile kmp_real32 *p, kmp_real32 v);
  572. extern kmp_real64 __kmp_xchg_real64(volatile kmp_real64 *p, kmp_real64 v);
  573. //#define KMP_TEST_THEN_INC32(p) __kmp_test_then_add32((p), 1)
  574. //#define KMP_TEST_THEN_INC_ACQ32(p) __kmp_test_then_add32((p), 1)
  575. #define KMP_TEST_THEN_INC64(p) __kmp_test_then_add64((p), 1LL)
  576. #define KMP_TEST_THEN_INC_ACQ64(p) __kmp_test_then_add64((p), 1LL)
  577. //#define KMP_TEST_THEN_ADD4_32(p) __kmp_test_then_add32((p), 4)
  578. //#define KMP_TEST_THEN_ADD4_ACQ32(p) __kmp_test_then_add32((p), 4)
  579. #define KMP_TEST_THEN_ADD4_64(p) __kmp_test_then_add64((p), 4LL)
  580. #define KMP_TEST_THEN_ADD4_ACQ64(p) __kmp_test_then_add64((p), 4LL)
  581. //#define KMP_TEST_THEN_DEC32(p) __kmp_test_then_add32((p), -1)
  582. //#define KMP_TEST_THEN_DEC_ACQ32(p) __kmp_test_then_add32((p), -1)
  583. #define KMP_TEST_THEN_DEC64(p) __kmp_test_then_add64((p), -1LL)
  584. #define KMP_TEST_THEN_DEC_ACQ64(p) __kmp_test_then_add64((p), -1LL)
  585. //#define KMP_TEST_THEN_ADD32(p, v) __kmp_test_then_add32((p), (v))
  586. #define KMP_TEST_THEN_ADD8(p, v) __kmp_test_then_add8((p), (v))
  587. #define KMP_TEST_THEN_ADD64(p, v) __kmp_test_then_add64((p), (v))
  588. #define KMP_COMPARE_AND_STORE_ACQ8(p, cv, sv) \
  589. __kmp_compare_and_store8((p), (cv), (sv))
  590. #define KMP_COMPARE_AND_STORE_REL8(p, cv, sv) \
  591. __kmp_compare_and_store8((p), (cv), (sv))
  592. #define KMP_COMPARE_AND_STORE_ACQ16(p, cv, sv) \
  593. __kmp_compare_and_store16((p), (cv), (sv))
  594. #define KMP_COMPARE_AND_STORE_REL16(p, cv, sv) \
  595. __kmp_compare_and_store16((p), (cv), (sv))
  596. #define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv) \
  597. __kmp_compare_and_store32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  598. (kmp_int32)(sv))
  599. #define KMP_COMPARE_AND_STORE_REL32(p, cv, sv) \
  600. __kmp_compare_and_store32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  601. (kmp_int32)(sv))
  602. #define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) \
  603. __kmp_compare_and_store64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  604. (kmp_int64)(sv))
  605. #define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) \
  606. __kmp_compare_and_store64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  607. (kmp_int64)(sv))
  608. #if KMP_ARCH_X86
  609. #define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) \
  610. __kmp_compare_and_store32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  611. (kmp_int32)(sv))
  612. #else /* 64 bit pointers */
  613. #define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) \
  614. __kmp_compare_and_store64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  615. (kmp_int64)(sv))
  616. #endif /* KMP_ARCH_X86 */
  617. #define KMP_COMPARE_AND_STORE_RET8(p, cv, sv) \
  618. __kmp_compare_and_store_ret8((p), (cv), (sv))
  619. #define KMP_COMPARE_AND_STORE_RET16(p, cv, sv) \
  620. __kmp_compare_and_store_ret16((p), (cv), (sv))
  621. #define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) \
  622. __kmp_compare_and_store_ret64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  623. (kmp_int64)(sv))
  624. #define KMP_XCHG_FIXED8(p, v) \
  625. __kmp_xchg_fixed8((volatile kmp_int8 *)(p), (kmp_int8)(v));
  626. #define KMP_XCHG_FIXED16(p, v) __kmp_xchg_fixed16((p), (v));
  627. //#define KMP_XCHG_FIXED32(p, v) __kmp_xchg_fixed32((p), (v));
  628. //#define KMP_XCHG_FIXED64(p, v) __kmp_xchg_fixed64((p), (v));
  629. //#define KMP_XCHG_REAL32(p, v) __kmp_xchg_real32((p), (v));
  630. #define KMP_XCHG_REAL64(p, v) __kmp_xchg_real64((p), (v));
  631. #endif
  632. #elif (KMP_ASM_INTRINS && KMP_OS_UNIX) || !(KMP_ARCH_X86 || KMP_ARCH_X86_64)
  633. /* cast p to correct type so that proper intrinsic will be used */
  634. #define KMP_TEST_THEN_INC32(p) \
  635. __sync_fetch_and_add((volatile kmp_int32 *)(p), 1)
  636. #define KMP_TEST_THEN_INC_ACQ32(p) \
  637. __sync_fetch_and_add((volatile kmp_int32 *)(p), 1)
  638. #if KMP_ARCH_MIPS
  639. #define KMP_TEST_THEN_INC64(p) \
  640. __atomic_fetch_add((volatile kmp_int64 *)(p), 1LL, __ATOMIC_SEQ_CST)
  641. #define KMP_TEST_THEN_INC_ACQ64(p) \
  642. __atomic_fetch_add((volatile kmp_int64 *)(p), 1LL, __ATOMIC_SEQ_CST)
  643. #else
  644. #define KMP_TEST_THEN_INC64(p) \
  645. __sync_fetch_and_add((volatile kmp_int64 *)(p), 1LL)
  646. #define KMP_TEST_THEN_INC_ACQ64(p) \
  647. __sync_fetch_and_add((volatile kmp_int64 *)(p), 1LL)
  648. #endif
  649. #define KMP_TEST_THEN_ADD4_32(p) \
  650. __sync_fetch_and_add((volatile kmp_int32 *)(p), 4)
  651. #define KMP_TEST_THEN_ADD4_ACQ32(p) \
  652. __sync_fetch_and_add((volatile kmp_int32 *)(p), 4)
  653. #if KMP_ARCH_MIPS
  654. #define KMP_TEST_THEN_ADD4_64(p) \
  655. __atomic_fetch_add((volatile kmp_int64 *)(p), 4LL, __ATOMIC_SEQ_CST)
  656. #define KMP_TEST_THEN_ADD4_ACQ64(p) \
  657. __atomic_fetch_add((volatile kmp_int64 *)(p), 4LL, __ATOMIC_SEQ_CST)
  658. #define KMP_TEST_THEN_DEC64(p) \
  659. __atomic_fetch_sub((volatile kmp_int64 *)(p), 1LL, __ATOMIC_SEQ_CST)
  660. #define KMP_TEST_THEN_DEC_ACQ64(p) \
  661. __atomic_fetch_sub((volatile kmp_int64 *)(p), 1LL, __ATOMIC_SEQ_CST)
  662. #else
  663. #define KMP_TEST_THEN_ADD4_64(p) \
  664. __sync_fetch_and_add((volatile kmp_int64 *)(p), 4LL)
  665. #define KMP_TEST_THEN_ADD4_ACQ64(p) \
  666. __sync_fetch_and_add((volatile kmp_int64 *)(p), 4LL)
  667. #define KMP_TEST_THEN_DEC64(p) \
  668. __sync_fetch_and_sub((volatile kmp_int64 *)(p), 1LL)
  669. #define KMP_TEST_THEN_DEC_ACQ64(p) \
  670. __sync_fetch_and_sub((volatile kmp_int64 *)(p), 1LL)
  671. #endif
  672. #define KMP_TEST_THEN_DEC32(p) \
  673. __sync_fetch_and_sub((volatile kmp_int32 *)(p), 1)
  674. #define KMP_TEST_THEN_DEC_ACQ32(p) \
  675. __sync_fetch_and_sub((volatile kmp_int32 *)(p), 1)
  676. #define KMP_TEST_THEN_ADD8(p, v) \
  677. __sync_fetch_and_add((volatile kmp_int8 *)(p), (kmp_int8)(v))
  678. #define KMP_TEST_THEN_ADD32(p, v) \
  679. __sync_fetch_and_add((volatile kmp_int32 *)(p), (kmp_int32)(v))
  680. #if KMP_ARCH_MIPS
  681. #define KMP_TEST_THEN_ADD64(p, v) \
  682. __atomic_fetch_add((volatile kmp_uint64 *)(p), (kmp_uint64)(v), \
  683. __ATOMIC_SEQ_CST)
  684. #else
  685. #define KMP_TEST_THEN_ADD64(p, v) \
  686. __sync_fetch_and_add((volatile kmp_int64 *)(p), (kmp_int64)(v))
  687. #endif
  688. #define KMP_TEST_THEN_OR8(p, v) \
  689. __sync_fetch_and_or((volatile kmp_int8 *)(p), (kmp_int8)(v))
  690. #define KMP_TEST_THEN_AND8(p, v) \
  691. __sync_fetch_and_and((volatile kmp_int8 *)(p), (kmp_int8)(v))
  692. #define KMP_TEST_THEN_OR32(p, v) \
  693. __sync_fetch_and_or((volatile kmp_uint32 *)(p), (kmp_uint32)(v))
  694. #define KMP_TEST_THEN_AND32(p, v) \
  695. __sync_fetch_and_and((volatile kmp_uint32 *)(p), (kmp_uint32)(v))
  696. #if KMP_ARCH_MIPS
  697. #define KMP_TEST_THEN_OR64(p, v) \
  698. __atomic_fetch_or((volatile kmp_uint64 *)(p), (kmp_uint64)(v), \
  699. __ATOMIC_SEQ_CST)
  700. #define KMP_TEST_THEN_AND64(p, v) \
  701. __atomic_fetch_and((volatile kmp_uint64 *)(p), (kmp_uint64)(v), \
  702. __ATOMIC_SEQ_CST)
  703. #else
  704. #define KMP_TEST_THEN_OR64(p, v) \
  705. __sync_fetch_and_or((volatile kmp_uint64 *)(p), (kmp_uint64)(v))
  706. #define KMP_TEST_THEN_AND64(p, v) \
  707. __sync_fetch_and_and((volatile kmp_uint64 *)(p), (kmp_uint64)(v))
  708. #endif
  709. #define KMP_COMPARE_AND_STORE_ACQ8(p, cv, sv) \
  710. __sync_bool_compare_and_swap((volatile kmp_uint8 *)(p), (kmp_uint8)(cv), \
  711. (kmp_uint8)(sv))
  712. #define KMP_COMPARE_AND_STORE_REL8(p, cv, sv) \
  713. __sync_bool_compare_and_swap((volatile kmp_uint8 *)(p), (kmp_uint8)(cv), \
  714. (kmp_uint8)(sv))
  715. #define KMP_COMPARE_AND_STORE_ACQ16(p, cv, sv) \
  716. __sync_bool_compare_and_swap((volatile kmp_uint16 *)(p), (kmp_uint16)(cv), \
  717. (kmp_uint16)(sv))
  718. #define KMP_COMPARE_AND_STORE_REL16(p, cv, sv) \
  719. __sync_bool_compare_and_swap((volatile kmp_uint16 *)(p), (kmp_uint16)(cv), \
  720. (kmp_uint16)(sv))
  721. #define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv) \
  722. __sync_bool_compare_and_swap((volatile kmp_uint32 *)(p), (kmp_uint32)(cv), \
  723. (kmp_uint32)(sv))
  724. #define KMP_COMPARE_AND_STORE_REL32(p, cv, sv) \
  725. __sync_bool_compare_and_swap((volatile kmp_uint32 *)(p), (kmp_uint32)(cv), \
  726. (kmp_uint32)(sv))
  727. #define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) \
  728. __sync_bool_compare_and_swap((void *volatile *)(p), (void *)(cv), \
  729. (void *)(sv))
  730. #define KMP_COMPARE_AND_STORE_RET8(p, cv, sv) \
  731. __sync_val_compare_and_swap((volatile kmp_uint8 *)(p), (kmp_uint8)(cv), \
  732. (kmp_uint8)(sv))
  733. #define KMP_COMPARE_AND_STORE_RET16(p, cv, sv) \
  734. __sync_val_compare_and_swap((volatile kmp_uint16 *)(p), (kmp_uint16)(cv), \
  735. (kmp_uint16)(sv))
  736. #define KMP_COMPARE_AND_STORE_RET32(p, cv, sv) \
  737. __sync_val_compare_and_swap((volatile kmp_uint32 *)(p), (kmp_uint32)(cv), \
  738. (kmp_uint32)(sv))
  739. #if KMP_ARCH_MIPS
  740. static inline bool mips_sync_bool_compare_and_swap(volatile kmp_uint64 *p,
  741. kmp_uint64 cv,
  742. kmp_uint64 sv) {
  743. return __atomic_compare_exchange(p, &cv, &sv, false, __ATOMIC_SEQ_CST,
  744. __ATOMIC_SEQ_CST);
  745. }
  746. static inline bool mips_sync_val_compare_and_swap(volatile kmp_uint64 *p,
  747. kmp_uint64 cv,
  748. kmp_uint64 sv) {
  749. __atomic_compare_exchange(p, &cv, &sv, false, __ATOMIC_SEQ_CST,
  750. __ATOMIC_SEQ_CST);
  751. return cv;
  752. }
  753. #define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) \
  754. mips_sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), \
  755. (kmp_uint64)(cv), (kmp_uint64)(sv))
  756. #define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) \
  757. mips_sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), \
  758. (kmp_uint64)(cv), (kmp_uint64)(sv))
  759. #define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) \
  760. mips_sync_val_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64)(cv), \
  761. (kmp_uint64)(sv))
  762. #else
  763. #define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) \
  764. __sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64)(cv), \
  765. (kmp_uint64)(sv))
  766. #define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) \
  767. __sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64)(cv), \
  768. (kmp_uint64)(sv))
  769. #define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) \
  770. __sync_val_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64)(cv), \
  771. (kmp_uint64)(sv))
  772. #endif
  773. #if KMP_OS_DARWIN && defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1800
  774. #define KMP_XCHG_FIXED8(p, v) \
  775. __atomic_exchange_1((volatile kmp_uint8 *)(p), (kmp_uint8)(v), \
  776. __ATOMIC_SEQ_CST)
  777. #else
  778. #define KMP_XCHG_FIXED8(p, v) \
  779. __sync_lock_test_and_set((volatile kmp_uint8 *)(p), (kmp_uint8)(v))
  780. #endif
  781. #define KMP_XCHG_FIXED16(p, v) \
  782. __sync_lock_test_and_set((volatile kmp_uint16 *)(p), (kmp_uint16)(v))
  783. #define KMP_XCHG_FIXED32(p, v) \
  784. __sync_lock_test_and_set((volatile kmp_uint32 *)(p), (kmp_uint32)(v))
  785. #define KMP_XCHG_FIXED64(p, v) \
  786. __sync_lock_test_and_set((volatile kmp_uint64 *)(p), (kmp_uint64)(v))
  787. inline kmp_real32 KMP_XCHG_REAL32(volatile kmp_real32 *p, kmp_real32 v) {
  788. volatile kmp_uint32 *up;
  789. kmp_uint32 uv;
  790. memcpy(&up, &p, sizeof(up));
  791. memcpy(&uv, &v, sizeof(uv));
  792. kmp_int32 tmp = __sync_lock_test_and_set(up, uv);
  793. kmp_real32 ftmp;
  794. memcpy(&ftmp, &tmp, sizeof(tmp));
  795. return ftmp;
  796. }
  797. inline kmp_real64 KMP_XCHG_REAL64(volatile kmp_real64 *p, kmp_real64 v) {
  798. volatile kmp_uint64 *up;
  799. kmp_uint64 uv;
  800. memcpy(&up, &p, sizeof(up));
  801. memcpy(&uv, &v, sizeof(uv));
  802. kmp_int64 tmp = __sync_lock_test_and_set(up, uv);
  803. kmp_real64 dtmp;
  804. memcpy(&dtmp, &tmp, sizeof(tmp));
  805. return dtmp;
  806. }
  807. #else
  808. extern kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 v);
  809. extern kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 v);
  810. extern kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 v);
  811. extern kmp_int32 __kmp_test_then_add32(volatile kmp_int32 *p, kmp_int32 v);
  812. extern kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 v);
  813. extern kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 v);
  814. extern kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 v);
  815. extern kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 v);
  816. extern kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 v);
  817. extern kmp_int8 __kmp_compare_and_store8(volatile kmp_int8 *p, kmp_int8 cv,
  818. kmp_int8 sv);
  819. extern kmp_int16 __kmp_compare_and_store16(volatile kmp_int16 *p, kmp_int16 cv,
  820. kmp_int16 sv);
  821. extern kmp_int32 __kmp_compare_and_store32(volatile kmp_int32 *p, kmp_int32 cv,
  822. kmp_int32 sv);
  823. extern kmp_int32 __kmp_compare_and_store64(volatile kmp_int64 *p, kmp_int64 cv,
  824. kmp_int64 sv);
  825. extern kmp_int8 __kmp_compare_and_store_ret8(volatile kmp_int8 *p, kmp_int8 cv,
  826. kmp_int8 sv);
  827. extern kmp_int16 __kmp_compare_and_store_ret16(volatile kmp_int16 *p,
  828. kmp_int16 cv, kmp_int16 sv);
  829. extern kmp_int32 __kmp_compare_and_store_ret32(volatile kmp_int32 *p,
  830. kmp_int32 cv, kmp_int32 sv);
  831. extern kmp_int64 __kmp_compare_and_store_ret64(volatile kmp_int64 *p,
  832. kmp_int64 cv, kmp_int64 sv);
  833. extern kmp_int8 __kmp_xchg_fixed8(volatile kmp_int8 *p, kmp_int8 v);
  834. extern kmp_int16 __kmp_xchg_fixed16(volatile kmp_int16 *p, kmp_int16 v);
  835. extern kmp_int32 __kmp_xchg_fixed32(volatile kmp_int32 *p, kmp_int32 v);
  836. extern kmp_int64 __kmp_xchg_fixed64(volatile kmp_int64 *p, kmp_int64 v);
  837. extern kmp_real32 __kmp_xchg_real32(volatile kmp_real32 *p, kmp_real32 v);
  838. extern kmp_real64 __kmp_xchg_real64(volatile kmp_real64 *p, kmp_real64 v);
  839. #define KMP_TEST_THEN_INC32(p) \
  840. __kmp_test_then_add32((volatile kmp_int32 *)(p), 1)
  841. #define KMP_TEST_THEN_INC_ACQ32(p) \
  842. __kmp_test_then_add32((volatile kmp_int32 *)(p), 1)
  843. #define KMP_TEST_THEN_INC64(p) \
  844. __kmp_test_then_add64((volatile kmp_int64 *)(p), 1LL)
  845. #define KMP_TEST_THEN_INC_ACQ64(p) \
  846. __kmp_test_then_add64((volatile kmp_int64 *)(p), 1LL)
  847. #define KMP_TEST_THEN_ADD4_32(p) \
  848. __kmp_test_then_add32((volatile kmp_int32 *)(p), 4)
  849. #define KMP_TEST_THEN_ADD4_ACQ32(p) \
  850. __kmp_test_then_add32((volatile kmp_int32 *)(p), 4)
  851. #define KMP_TEST_THEN_ADD4_64(p) \
  852. __kmp_test_then_add64((volatile kmp_int64 *)(p), 4LL)
  853. #define KMP_TEST_THEN_ADD4_ACQ64(p) \
  854. __kmp_test_then_add64((volatile kmp_int64 *)(p), 4LL)
  855. #define KMP_TEST_THEN_DEC32(p) \
  856. __kmp_test_then_add32((volatile kmp_int32 *)(p), -1)
  857. #define KMP_TEST_THEN_DEC_ACQ32(p) \
  858. __kmp_test_then_add32((volatile kmp_int32 *)(p), -1)
  859. #define KMP_TEST_THEN_DEC64(p) \
  860. __kmp_test_then_add64((volatile kmp_int64 *)(p), -1LL)
  861. #define KMP_TEST_THEN_DEC_ACQ64(p) \
  862. __kmp_test_then_add64((volatile kmp_int64 *)(p), -1LL)
  863. #define KMP_TEST_THEN_ADD8(p, v) \
  864. __kmp_test_then_add8((volatile kmp_int8 *)(p), (kmp_int8)(v))
  865. #define KMP_TEST_THEN_ADD32(p, v) \
  866. __kmp_test_then_add32((volatile kmp_int32 *)(p), (kmp_int32)(v))
  867. #define KMP_TEST_THEN_ADD64(p, v) \
  868. __kmp_test_then_add64((volatile kmp_int64 *)(p), (kmp_int64)(v))
  869. #define KMP_TEST_THEN_OR8(p, v) \
  870. __kmp_test_then_or8((volatile kmp_int8 *)(p), (kmp_int8)(v))
  871. #define KMP_TEST_THEN_AND8(p, v) \
  872. __kmp_test_then_and8((volatile kmp_int8 *)(p), (kmp_int8)(v))
  873. #define KMP_TEST_THEN_OR32(p, v) \
  874. __kmp_test_then_or32((volatile kmp_uint32 *)(p), (kmp_uint32)(v))
  875. #define KMP_TEST_THEN_AND32(p, v) \
  876. __kmp_test_then_and32((volatile kmp_uint32 *)(p), (kmp_uint32)(v))
  877. #define KMP_TEST_THEN_OR64(p, v) \
  878. __kmp_test_then_or64((volatile kmp_uint64 *)(p), (kmp_uint64)(v))
  879. #define KMP_TEST_THEN_AND64(p, v) \
  880. __kmp_test_then_and64((volatile kmp_uint64 *)(p), (kmp_uint64)(v))
  881. #define KMP_COMPARE_AND_STORE_ACQ8(p, cv, sv) \
  882. __kmp_compare_and_store8((volatile kmp_int8 *)(p), (kmp_int8)(cv), \
  883. (kmp_int8)(sv))
  884. #define KMP_COMPARE_AND_STORE_REL8(p, cv, sv) \
  885. __kmp_compare_and_store8((volatile kmp_int8 *)(p), (kmp_int8)(cv), \
  886. (kmp_int8)(sv))
  887. #define KMP_COMPARE_AND_STORE_ACQ16(p, cv, sv) \
  888. __kmp_compare_and_store16((volatile kmp_int16 *)(p), (kmp_int16)(cv), \
  889. (kmp_int16)(sv))
  890. #define KMP_COMPARE_AND_STORE_REL16(p, cv, sv) \
  891. __kmp_compare_and_store16((volatile kmp_int16 *)(p), (kmp_int16)(cv), \
  892. (kmp_int16)(sv))
  893. #define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv) \
  894. __kmp_compare_and_store32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  895. (kmp_int32)(sv))
  896. #define KMP_COMPARE_AND_STORE_REL32(p, cv, sv) \
  897. __kmp_compare_and_store32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  898. (kmp_int32)(sv))
  899. #define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) \
  900. __kmp_compare_and_store64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  901. (kmp_int64)(sv))
  902. #define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) \
  903. __kmp_compare_and_store64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  904. (kmp_int64)(sv))
  905. #if KMP_ARCH_X86
  906. #define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) \
  907. __kmp_compare_and_store32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  908. (kmp_int32)(sv))
  909. #else /* 64 bit pointers */
  910. #define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) \
  911. __kmp_compare_and_store64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  912. (kmp_int64)(sv))
  913. #endif /* KMP_ARCH_X86 */
  914. #define KMP_COMPARE_AND_STORE_RET8(p, cv, sv) \
  915. __kmp_compare_and_store_ret8((p), (cv), (sv))
  916. #define KMP_COMPARE_AND_STORE_RET16(p, cv, sv) \
  917. __kmp_compare_and_store_ret16((p), (cv), (sv))
  918. #define KMP_COMPARE_AND_STORE_RET32(p, cv, sv) \
  919. __kmp_compare_and_store_ret32((volatile kmp_int32 *)(p), (kmp_int32)(cv), \
  920. (kmp_int32)(sv))
  921. #define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) \
  922. __kmp_compare_and_store_ret64((volatile kmp_int64 *)(p), (kmp_int64)(cv), \
  923. (kmp_int64)(sv))
  924. #define KMP_XCHG_FIXED8(p, v) \
  925. __kmp_xchg_fixed8((volatile kmp_int8 *)(p), (kmp_int8)(v));
  926. #define KMP_XCHG_FIXED16(p, v) __kmp_xchg_fixed16((p), (v));
  927. #define KMP_XCHG_FIXED32(p, v) __kmp_xchg_fixed32((p), (v));
  928. #define KMP_XCHG_FIXED64(p, v) __kmp_xchg_fixed64((p), (v));
  929. #define KMP_XCHG_REAL32(p, v) __kmp_xchg_real32((p), (v));
  930. #define KMP_XCHG_REAL64(p, v) __kmp_xchg_real64((p), (v));
  931. #endif /* KMP_ASM_INTRINS */
  932. /* ------------- relaxed consistency memory model stuff ------------------ */
  933. #if KMP_OS_WINDOWS
  934. #ifdef __ABSOFT_WIN
  935. #define KMP_MB() asm("nop")
  936. #define KMP_IMB() asm("nop")
  937. #else
  938. #define KMP_MB() /* _asm{ nop } */
  939. #define KMP_IMB() /* _asm{ nop } */
  940. #endif
  941. #endif /* KMP_OS_WINDOWS */
  942. #if KMP_ARCH_PPC64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS || \
  943. KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64
  944. #if KMP_OS_WINDOWS
  945. #undef KMP_MB
  946. #define KMP_MB() std::atomic_thread_fence(std::memory_order_seq_cst)
  947. #else /* !KMP_OS_WINDOWS */
  948. #define KMP_MB() __sync_synchronize()
  949. #endif
  950. #endif
  951. #ifndef KMP_MB
  952. #define KMP_MB() /* nothing to do */
  953. #endif
  954. #if KMP_ARCH_X86 || KMP_ARCH_X86_64
  955. #if KMP_COMPILER_ICC || KMP_COMPILER_ICX
  956. #define KMP_MFENCE_() _mm_mfence()
  957. #define KMP_SFENCE_() _mm_sfence()
  958. #elif KMP_COMPILER_MSVC
  959. #define KMP_MFENCE_() MemoryBarrier()
  960. #define KMP_SFENCE_() MemoryBarrier()
  961. #else
  962. #define KMP_MFENCE_() __sync_synchronize()
  963. #define KMP_SFENCE_() __sync_synchronize()
  964. #endif
  965. #define KMP_MFENCE() \
  966. if (UNLIKELY(!__kmp_cpuinfo.initialized)) { \
  967. __kmp_query_cpuid(&__kmp_cpuinfo); \
  968. } \
  969. if (__kmp_cpuinfo.flags.sse2) { \
  970. KMP_MFENCE_(); \
  971. }
  972. #define KMP_SFENCE() KMP_SFENCE_()
  973. #else
  974. #define KMP_MFENCE() KMP_MB()
  975. #define KMP_SFENCE() KMP_MB()
  976. #endif
  977. #ifndef KMP_IMB
  978. #define KMP_IMB() /* nothing to do */
  979. #endif
  980. #ifndef KMP_ST_REL32
  981. #define KMP_ST_REL32(A, D) (*(A) = (D))
  982. #endif
  983. #ifndef KMP_ST_REL64
  984. #define KMP_ST_REL64(A, D) (*(A) = (D))
  985. #endif
  986. #ifndef KMP_LD_ACQ32
  987. #define KMP_LD_ACQ32(A) (*(A))
  988. #endif
  989. #ifndef KMP_LD_ACQ64
  990. #define KMP_LD_ACQ64(A) (*(A))
  991. #endif
  992. /* ------------------------------------------------------------------------ */
  993. // FIXME - maybe this should this be
  994. //
  995. // #define TCR_4(a) (*(volatile kmp_int32 *)(&a))
  996. // #define TCW_4(a,b) (a) = (*(volatile kmp_int32 *)&(b))
  997. //
  998. // #define TCR_8(a) (*(volatile kmp_int64 *)(a))
  999. // #define TCW_8(a,b) (a) = (*(volatile kmp_int64 *)(&b))
  1000. //
  1001. // I'm fairly certain this is the correct thing to do, but I'm afraid
  1002. // of performance regressions.
  1003. #define TCR_1(a) (a)
  1004. #define TCW_1(a, b) (a) = (b)
  1005. #define TCR_4(a) (a)
  1006. #define TCW_4(a, b) (a) = (b)
  1007. #define TCI_4(a) (++(a))
  1008. #define TCD_4(a) (--(a))
  1009. #define TCR_8(a) (a)
  1010. #define TCW_8(a, b) (a) = (b)
  1011. #define TCI_8(a) (++(a))
  1012. #define TCD_8(a) (--(a))
  1013. #define TCR_SYNC_4(a) (a)
  1014. #define TCW_SYNC_4(a, b) (a) = (b)
  1015. #define TCX_SYNC_4(a, b, c) \
  1016. KMP_COMPARE_AND_STORE_REL32((volatile kmp_int32 *)(volatile void *)&(a), \
  1017. (kmp_int32)(b), (kmp_int32)(c))
  1018. #define TCR_SYNC_8(a) (a)
  1019. #define TCW_SYNC_8(a, b) (a) = (b)
  1020. #define TCX_SYNC_8(a, b, c) \
  1021. KMP_COMPARE_AND_STORE_REL64((volatile kmp_int64 *)(volatile void *)&(a), \
  1022. (kmp_int64)(b), (kmp_int64)(c))
  1023. #if KMP_ARCH_X86 || KMP_ARCH_MIPS
  1024. // What about ARM?
  1025. #define TCR_PTR(a) ((void *)TCR_4(a))
  1026. #define TCW_PTR(a, b) TCW_4((a), (b))
  1027. #define TCR_SYNC_PTR(a) ((void *)TCR_SYNC_4(a))
  1028. #define TCW_SYNC_PTR(a, b) TCW_SYNC_4((a), (b))
  1029. #define TCX_SYNC_PTR(a, b, c) ((void *)TCX_SYNC_4((a), (b), (c)))
  1030. #else /* 64 bit pointers */
  1031. #define TCR_PTR(a) ((void *)TCR_8(a))
  1032. #define TCW_PTR(a, b) TCW_8((a), (b))
  1033. #define TCR_SYNC_PTR(a) ((void *)TCR_SYNC_8(a))
  1034. #define TCW_SYNC_PTR(a, b) TCW_SYNC_8((a), (b))
  1035. #define TCX_SYNC_PTR(a, b, c) ((void *)TCX_SYNC_8((a), (b), (c)))
  1036. #endif /* KMP_ARCH_X86 */
  1037. /* If these FTN_{TRUE,FALSE} values change, may need to change several places
  1038. where they are used to check that language is Fortran, not C. */
  1039. #ifndef FTN_TRUE
  1040. #define FTN_TRUE TRUE
  1041. #endif
  1042. #ifndef FTN_FALSE
  1043. #define FTN_FALSE FALSE
  1044. #endif
  1045. typedef void (*microtask_t)(int *gtid, int *npr, ...);
  1046. #ifdef USE_VOLATILE_CAST
  1047. #define VOLATILE_CAST(x) (volatile x)
  1048. #else
  1049. #define VOLATILE_CAST(x) (x)
  1050. #endif
  1051. #define KMP_WAIT __kmp_wait_4
  1052. #define KMP_WAIT_PTR __kmp_wait_4_ptr
  1053. #define KMP_EQ __kmp_eq_4
  1054. #define KMP_NEQ __kmp_neq_4
  1055. #define KMP_LT __kmp_lt_4
  1056. #define KMP_GE __kmp_ge_4
  1057. #define KMP_LE __kmp_le_4
  1058. /* Workaround for Intel(R) 64 code gen bug when taking address of static array
  1059. * (Intel(R) 64 Tracker #138) */
  1060. #if (KMP_ARCH_X86_64 || KMP_ARCH_PPC64) && KMP_OS_LINUX
  1061. #define STATIC_EFI2_WORKAROUND
  1062. #else
  1063. #define STATIC_EFI2_WORKAROUND static
  1064. #endif
  1065. // Support of BGET usage
  1066. #ifndef KMP_USE_BGET
  1067. #define KMP_USE_BGET 1
  1068. #endif
  1069. // Switches for OSS builds
  1070. #ifndef USE_CMPXCHG_FIX
  1071. #define USE_CMPXCHG_FIX 1
  1072. #endif
  1073. // Enable dynamic user lock
  1074. #define KMP_USE_DYNAMIC_LOCK 1
  1075. // Enable Intel(R) Transactional Synchronization Extensions (Intel(R) TSX) if
  1076. // dynamic user lock is turned on
  1077. #if KMP_USE_DYNAMIC_LOCK
  1078. // Visual studio can't handle the asm sections in this code
  1079. #define KMP_USE_TSX (KMP_ARCH_X86 || KMP_ARCH_X86_64) && !KMP_COMPILER_MSVC
  1080. #ifdef KMP_USE_ADAPTIVE_LOCKS
  1081. #undef KMP_USE_ADAPTIVE_LOCKS
  1082. #endif
  1083. #define KMP_USE_ADAPTIVE_LOCKS KMP_USE_TSX
  1084. #endif
  1085. // Enable tick time conversion of ticks to seconds
  1086. #if KMP_STATS_ENABLED
  1087. #define KMP_HAVE_TICK_TIME \
  1088. (KMP_OS_LINUX && (KMP_MIC || KMP_ARCH_X86 || KMP_ARCH_X86_64))
  1089. #endif
  1090. // Warning levels
  1091. enum kmp_warnings_level {
  1092. kmp_warnings_off = 0, /* No warnings */
  1093. kmp_warnings_low, /* Minimal warnings (default) */
  1094. kmp_warnings_explicit = 6, /* Explicitly set to ON - more warnings */
  1095. kmp_warnings_verbose /* reserved */
  1096. };
  1097. #ifdef __cplusplus
  1098. } // extern "C"
  1099. #endif // __cplusplus
  1100. // Safe C API
  1101. #include "kmp_safe_c_api.h"
  1102. // Macros for C++11 atomic functions
  1103. #define KMP_ATOMIC_LD(p, order) (p)->load(std::memory_order_##order)
  1104. #define KMP_ATOMIC_OP(op, p, v, order) (p)->op(v, std::memory_order_##order)
  1105. // For non-default load/store
  1106. #define KMP_ATOMIC_LD_ACQ(p) KMP_ATOMIC_LD(p, acquire)
  1107. #define KMP_ATOMIC_LD_RLX(p) KMP_ATOMIC_LD(p, relaxed)
  1108. #define KMP_ATOMIC_ST_REL(p, v) KMP_ATOMIC_OP(store, p, v, release)
  1109. #define KMP_ATOMIC_ST_RLX(p, v) KMP_ATOMIC_OP(store, p, v, relaxed)
  1110. // For non-default fetch_<op>
  1111. #define KMP_ATOMIC_ADD(p, v) KMP_ATOMIC_OP(fetch_add, p, v, acq_rel)
  1112. #define KMP_ATOMIC_SUB(p, v) KMP_ATOMIC_OP(fetch_sub, p, v, acq_rel)
  1113. #define KMP_ATOMIC_AND(p, v) KMP_ATOMIC_OP(fetch_and, p, v, acq_rel)
  1114. #define KMP_ATOMIC_OR(p, v) KMP_ATOMIC_OP(fetch_or, p, v, acq_rel)
  1115. #define KMP_ATOMIC_INC(p) KMP_ATOMIC_OP(fetch_add, p, 1, acq_rel)
  1116. #define KMP_ATOMIC_DEC(p) KMP_ATOMIC_OP(fetch_sub, p, 1, acq_rel)
  1117. #define KMP_ATOMIC_ADD_RLX(p, v) KMP_ATOMIC_OP(fetch_add, p, v, relaxed)
  1118. #define KMP_ATOMIC_INC_RLX(p) KMP_ATOMIC_OP(fetch_add, p, 1, relaxed)
  1119. // Callers of the following functions cannot see the side effect on "expected".
  1120. template <typename T>
  1121. bool __kmp_atomic_compare_store(std::atomic<T> *p, T expected, T desired) {
  1122. return p->compare_exchange_strong(
  1123. expected, desired, std::memory_order_acq_rel, std::memory_order_relaxed);
  1124. }
  1125. template <typename T>
  1126. bool __kmp_atomic_compare_store_acq(std::atomic<T> *p, T expected, T desired) {
  1127. return p->compare_exchange_strong(
  1128. expected, desired, std::memory_order_acquire, std::memory_order_relaxed);
  1129. }
  1130. template <typename T>
  1131. bool __kmp_atomic_compare_store_rel(std::atomic<T> *p, T expected, T desired) {
  1132. return p->compare_exchange_strong(
  1133. expected, desired, std::memory_order_release, std::memory_order_relaxed);
  1134. }
  1135. // Symbol lookup on Linux/Windows
  1136. #if KMP_OS_WINDOWS
  1137. extern void *__kmp_lookup_symbol(const char *name);
  1138. #define KMP_DLSYM(name) __kmp_lookup_symbol(name)
  1139. #define KMP_DLSYM_NEXT(name) nullptr
  1140. #else
  1141. #define KMP_DLSYM(name) dlsym(RTLD_DEFAULT, name)
  1142. #define KMP_DLSYM_NEXT(name) dlsym(RTLD_NEXT, name)
  1143. #endif
  1144. #endif /* KMP_OS_H */