Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Groups Pages
kmp_os.h
1 /*
2  * kmp_os.h -- KPTS runtime header file.
3  * $Revision: 42489 $
4  * $Date: 2013-07-08 11:00:09 -0500 (Mon, 08 Jul 2013) $
5  */
6 
7 /* <copyright>
8  Copyright (c) 1997-2013 Intel Corporation. All Rights Reserved.
9 
10  Redistribution and use in source and binary forms, with or without
11  modification, are permitted provided that the following conditions
12  are met:
13 
14  * Redistributions of source code must retain the above copyright
15  notice, this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright
17  notice, this list of conditions and the following disclaimer in the
18  documentation and/or other materials provided with the distribution.
19  * Neither the name of Intel Corporation nor the names of its
20  contributors may be used to endorse or promote products derived
21  from this software without specific prior written permission.
22 
23  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 
35 </copyright> */
36 
37 #ifndef KMP_OS_H
38 #define KMP_OS_H
39 
40 #include <stdlib.h>
41 
42 #define KMP_FTN_PLAIN 1
43 #define KMP_FTN_APPEND 2
44 #define KMP_FTN_UPPER 3
45 /*
46 #define KMP_FTN_PREPEND 4
47 #define KMP_FTN_UAPPEND 5
48 */
49 
50 #define KMP_PTR_SKIP (sizeof(void*))
51 
52 /* -------------------------- Compiler variations ------------------------ */
53 
54 #define KMP_OFF 0
55 #define KMP_ON 1
56 
57 #define KMP_MEM_CONS_VOLATILE 0
58 #define KMP_MEM_CONS_FENCE 1
59 
60 #ifndef KMP_MEM_CONS_MODEL
61 # define KMP_MEM_CONS_MODEL KMP_MEM_CONS_VOLATILE
62 #endif
63 
64 /* ---------------------- Operating system recognition ------------------- */
65 
66 #define KMP_OS_LINUX 0
67 #define KMP_OS_DARWIN 0
68 #define KMP_OS_WINDOWS 0
69 #define KMP_OS_UNIX 0 /* disjunction of KMP_OS_LINUX with KMP_OS_DARWIN */
70 
71 #define KMP_ARCH_X86 0
72 #define KMP_ARCH_X86_64 0
73 
74 #ifdef _WIN32
75 # undef KMP_OS_WINDOWS
76 # define KMP_OS_WINDOWS 1
77 #endif
78 
79 #if ( defined __APPLE__ && defined __MACH__ )
80 # undef KMP_OS_DARWIN
81 # define KMP_OS_DARWIN 1
82 #endif
83 
84 #if ( defined __linux )
85 # undef KMP_OS_LINUX
86 # define KMP_OS_LINUX 1
87 #endif
88 
89 #if (1 != KMP_OS_LINUX + KMP_OS_DARWIN + KMP_OS_WINDOWS)
90 # error Unknown OS
91 #endif
92 
93 #if KMP_OS_LINUX || KMP_OS_DARWIN
94 # undef KMP_OS_UNIX
95 # define KMP_OS_UNIX 1
96 #endif
97 
98 #if KMP_OS_WINDOWS
99 # if defined _M_AMD64
100 # undef KMP_ARCH_X86_64
101 # define KMP_ARCH_X86_64 1
102 # else
103 # undef KMP_ARCH_X86
104 # define KMP_ARCH_X86 1
105 # endif
106 #endif
107 
108 #if KMP_OS_UNIX
109 # if defined __x86_64
110 # undef KMP_ARCH_X86_64
111 # define KMP_ARCH_X86_64 1
112 # else
113 # undef KMP_ARCH_X86
114 # define KMP_ARCH_X86 1
115 # endif
116 #endif
117 
118 #if (1 != KMP_ARCH_X86 + KMP_ARCH_X86_64)
119 # error Unknown or unsupported architecture
120 #endif
121 
122 #if KMP_OS_WINDOWS
123 # if defined KMP_WIN_CDECL || !defined GUIDEDLL_EXPORTS
124 # define USE_FTN_CDECL KMP_FTN_UPPER
125 # endif
126 
127 # define KMP_FTN KMP_FTN_PLAIN
128 # define USE_FTN_EXTRA KMP_FTN_PLAIN
129 # if KMP_ARCH_X86
130 # if defined KMP_WIN_STDCALL || !defined GUIDEDLL_EXPORTS
131 # define USE_FTN_STDCALL KMP_FTN_UPPER
132 # endif
133 # endif
134  typedef char kmp_int8;
135  typedef unsigned char kmp_uint8;
136  typedef short kmp_int16;
137  typedef unsigned short kmp_uint16;
138  typedef int kmp_int32;
139  typedef unsigned int kmp_uint32;
140 # define KMP_INT32_SPEC "d"
141 # define KMP_UINT32_SPEC "u"
142 # ifndef KMP_STRUCT64
143  typedef __int64 kmp_int64;
144  typedef unsigned __int64 kmp_uint64;
145  #define KMP_INT64_SPEC "I64d"
146  #define KMP_UINT64_SPEC "I64u"
147 # else
148  struct kmp_struct64 {
149  kmp_int32 a,b;
150  };
151  typedef struct kmp_struct64 kmp_int64;
152  typedef struct kmp_struct64 kmp_uint64;
153  /* Not sure what to use for KMP_[U]INT64_SPEC here */
154 # endif
155 # if KMP_ARCH_X86_64
156 # define KMP_INTPTR 1
157  typedef __int64 kmp_intptr_t;
158  typedef unsigned __int64 kmp_uintptr_t;
159 # define KMP_INTPTR_SPEC "I64d"
160 # define KMP_UINTPTR_SPEC "I64u"
161 # endif
162 #endif /* KMP_OS_WINDOWS */
163 
164 #if KMP_OS_UNIX
165 # define KMP_FTN KMP_FTN_PLAIN
166 # define USE_FTN_CDECL KMP_FTN_PLAIN
167 # define USE_FTN_EXTRA KMP_FTN_APPEND
168  typedef char kmp_int8;
169  typedef unsigned char kmp_uint8;
170  typedef short kmp_int16;
171  typedef unsigned short kmp_uint16;
172  typedef int kmp_int32;
173  typedef unsigned int kmp_uint32;
174  typedef long long kmp_int64;
175  typedef unsigned long long kmp_uint64;
176 # define KMP_INT32_SPEC "d"
177 # define KMP_UINT32_SPEC "u"
178 # define KMP_INT64_SPEC "lld"
179 # define KMP_UINT64_SPEC "llu"
180 #endif /* KMP_OS_UNIX */
181 
182 #if KMP_ARCH_X86
183 # define KMP_SIZE_T_SPEC KMP_UINT32_SPEC
184 #elif KMP_ARCH_X86_64
185 # define KMP_SIZE_T_SPEC KMP_UINT64_SPEC
186 #else
187 # error "Can't determine size_t printf format specifier."
188 #endif
189 
190 #if KMP_ARCH_X86
191 # define KMP_SIZE_T_MAX (0xFFFFFFFF)
192 #else
193 # define KMP_SIZE_T_MAX (0xFFFFFFFFFFFFFFFF)
194 #endif
195 
196 typedef size_t kmp_size_t;
197 typedef float kmp_real32;
198 typedef double kmp_real64;
199 
200 #ifndef KMP_INTPTR
201 # define KMP_INTPTR 1
202  typedef long kmp_intptr_t;
203  typedef unsigned long kmp_uintptr_t;
204 # define KMP_INTPTR_SPEC "ld"
205 # define KMP_UINTPTR_SPEC "lu"
206 #endif
207 
208 #ifdef KMP_I8
209  typedef kmp_int64 kmp_int;
210  typedef kmp_uint64 kmp_uint;
211 # define KMP_INT_SPEC KMP_INT64_SPEC
212 # define KMP_UINT_SPEC KMP_UINT64_SPEC
213 # define KMP_INT_MAX ((kmp_int64)0x7FFFFFFFFFFFFFFFLL)
214 # define KMP_INT_MIN ((kmp_int64)0x8000000000000000LL)
215 #else
216  typedef kmp_int32 kmp_int;
217  typedef kmp_uint32 kmp_uint;
218 # define KMP_INT_SPEC KMP_INT32_SPEC
219 # define KMP_UINT_SPEC KMP_UINT32_SPEC
220 # define KMP_INT_MAX ((kmp_int32)0x7FFFFFFF)
221 # define KMP_INT_MIN ((kmp_int64)0x80000000)
222 #endif /* KMP_I8 */
223 
224 #ifdef __cplusplus
225  //-------------------------------------------------------------------------
226  // template for debug prints specification ( d, u, lld, llu ), and to obtain
227  // signed/unsigned flavors of a type
228  template< typename T >
229  struct traits_t {
230  typedef T signed_t;
231  typedef T unsigned_t;
232  typedef T floating_t;
233  static char const * spec;
234  };
235  // int
236  template<>
237  struct traits_t< signed int > {
238  typedef signed int signed_t;
239  typedef unsigned int unsigned_t;
240  typedef double floating_t;
241  static char const * spec;
242  };
243  // unsigned int
244  template<>
245  struct traits_t< unsigned int > {
246  typedef signed int signed_t;
247  typedef unsigned int unsigned_t;
248  typedef double floating_t;
249  static char const * spec;
250  };
251  // long long
252  template<>
253  struct traits_t< signed long long > {
254  typedef signed long long signed_t;
255  typedef unsigned long long unsigned_t;
256  typedef long double floating_t;
257  static char const * spec;
258  };
259  // unsigned long long
260  template<>
261  struct traits_t< unsigned long long > {
262  typedef signed long long signed_t;
263  typedef unsigned long long unsigned_t;
264  typedef long double floating_t;
265  static char const * spec;
266  };
267  //-------------------------------------------------------------------------
268 #endif // __cplusplus
269 
270 #if KMP_OS_WINDOWS
271 # define KMP_STDCALL __stdcall
272 #endif
273 
274 #ifndef KMP_STDCALL
275 # define KMP_STDCALL /* nothing */
276 #endif
277 
278 #define KMP_EXPORT extern /* export declaration in guide libraries */
279 
280 #if __GNUC__ == 4
281  #define __forceinline __inline
282 #endif
283 
284 #define PAGE_SIZE (0x4000)
285 #define PAGE_ALIGNED(_addr) ( ! ((size_t) _addr & \
286  (size_t)(PAGE_SIZE - 1)))
287 #define ALIGN_TO_PAGE(x) (void *)(((size_t)(x)) & ~((size_t)(PAGE_SIZE - 1)))
288 
289 /* ---------------------- Support for cache alignment, padding, etc. -----------------*/
290 
291 #ifdef __cplusplus
292 extern "C" {
293 #endif // __cplusplus
294 
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 it for a while...
301  #warning CACHE_LINE is too small.
302  #endif
303 #endif /* CACHE_LINE */
304 
305 /* SGI's cache padding improvements using align decl specs (Ver 19) */
306 #if !defined KMP_PERF_V19
307 # define KMP_PERF_V19 KMP_ON
308 #endif
309 
310 /* SGI's improvements for inline argv (Ver 106) */
311 #if !defined KMP_PERF_V106
312 # define KMP_PERF_V106 KMP_ON
313 #endif
314 
315 #define KMP_CACHE_PREFETCH(ADDR) /* nothing */
316 
317 /* Temporary note: if performance testing of this passes, we can remove
318  all references to KMP_DO_ALIGN and replace with KMP_ALIGN. */
319 #if KMP_OS_UNIX && defined(__GNUC__)
320 # define KMP_DO_ALIGN(bytes) __attribute__((aligned(bytes)))
321 # define KMP_ALIGN_CACHE __attribute__((aligned(CACHE_LINE)))
322 # define KMP_ALIGN(bytes) __attribute__((aligned(bytes)))
323 #else
324 # define KMP_DO_ALIGN(bytes) __declspec( align(bytes) )
325 # define KMP_ALIGN_CACHE __declspec( align(CACHE_LINE) )
326 # define KMP_ALIGN(bytes) __declspec( align(bytes) )
327 #endif
328 
329 #if defined(__MIC__) || defined(__MIC2__)
330  #define KMP_MIC 1
331 // Intel(R) Composer XE (13.0) defines both __MIC__ and __MIC2__ !
332 # if __MIC2__ || __KNC__
333  #define KMP_MIC1 0
334  #define KMP_MIC2 1
335 # else
336  #define KMP_MIC1 1
337  #define KMP_MIC2 0
338 # endif
339 #else
340  #define KMP_MIC 0
341  #define KMP_MIC1 0
342  #define KMP_MIC2 0
343 #endif
344 
345 /* General purpose fence types for memory operations */
346 enum kmp_mem_fence_type {
347  kmp_no_fence, /* No memory fence */
348  kmp_acquire_fence, /* Acquire (read) memory fence */
349  kmp_release_fence, /* Release (write) memory fence */
350  kmp_full_fence /* Full (read+write) memory fence */
351 };
352 
353 
354 #if KMP_MIC
355 /* cast ADDR to correct type so that proper intrinsic will be used */
356 # define KMP_TEST_THEN_INC32( ADDR ) __sync_fetch_and_add( (kmp_int32*)(ADDR), 1 )
357 //__atomic_fetch_add_explicit_4((ADDR),1,0)
358 # define KMP_TEST_THEN_INC_ACQ32( ADDR ) __sync_fetch_and_add( (kmp_int32*)(ADDR), 1 )
359 //__atomic_fetch_add_explicit_4((ADDR),1,0)
360 # define KMP_TEST_THEN_INC64( ADDR ) __sync_fetch_and_add( (kmp_int64*)(ADDR), 1LL )
361 //__atomic_fetch_add_explicit_8((ADDR),1LL,0)
362 # define KMP_TEST_THEN_INC_ACQ64( ADDR ) __sync_fetch_and_add( (kmp_int64*)(ADDR), 1LL )
363 //__atomic_fetch_add_explicit_8((ADDR),1LL,0)
364 # define KMP_TEST_THEN_ADD4_32( ADDR ) __sync_fetch_and_add( (kmp_int32*)(ADDR), 4 )
365 //__atomic_fetch_add_explicit_4((ADDR),4,0)
366 # define KMP_TEST_THEN_ADD4_ACQ32( ADDR ) __sync_fetch_and_add( (kmp_int32*)(ADDR), 4 )
367 //__atomic_fetch_add_explicit_4((ADDR),4,0)
368 # define KMP_TEST_THEN_ADD4_64( ADDR ) __sync_fetch_and_add( (kmp_int64*)(ADDR), 4LL )
369 //__atomic_fetch_add_explicit_8((ADDR),4LL,0)
370 # define KMP_TEST_THEN_ADD4_ACQ64( ADDR ) __sync_fetch_and_add( (kmp_int64*)(ADDR), 4LL )
371 //__atomic_fetch_add_explicit_8((ADDR),4LL,0)
372 # define KMP_TEST_THEN_DEC32( ADDR ) __sync_fetch_and_sub( (kmp_int32*)(ADDR), 1 )
373 //__atomic_fetch_sub_explicit_4((ADDR),1,0)
374 # define KMP_TEST_THEN_DEC_ACQ32( ADDR ) __sync_fetch_and_sub( (kmp_int32*)(ADDR), 1 )
375 //__atomic_fetch_sub_explicit_4((ADDR),1,0)
376 # define KMP_TEST_THEN_DEC64( ADDR ) __sync_fetch_and_sub( (kmp_int64*)(ADDR), 1LL )
377 //__atomic_fetch_sub_explicit_8((ADDR),1LL,0)
378 # define KMP_TEST_THEN_DEC_ACQ64( ADDR ) __sync_fetch_and_sub( (kmp_int64*)(ADDR), 1LL )
379 //__atomic_fetch_sub_explicit_8((ADDR),1LL,0)
380 # define KMP_TEST_THEN_ADD32( ADDR, INCR ) __sync_fetch_and_add( (kmp_int32*)(ADDR), (INCR) )
381 //__atomic_fetch_add_explicit_4((ADDR),(INCR),0)
382 # define KMP_TEST_THEN_ADD64( ADDR, INCR ) __sync_fetch_and_add( (kmp_int64*)(ADDR), (INCR) )
383 //__atomic_fetch_add_explicit_8((ADDR),(INCR),0)
384 # define KMP_COMPARE_AND_STORE_ACQ32(p,cv,sv) __sync_bool_compare_and_swap((volatile kmp_uint32*)(p),(kmp_uint32)(cv),(kmp_uint32)(sv))
385 # define KMP_COMPARE_AND_STORE_REL32(p,cv,sv) __sync_bool_compare_and_swap((volatile kmp_uint32*)(p),(kmp_uint32)(cv),(kmp_uint32)(sv))
386 # define KMP_COMPARE_AND_STORE_ACQ64(p,cv,sv) __sync_bool_compare_and_swap((volatile kmp_uint64*)(p),(kmp_uint64)(cv),(kmp_uint64)(sv))
387 # define KMP_COMPARE_AND_STORE_REL64(p,cv,sv) __sync_bool_compare_and_swap((volatile kmp_uint64*)(p),(kmp_uint64)(cv),(kmp_uint64)(sv))
388 # define KMP_COMPARE_AND_STORE_PTR(p,cv,sv) __sync_bool_compare_and_swap((volatile kmp_uint64*)(p),(kmp_uint64)(cv),(kmp_uint64)(sv))
389 // cannot use low-level CAS intrinsic because it has two pointer parameters (we often use 0 or 1)
390 #endif
391 
392 #if ! defined KMP_TEST_THEN_INC32
393 # define KMP_TEST_THEN_INC32( ADDR ) ( __kmp_test_then_add32( (ADDR), 1 ) )
394 #endif
395 #if ! defined KMP_TEST_THEN_INC_ACQ32
396 # define KMP_TEST_THEN_INC_ACQ32( ADDR ) ( __kmp_test_then_add32( (ADDR), 1 ) )
397 #endif
398 
399 #if ! defined KMP_TEST_THEN_INC64
400 # define KMP_TEST_THEN_INC64( ADDR ) ( __kmp_test_then_add64( (ADDR), 1LL ) )
401 #endif
402 #if ! defined KMP_TEST_THEN_INC_ACQ64
403 # define KMP_TEST_THEN_INC_ACQ64( ADDR ) ( __kmp_test_then_add64( (ADDR), 1LL ) )
404 #endif
405 
406 #if ! defined KMP_TEST_THEN_ADD4_32
407 # define KMP_TEST_THEN_ADD4_32( ADDR ) ( __kmp_test_then_add32( (ADDR), 4 ) )
408 #endif
409 #if ! defined KMP_TEST_THEN_ADD4_ACQ32
410 # define KMP_TEST_THEN_ADD4_ACQ32( ADDR ) ( __kmp_test_then_add32( (ADDR), 4 ) )
411 #endif
412 
413 #if ! defined KMP_TEST_THEN_ADD4_64
414 # define KMP_TEST_THEN_ADD4_64( ADDR ) ( __kmp_test_then_add64( (ADDR), 4LL ) )
415 #endif
416 #if ! defined KMP_TEST_THEN_ADD4_ACQ64
417 # define KMP_TEST_THEN_ADD4_ACQ64( ADDR ) ( __kmp_test_then_add64( (ADDR), 4LL ) )
418 #endif
419 
420 #if ! defined KMP_TEST_THEN_DEC32
421 # define KMP_TEST_THEN_DEC32( ADDR ) ( __kmp_test_then_add32( (ADDR), -1 ) )
422 #endif
423 #if !defined KMP_TEST_THEN_DEC_ACQ32
424 # define KMP_TEST_THEN_DEC_ACQ32( ADDR ) ( __kmp_test_then_add32( (ADDR), -1 ) )
425 #endif
426 
427 #if !defined KMP_TEST_THEN_DEC64
428 # define KMP_TEST_THEN_DEC64( ADDR ) ( __kmp_test_then_add64( (ADDR), -1LL ) )
429 #endif
430 #if !defined KMP_TEST_THEN_DEC_ACQ64
431 # define KMP_TEST_THEN_DEC_ACQ64( ADDR ) ( __kmp_test_then_add64( (ADDR), -1LL ) )
432 #endif
433 
434 #if !defined KMP_TEST_THEN_ADD32
435 # define KMP_TEST_THEN_ADD32( ADDR, INCR ) ( __kmp_test_then_add32( (ADDR), (INCR) ) )
436 #endif
437 
438 #if !defined KMP_TEST_THEN_ADD64
439 # define KMP_TEST_THEN_ADD64( ADDR, INCR ) ( __kmp_test_then_add64( (ADDR), (INCR) ) )
440 #endif
441 
442 /* ------------- relaxed consistency memory model stuff ------------------ */
443 
444 #if KMP_OS_WINDOWS
445 #if USE_ITT_BUILD
446 # ifdef USE_ITT
447 # define KMP_MB() /* _asm{ nop } */
448 # define KMP_IMB() /* _asm{ nop } */
449 # else
450 # ifdef __ABSOFT_WIN
451 # define KMP_MB() asm ("nop")
452 # define KMP_IMB() asm ("nop")
453 # else
454 # define KMP_MB() /* _asm{ nop } */
455 # define KMP_IMB() /* _asm{ nop } */
456 # endif
457 # endif /* USE_ITT */
458 #else
459 # ifdef __ABSOFT_WIN
460 # define KMP_MB() asm ("nop")
461 # define KMP_IMB() asm ("nop")
462 # else
463 # define KMP_MB() /* _asm{ nop } */
464 # define KMP_IMB() /* _asm{ nop } */
465 # endif
466 #endif /* USE_ITT_BUILD */
467 #endif /* KMP_OS_WINDOWS */
468 
469 #ifndef KMP_MB
470 # define KMP_MB() /* nothing to do */
471 #endif
472 
473 #ifndef KMP_IMB
474 # define KMP_IMB() /* nothing to do */
475 #endif
476 
477 #ifndef KMP_ST4_REL
478 # define KMP_ST4_REL(A,D) ( *(A) = (D) )
479 #endif
480 
481 #ifndef KMP_ST8_REL
482 # define KMP_ST8_REL(A,D) ( *(A) = (D) )
483 #endif
484 
485 #ifndef KMP_LD4_ACQ
486 # define KMP_LD4_ACQ(A) ( *(A) )
487 #endif
488 
489 #ifndef KMP_LD8_ACQ
490 # define KMP_LD8_ACQ(A) ( *(A) )
491 #endif
492 
493 /* ------------------------------------------------------------------------ */
494 //
495 // FIXME - maybe this should this be
496 //
497 // #define TCR_4(a) (*(volatile kmp_int32 *)(&a))
498 // #define TCW_4(a,b) (a) = (*(volatile kmp_int32 *)&(b))
499 //
500 // #define TCR_8(a) (*(volatile kmp_int64 *)(a))
501 // #define TCW_8(a,b) (a) = (*(volatile kmp_int64 *)(&b))
502 //
503 // I'm fairly certain this is the correct thing to do, but I'm afraid
504 // of performance regressions.
505 //
506 
507 #define TCR_4(a) (a)
508 #define TCW_4(a,b) (a) = (b)
509 #define TCR_8(a) (a)
510 #define TCW_8(a,b) (a) = (b)
511 #define TCR_SYNC_4(a) (a)
512 #define TCW_SYNC_4(a,b) (a) = (b)
513 #define TCX_SYNC_4(a,b,c) KMP_COMPARE_AND_STORE_REL32((volatile kmp_int32 *)(volatile void *)&(a), (kmp_int32)(b), (kmp_int32)(c))
514 #define TCR_SYNC_8(a) (a)
515 #define TCW_SYNC_8(a,b) (a) = (b)
516 #define TCX_SYNC_8(a,b,c) KMP_COMPARE_AND_STORE_REL64((volatile kmp_int64 *)(volatile void *)&(a), (kmp_int64)(b), (kmp_int64)(c))
517 
518 #if KMP_ARCH_X86
519 
520  #define TCR_PTR(a) ((void *)TCR_4(a))
521  #define TCW_PTR(a,b) TCW_4((a),(b))
522  #define TCR_SYNC_PTR(a) ((void *)TCR_SYNC_4(a))
523  #define TCW_SYNC_PTR(a,b) TCW_SYNC_4((a),(b))
524  #define TCX_SYNC_PTR(a,b,c) ((void *)TCX_SYNC_4((a),(b),(c)))
525 
526 #else /* 64 bit pointers */
527 
528  #define TCR_PTR(a) ((void *)TCR_8(a))
529  #define TCW_PTR(a,b) TCW_8((a),(b))
530  #define TCR_SYNC_PTR(a) ((void *)TCR_SYNC_8(a))
531  #define TCW_SYNC_PTR(a,b) TCW_SYNC_8((a),(b))
532  #define TCX_SYNC_PTR(a,b,c) ((void *)TCX_SYNC_8((a),(b),(c)))
533 
534 #endif /* KMP_ARCH_X86 */
535 
536 /*
537  * If these FTN_{TRUE,FALSE} values change, may need to
538  * change several places where they are used to check that
539  * language is Fortran, not C.
540  */
541 
542 #ifndef FTN_TRUE
543 # define FTN_TRUE TRUE
544 #endif
545 
546 #ifndef FTN_FALSE
547 # define FTN_FALSE FALSE
548 #endif
549 
550 typedef void (*microtask_t)( int *gtid, int *npr, ... );
551 
552 #ifdef USE_VOLATILE_CAST
553 # define VOLATILE_CAST(x) (volatile x)
554 #else
555 # define VOLATILE_CAST(x) (x)
556 #endif
557 
558 #ifdef KMP_I8
559 # define KMP_WAIT_YIELD __kmp_wait_yield_8
560 # define KMP_EQ __kmp_eq_8
561 # define KMP_NEQ __kmp_neq_8
562 # define KMP_LT __kmp_lt_8
563 # define KMP_GE __kmp_ge_8
564 # define KMP_LE __kmp_le_8
565 #else
566 # define KMP_WAIT_YIELD __kmp_wait_yield_4
567 # define KMP_EQ __kmp_eq_4
568 # define KMP_NEQ __kmp_neq_4
569 # define KMP_LT __kmp_lt_4
570 # define KMP_GE __kmp_ge_4
571 # define KMP_LE __kmp_le_4
572 #endif /* KMP_I8 */
573 
574 /* Workaround for Intel(R) 64 code gen bug when taking address of static array (Intel(R) 64 Tracker #138) */
575 #if KMP_ARCH_X86_64 && KMP_OS_LINUX
576 # define STATIC_EFI2_WORKAROUND
577 #else
578 # define STATIC_EFI2_WORKAROUND static
579 #endif
580 
581 // Support of BGET usage
582 #ifndef KMP_USE_BGET
583 #define KMP_USE_BGET 1
584 #endif
585 
586 
587 // Warning levels
588 enum kmp_warnings_level {
589  kmp_warnings_off = 0, /* No warnings */
590  kmp_warnings_low, /* Minimal warmings (default) */
591  kmp_warnings_explicit = 6, /* Explicitly set to ON - more warnings */
592  kmp_warnings_verbose /* reserved */
593 };
594 
595 #ifdef __cplusplus
596 } // extern "C"
597 #endif // __cplusplus
598 
599 #endif /* KMP_OS_H */