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: 42588 $
4  * $Date: 2013-08-13 01:26:00 -0500 (Tue, 13 Aug 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 //
355 // Synchronization primitives
356 //
357 
358 #if KMP_ASM_INTRINS
359 
360 /* cast p to correct type so that proper intrinsic will be used */
361 # define KMP_TEST_THEN_INC32(p) __sync_fetch_and_add( (kmp_int32 *)(p), 1 )
362 # define KMP_TEST_THEN_INC_ACQ32(p) __sync_fetch_and_add( (kmp_int32 *)(p), 1 )
363 # define KMP_TEST_THEN_INC64(p) __sync_fetch_and_add( (kmp_int64 *)(p), 1LL )
364 # define KMP_TEST_THEN_INC_ACQ64(p) __sync_fetch_and_add( (kmp_int64 *)(p), 1LL )
365 # define KMP_TEST_THEN_ADD4_32(p) __sync_fetch_and_add( (kmp_int32 *)(p), 4 )
366 # define KMP_TEST_THEN_ADD4_ACQ32(p) __sync_fetch_and_add( (kmp_int32 *)(p), 4 )
367 # define KMP_TEST_THEN_ADD4_64(p) __sync_fetch_and_add( (kmp_int64 *)(p), 4LL )
368 # define KMP_TEST_THEN_ADD4_ACQ64(p) __sync_fetch_and_add( (kmp_int64 *)(p), 4LL )
369 # define KMP_TEST_THEN_DEC32(p) __sync_fetch_and_sub( (kmp_int32 *)(p), 1 )
370 # define KMP_TEST_THEN_DEC_ACQ32(p) __sync_fetch_and_sub( (kmp_int32 *)(p), 1 )
371 # define KMP_TEST_THEN_DEC64(p) __sync_fetch_and_sub( (kmp_int64 *)(p), 1LL )
372 # define KMP_TEST_THEN_DEC_ACQ64(p) __sync_fetch_and_sub( (kmp_int64 *)(p), 1LL )
373 # define KMP_TEST_THEN_ADD32(p, v) __sync_fetch_and_add( (kmp_int32 *)(p), (v) )
374 # define KMP_TEST_THEN_ADD64(p, v) __sync_fetch_and_add( (kmp_int64 *)(p), (v) )
375 
376 # define KMP_TEST_THEN_OR32(p, v) __sync_fetch_and_or( (kmp_int32 *)(p), (v) )
377 # define KMP_TEST_THEN_AND32(p, v) __sync_fetch_and_and( (kmp_int32 *)(p), (v) )
378 # define KMP_TEST_THEN_OR64(p, v) __sync_fetch_and_or( (kmp_int64 *)(p), (v) )
379 # define KMP_TEST_THEN_AND64(p, v) __sync_fetch_and_and( (kmp_int64 *)(p), (v) )
380 
381 # define KMP_COMPARE_AND_STORE_ACQ8(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint8 *)(p),(kmp_uint8)(cv),(kmp_uint8)(sv) )
382 # define KMP_COMPARE_AND_STORE_REL8(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint8 *)(p),(kmp_uint8)(cv),(kmp_uint8)(sv) )
383 # define KMP_COMPARE_AND_STORE_ACQ16(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint16 *)(p),(kmp_uint16)(cv),(kmp_uint16)(sv) )
384 # define KMP_COMPARE_AND_STORE_REL16(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint16 *)(p),(kmp_uint16)(cv),(kmp_uint16)(sv) )
385 # define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint32 *)(p),(kmp_uint32)(cv),(kmp_uint32)(sv) )
386 # define KMP_COMPARE_AND_STORE_REL32(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint32 *)(p),(kmp_uint32)(cv),(kmp_uint32)(sv) )
387 # define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint64 *)(p),(kmp_uint64)(cv),(kmp_uint64)(sv) )
388 # define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) __sync_bool_compare_and_swap( (volatile kmp_uint64 *)(p),(kmp_uint64)(cv),(kmp_uint64)(sv) )
389 # define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) __sync_bool_compare_and_swap( (volatile void **)(p),(void *)(cv),(void *)(sv) )
390 
391 # define KMP_COMPARE_AND_STORE_RET8(p, cv, sv) __sync_val_compare_and_swap( (volatile kmp_uint8 *)(p),(kmp_uint8)(cv),(kmp_uint8)(sv) )
392 # define KMP_COMPARE_AND_STORE_RET16(p, cv, sv) __sync_val_compare_and_swap( (volatile kmp_uint16 *)(p),(kmp_uint16)(cv),(kmp_uint16)(sv) )
393 # define KMP_COMPARE_AND_STORE_RET32(p, cv, sv) __sync_val_compare_and_swap( (volatile kmp_uint32 *)(p),(kmp_uint32)(cv),(kmp_uint32)(sv) )
394 # define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) __sync_val_compare_and_swap( (volatile kmp_uint64 *)(p),(kmp_uint64)(cv),(kmp_uint64)(sv) )
395 
396 #define KMP_XCHG_FIXED8(p, v) __sync_lock_test_and_set( (volatile kmp_uint8 *)(p), (kmp_uint8)(v) )
397 #define KMP_XCHG_FIXED16(p, v) __sync_lock_test_and_set( (volatile kmp_uint16 *)(p), (kmp_uint16)(v) )
398 #define KMP_XCHG_FIXED32(p, v) __sync_lock_test_and_set( (volatile kmp_uint32 *)(p), (kmp_uint32)(v) )
399 #define KMP_XCHG_FIXED64(p, v) __sync_lock_test_and_set( (volatile kmp_uint64 *)(p), (kmp_uint64)(v) )
400 
401 inline kmp_real32 KMP_XCHG_REAL32( volatile kmp_real32 *p, kmp_real32 v)
402 {
403  kmp_int32 tmp = __sync_lock_test_and_set( (kmp_int32*)p, *(kmp_int32*)&v);
404  return *(kmp_real32*)&tmp;
405 }
406 
407 static kmp_real64 KMP_XCHG_REAL64( volatile kmp_real64 *p, kmp_real64 v)
408 {
409  kmp_int64 tmp = __sync_lock_test_and_set( (kmp_int64*)p, *(kmp_int64*)&v);
410  return *(kmp_real64*)&tmp;
411 }
412 
413 #else
414 
415 extern kmp_int32 __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 v );
416 extern kmp_int32 __kmp_test_then_or32( volatile kmp_int32 *p, kmp_int32 v );
417 extern kmp_int32 __kmp_test_then_and32( volatile kmp_int32 *p, kmp_int32 v );
418 extern kmp_int64 __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 v );
419 extern kmp_int64 __kmp_test_then_or64( volatile kmp_int64 *p, kmp_int64 v );
420 extern kmp_int64 __kmp_test_then_and64( volatile kmp_int64 *p, kmp_int64 v );
421 
422 extern kmp_int8 __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
423 extern kmp_int16 __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
424 extern kmp_int32 __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
425 extern kmp_int32 __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
426 extern kmp_int8 __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
427 extern kmp_int16 __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
428 extern kmp_int32 __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
429 extern kmp_int64 __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
430 
431 extern kmp_int8 __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 v );
432 extern kmp_int16 __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 v );
433 extern kmp_int32 __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 v );
434 extern kmp_int64 __kmp_xchg_fixed64( volatile kmp_int64 *p, kmp_int64 v );
435 extern kmp_real32 __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 v );
436 extern kmp_real64 __kmp_xchg_real64( volatile kmp_real64 *p, kmp_real64 v );
437 
438 # define KMP_TEST_THEN_INC32(p) __kmp_test_then_add32( (p), 1 )
439 # define KMP_TEST_THEN_INC_ACQ32(p) __kmp_test_then_add32( (p), 1 )
440 # define KMP_TEST_THEN_INC64(p) __kmp_test_then_add64( (p), 1LL )
441 # define KMP_TEST_THEN_INC_ACQ64(p) __kmp_test_then_add64( (p), 1LL )
442 # define KMP_TEST_THEN_ADD4_32(p) __kmp_test_then_add32( (p), 4 )
443 # define KMP_TEST_THEN_ADD4_ACQ32(p) __kmp_test_then_add32( (p), 4 )
444 # define KMP_TEST_THEN_ADD4_64(p) __kmp_test_then_add64( (p), 4LL )
445 # define KMP_TEST_THEN_ADD4_ACQ64(p) __kmp_test_then_add64( (p), 4LL )
446 # define KMP_TEST_THEN_DEC32(p) __kmp_test_then_add32( (p), -1 )
447 # define KMP_TEST_THEN_DEC_ACQ32(p) __kmp_test_then_add32( (p), -1 )
448 # define KMP_TEST_THEN_DEC64(p) __kmp_test_then_add64( (p), -1LL )
449 # define KMP_TEST_THEN_DEC_ACQ64(p) __kmp_test_then_add64( (p), -1LL )
450 # define KMP_TEST_THEN_ADD32(p, v) __kmp_test_then_add32( (p), (v) )
451 # define KMP_TEST_THEN_ADD64(p, v) __kmp_test_then_add64( (p), (v) )
452 
453 # define KMP_TEST_THEN_OR32(p, v) __kmp_test_then_or32( (p), (v) )
454 # define KMP_TEST_THEN_AND32(p, v) __kmp_test_then_and32( (p), (v) )
455 # define KMP_TEST_THEN_OR64(p, v) __kmp_test_then_or64( (p), (v) )
456 # define KMP_TEST_THEN_AND64(p, v) __kmp_test_then_and64( (p), (v) )
457 
458 # define KMP_COMPARE_AND_STORE_ACQ8(p, cv, sv) __kmp_compare_and_store8( (p), (cv), (sv) )
459 # define KMP_COMPARE_AND_STORE_REL8(p, cv, sv) __kmp_compare_and_store8( (p), (cv), (sv) )
460 # define KMP_COMPARE_AND_STORE_ACQ16(p, cv, sv) __kmp_compare_and_store16( (p), (cv), (sv) )
461 # define KMP_COMPARE_AND_STORE_REL16(p, cv, sv) __kmp_compare_and_store16( (p), (cv), (sv) )
462 # define KMP_COMPARE_AND_STORE_ACQ32(p, cv, sv) __kmp_compare_and_store32( (p), (cv), (sv) )
463 # define KMP_COMPARE_AND_STORE_REL32(p, cv, sv) __kmp_compare_and_store32( (p), (cv), (sv) )
464 # define KMP_COMPARE_AND_STORE_ACQ64(p, cv, sv) __kmp_compare_and_store64( (p), (cv), (sv) )
465 # define KMP_COMPARE_AND_STORE_REL64(p, cv, sv) __kmp_compare_and_store64( (p), (cv), (sv) )
466 
467 # if KMP_ARCH_X86
468 # define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) __kmp_compare_and_store32( (volatile kmp_int32*)(p), (kmp_int32)(cv), (kmp_int32)(sv) )
469 # else /* 64 bit pointers */
470 # define KMP_COMPARE_AND_STORE_PTR(p, cv, sv) __kmp_compare_and_store64( (volatile kmp_int64*)(p), (kmp_int64)(cv), (kmp_int64)(sv) )
471 # endif /* KMP_ARCH_X86 */
472 
473 # define KMP_COMPARE_AND_STORE_RET8(p, cv, sv) __kmp_compare_and_store_ret8( (p), (cv), (sv) )
474 # define KMP_COMPARE_AND_STORE_RET16(p, cv, sv) __kmp_compare_and_store_ret16( (p), (cv), (sv) )
475 # define KMP_COMPARE_AND_STORE_RET32(p, cv, sv) __kmp_compare_and_store_ret32( (p), (cv), (sv) )
476 # define KMP_COMPARE_AND_STORE_RET64(p, cv, sv) __kmp_compare_and_store_ret64( (p), (cv), (sv) )
477 
478 # define KMP_XCHG_FIXED8(p, v) __kmp_xchg_fixed8( (p), (v) );
479 # define KMP_XCHG_FIXED16(p, v) __kmp_xchg_fixed16( (p), (v) );
480 # define KMP_XCHG_FIXED32(p, v) __kmp_xchg_fixed32( (p), (v) );
481 # define KMP_XCHG_FIXED64(p, v) __kmp_xchg_fixed64( (p), (v) );
482 # define KMP_XCHG_REAL32(p, v) __kmp_xchg_real32( (p), (v) );
483 # define KMP_XCHG_REAL64(p, v) __kmp_xchg_real64( (p), (v) );
484 
485 #endif /* KMP_ASM_INTRINS */
486 
487 # if !KMP_MIC
488 //
489 // no routines for floating addition on MIC
490 // no intrinsic support for floating addition on UNIX
491 //
492 extern kmp_real32 __kmp_test_then_add_real32 ( volatile kmp_real32 *p, kmp_real32 v );
493 extern kmp_real64 __kmp_test_then_add_real64 ( volatile kmp_real64 *p, kmp_real64 v );
494 # define KMP_TEST_THEN_ADD_REAL32(p, v) __kmp_test_then_add_real32( (p), (v) )
495 # define KMP_TEST_THEN_ADD_REAL64(p, v) __kmp_test_then_add_real64( (p), (v) )
496 # endif
497 
498 
499 /* ------------- relaxed consistency memory model stuff ------------------ */
500 
501 #if KMP_OS_WINDOWS
502 # ifdef __ABSOFT_WIN
503 # define KMP_MB() asm ("nop")
504 # define KMP_IMB() asm ("nop")
505 # else
506 # define KMP_MB() /* _asm{ nop } */
507 # define KMP_IMB() /* _asm{ nop } */
508 # endif
509 #endif /* KMP_OS_WINDOWS */
510 
511 #ifndef KMP_MB
512 # define KMP_MB() /* nothing to do */
513 #endif
514 
515 #ifndef KMP_IMB
516 # define KMP_IMB() /* nothing to do */
517 #endif
518 
519 #ifndef KMP_ST_REL32
520 # define KMP_ST_REL32(A,D) ( *(A) = (D) )
521 #endif
522 
523 #ifndef KMP_ST_REL64
524 # define KMP_ST_REL64(A,D) ( *(A) = (D) )
525 #endif
526 
527 #ifndef KMP_LD_ACQ32
528 # define KMP_LD_ACQ32(A) ( *(A) )
529 #endif
530 
531 #ifndef KMP_LD_ACQ64
532 # define KMP_LD_ACQ64(A) ( *(A) )
533 #endif
534 
535 /* ------------------------------------------------------------------------ */
536 //
537 // FIXME - maybe this should this be
538 //
539 // #define TCR_4(a) (*(volatile kmp_int32 *)(&a))
540 // #define TCW_4(a,b) (a) = (*(volatile kmp_int32 *)&(b))
541 //
542 // #define TCR_8(a) (*(volatile kmp_int64 *)(a))
543 // #define TCW_8(a,b) (a) = (*(volatile kmp_int64 *)(&b))
544 //
545 // I'm fairly certain this is the correct thing to do, but I'm afraid
546 // of performance regressions.
547 //
548 
549 #define TCR_4(a) (a)
550 #define TCW_4(a,b) (a) = (b)
551 #define TCR_8(a) (a)
552 #define TCW_8(a,b) (a) = (b)
553 #define TCR_SYNC_4(a) (a)
554 #define TCW_SYNC_4(a,b) (a) = (b)
555 #define TCX_SYNC_4(a,b,c) KMP_COMPARE_AND_STORE_REL32((volatile kmp_int32 *)(volatile void *)&(a), (kmp_int32)(b), (kmp_int32)(c))
556 #define TCR_SYNC_8(a) (a)
557 #define TCW_SYNC_8(a,b) (a) = (b)
558 #define TCX_SYNC_8(a,b,c) KMP_COMPARE_AND_STORE_REL64((volatile kmp_int64 *)(volatile void *)&(a), (kmp_int64)(b), (kmp_int64)(c))
559 
560 #if KMP_ARCH_X86
561 
562  #define TCR_PTR(a) ((void *)TCR_4(a))
563  #define TCW_PTR(a,b) TCW_4((a),(b))
564  #define TCR_SYNC_PTR(a) ((void *)TCR_SYNC_4(a))
565  #define TCW_SYNC_PTR(a,b) TCW_SYNC_4((a),(b))
566  #define TCX_SYNC_PTR(a,b,c) ((void *)TCX_SYNC_4((a),(b),(c)))
567 
568 #else /* 64 bit pointers */
569 
570  #define TCR_PTR(a) ((void *)TCR_8(a))
571  #define TCW_PTR(a,b) TCW_8((a),(b))
572  #define TCR_SYNC_PTR(a) ((void *)TCR_SYNC_8(a))
573  #define TCW_SYNC_PTR(a,b) TCW_SYNC_8((a),(b))
574  #define TCX_SYNC_PTR(a,b,c) ((void *)TCX_SYNC_8((a),(b),(c)))
575 
576 #endif /* KMP_ARCH_X86 */
577 
578 /*
579  * If these FTN_{TRUE,FALSE} values change, may need to
580  * change several places where they are used to check that
581  * language is Fortran, not C.
582  */
583 
584 #ifndef FTN_TRUE
585 # define FTN_TRUE TRUE
586 #endif
587 
588 #ifndef FTN_FALSE
589 # define FTN_FALSE FALSE
590 #endif
591 
592 typedef void (*microtask_t)( int *gtid, int *npr, ... );
593 
594 #ifdef USE_VOLATILE_CAST
595 # define VOLATILE_CAST(x) (volatile x)
596 #else
597 # define VOLATILE_CAST(x) (x)
598 #endif
599 
600 #ifdef KMP_I8
601 # define KMP_WAIT_YIELD __kmp_wait_yield_8
602 # define KMP_EQ __kmp_eq_8
603 # define KMP_NEQ __kmp_neq_8
604 # define KMP_LT __kmp_lt_8
605 # define KMP_GE __kmp_ge_8
606 # define KMP_LE __kmp_le_8
607 #else
608 # define KMP_WAIT_YIELD __kmp_wait_yield_4
609 # define KMP_EQ __kmp_eq_4
610 # define KMP_NEQ __kmp_neq_4
611 # define KMP_LT __kmp_lt_4
612 # define KMP_GE __kmp_ge_4
613 # define KMP_LE __kmp_le_4
614 #endif /* KMP_I8 */
615 
616 /* Workaround for Intel(R) 64 code gen bug when taking address of static array (Intel(R) 64 Tracker #138) */
617 #if KMP_ARCH_X86_64 && KMP_OS_LINUX
618 # define STATIC_EFI2_WORKAROUND
619 #else
620 # define STATIC_EFI2_WORKAROUND static
621 #endif
622 
623 // Support of BGET usage
624 #ifndef KMP_USE_BGET
625 #define KMP_USE_BGET 1
626 #endif
627 
628 
629 // Warning levels
630 enum kmp_warnings_level {
631  kmp_warnings_off = 0, /* No warnings */
632  kmp_warnings_low, /* Minimal warmings (default) */
633  kmp_warnings_explicit = 6, /* Explicitly set to ON - more warnings */
634  kmp_warnings_verbose /* reserved */
635 };
636 
637 #ifdef __cplusplus
638 } // extern "C"
639 #endif // __cplusplus
640 
641 #endif /* KMP_OS_H */