10b57cec5SDimitry Andric /*
20b57cec5SDimitry Andric  * kmp_ftn_entry.h -- Fortran entry linkage support for OpenMP.
30b57cec5SDimitry Andric  */
40b57cec5SDimitry Andric 
50b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
80b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
90b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef FTN_STDCALL
140b57cec5SDimitry Andric #error The support file kmp_ftn_entry.h should not be compiled by itself.
150b57cec5SDimitry Andric #endif
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #ifdef KMP_STUB
180b57cec5SDimitry Andric #include "kmp_stub.h"
190b57cec5SDimitry Andric #endif
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #include "kmp_i18n.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric // For affinity format functions
240b57cec5SDimitry Andric #include "kmp_io.h"
250b57cec5SDimitry Andric #include "kmp_str.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric #if OMPT_SUPPORT
280b57cec5SDimitry Andric #include "ompt-specific.h"
290b57cec5SDimitry Andric #endif
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #ifdef __cplusplus
320b57cec5SDimitry Andric extern "C" {
330b57cec5SDimitry Andric #endif // __cplusplus
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric /* For compatibility with the Gnu/MS Open MP codegen, omp_set_num_threads(),
360b57cec5SDimitry Andric  * omp_set_nested(), and omp_set_dynamic() [in lowercase on MS, and w/o
370b57cec5SDimitry Andric  * a trailing underscore on Linux* OS] take call by value integer arguments.
380b57cec5SDimitry Andric  * + omp_set_max_active_levels()
390b57cec5SDimitry Andric  * + omp_set_schedule()
400b57cec5SDimitry Andric  *
410b57cec5SDimitry Andric  * For backward compatibility with 9.1 and previous Intel compiler, these
420b57cec5SDimitry Andric  * entry points take call by reference integer arguments. */
430b57cec5SDimitry Andric #ifdef KMP_GOMP_COMPAT
440b57cec5SDimitry Andric #if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_UPPER)
450b57cec5SDimitry Andric #define PASS_ARGS_BY_VALUE 1
460b57cec5SDimitry Andric #endif
470b57cec5SDimitry Andric #endif
480b57cec5SDimitry Andric #if KMP_OS_WINDOWS
490b57cec5SDimitry Andric #if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_APPEND)
500b57cec5SDimitry Andric #define PASS_ARGS_BY_VALUE 1
510b57cec5SDimitry Andric #endif
520b57cec5SDimitry Andric #endif
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric // This macro helps to reduce code duplication.
550b57cec5SDimitry Andric #ifdef PASS_ARGS_BY_VALUE
560b57cec5SDimitry Andric #define KMP_DEREF
570b57cec5SDimitry Andric #else
580b57cec5SDimitry Andric #define KMP_DEREF *
590b57cec5SDimitry Andric #endif
600b57cec5SDimitry Andric 
61fe6060f1SDimitry Andric // For API with specific C vs. Fortran interfaces (ompc_* exists in
62fe6060f1SDimitry Andric // kmp_csupport.cpp), only create GOMP versioned symbols of the API for the
63fe6060f1SDimitry Andric // APPEND Fortran entries in this file. The GOMP versioned symbols of the C API
64fe6060f1SDimitry Andric // will take place where the ompc_* functions are defined.
65fe6060f1SDimitry Andric #if KMP_FTN_ENTRIES == KMP_FTN_APPEND
66fe6060f1SDimitry Andric #define KMP_EXPAND_NAME_IF_APPEND(name) KMP_EXPAND_NAME(name)
67fe6060f1SDimitry Andric #else
68fe6060f1SDimitry Andric #define KMP_EXPAND_NAME_IF_APPEND(name) name
69fe6060f1SDimitry Andric #endif
70fe6060f1SDimitry Andric 
FTN_SET_STACKSIZE(int KMP_DEREF arg)710b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_STACKSIZE(int KMP_DEREF arg) {
720b57cec5SDimitry Andric #ifdef KMP_STUB
730b57cec5SDimitry Andric   __kmps_set_stacksize(KMP_DEREF arg);
740b57cec5SDimitry Andric #else
750b57cec5SDimitry Andric   // __kmp_aux_set_stacksize initializes the library if needed
760b57cec5SDimitry Andric   __kmp_aux_set_stacksize((size_t)KMP_DEREF arg);
770b57cec5SDimitry Andric #endif
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
FTN_SET_STACKSIZE_S(size_t KMP_DEREF arg)800b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_STACKSIZE_S(size_t KMP_DEREF arg) {
810b57cec5SDimitry Andric #ifdef KMP_STUB
820b57cec5SDimitry Andric   __kmps_set_stacksize(KMP_DEREF arg);
830b57cec5SDimitry Andric #else
840b57cec5SDimitry Andric   // __kmp_aux_set_stacksize initializes the library if needed
850b57cec5SDimitry Andric   __kmp_aux_set_stacksize(KMP_DEREF arg);
860b57cec5SDimitry Andric #endif
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
FTN_GET_STACKSIZE(void)890b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_STACKSIZE(void) {
900b57cec5SDimitry Andric #ifdef KMP_STUB
91e8d8bef9SDimitry Andric   return (int)__kmps_get_stacksize();
920b57cec5SDimitry Andric #else
930b57cec5SDimitry Andric   if (!__kmp_init_serial) {
940b57cec5SDimitry Andric     __kmp_serial_initialize();
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric   return (int)__kmp_stksize;
970b57cec5SDimitry Andric #endif
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
FTN_GET_STACKSIZE_S(void)1000b57cec5SDimitry Andric size_t FTN_STDCALL FTN_GET_STACKSIZE_S(void) {
1010b57cec5SDimitry Andric #ifdef KMP_STUB
1020b57cec5SDimitry Andric   return __kmps_get_stacksize();
1030b57cec5SDimitry Andric #else
1040b57cec5SDimitry Andric   if (!__kmp_init_serial) {
1050b57cec5SDimitry Andric     __kmp_serial_initialize();
1060b57cec5SDimitry Andric   }
1070b57cec5SDimitry Andric   return __kmp_stksize;
1080b57cec5SDimitry Andric #endif
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric 
FTN_SET_BLOCKTIME(int KMP_DEREF arg)1110b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_BLOCKTIME(int KMP_DEREF arg) {
1120b57cec5SDimitry Andric #ifdef KMP_STUB
1130b57cec5SDimitry Andric   __kmps_set_blocktime(KMP_DEREF arg);
1140b57cec5SDimitry Andric #else
1155f757f3fSDimitry Andric   int gtid, tid, bt = (KMP_DEREF arg);
1160b57cec5SDimitry Andric   kmp_info_t *thread;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
1190b57cec5SDimitry Andric   tid = __kmp_tid_from_gtid(gtid);
1200b57cec5SDimitry Andric   thread = __kmp_thread_from_gtid(gtid);
1210b57cec5SDimitry Andric 
1225f757f3fSDimitry Andric   __kmp_aux_convert_blocktime(&bt);
1235f757f3fSDimitry Andric   __kmp_aux_set_blocktime(bt, thread, tid);
1240b57cec5SDimitry Andric #endif
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
1275f757f3fSDimitry Andric // Gets blocktime in units used for KMP_BLOCKTIME, ms otherwise
FTN_GET_BLOCKTIME(void)1280b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_BLOCKTIME(void) {
1290b57cec5SDimitry Andric #ifdef KMP_STUB
1300b57cec5SDimitry Andric   return __kmps_get_blocktime();
1310b57cec5SDimitry Andric #else
1320b57cec5SDimitry Andric   int gtid, tid;
1330b57cec5SDimitry Andric   kmp_team_p *team;
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
1360b57cec5SDimitry Andric   tid = __kmp_tid_from_gtid(gtid);
1370b57cec5SDimitry Andric   team = __kmp_threads[gtid]->th.th_team;
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   /* These must match the settings used in __kmp_wait_sleep() */
1400b57cec5SDimitry Andric   if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
1415f757f3fSDimitry Andric     KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d%cs\n", gtid,
1425f757f3fSDimitry Andric                   team->t.t_id, tid, KMP_MAX_BLOCKTIME, __kmp_blocktime_units));
1430b57cec5SDimitry Andric     return KMP_MAX_BLOCKTIME;
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric #ifdef KMP_ADJUST_BLOCKTIME
1460b57cec5SDimitry Andric   else if (__kmp_zero_bt && !get__bt_set(team, tid)) {
1475f757f3fSDimitry Andric     KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d%cs\n", gtid,
1485f757f3fSDimitry Andric                   team->t.t_id, tid, 0, __kmp_blocktime_units));
1490b57cec5SDimitry Andric     return 0;
1500b57cec5SDimitry Andric   }
1510b57cec5SDimitry Andric #endif /* KMP_ADJUST_BLOCKTIME */
1520b57cec5SDimitry Andric   else {
1535f757f3fSDimitry Andric     int bt = get__blocktime(team, tid);
1545f757f3fSDimitry Andric     if (__kmp_blocktime_units == 'm')
1555f757f3fSDimitry Andric       bt = bt / 1000;
1565f757f3fSDimitry Andric     KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d%cs\n", gtid,
1575f757f3fSDimitry Andric                   team->t.t_id, tid, bt, __kmp_blocktime_units));
1585f757f3fSDimitry Andric     return bt;
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric #endif
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
FTN_SET_LIBRARY_SERIAL(void)1630b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_LIBRARY_SERIAL(void) {
1640b57cec5SDimitry Andric #ifdef KMP_STUB
1650b57cec5SDimitry Andric   __kmps_set_library(library_serial);
1660b57cec5SDimitry Andric #else
1670b57cec5SDimitry Andric   // __kmp_user_set_library initializes the library if needed
1680b57cec5SDimitry Andric   __kmp_user_set_library(library_serial);
1690b57cec5SDimitry Andric #endif
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
FTN_SET_LIBRARY_TURNAROUND(void)1720b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_LIBRARY_TURNAROUND(void) {
1730b57cec5SDimitry Andric #ifdef KMP_STUB
1740b57cec5SDimitry Andric   __kmps_set_library(library_turnaround);
1750b57cec5SDimitry Andric #else
1760b57cec5SDimitry Andric   // __kmp_user_set_library initializes the library if needed
1770b57cec5SDimitry Andric   __kmp_user_set_library(library_turnaround);
1780b57cec5SDimitry Andric #endif
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric 
FTN_SET_LIBRARY_THROUGHPUT(void)1810b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_LIBRARY_THROUGHPUT(void) {
1820b57cec5SDimitry Andric #ifdef KMP_STUB
1830b57cec5SDimitry Andric   __kmps_set_library(library_throughput);
1840b57cec5SDimitry Andric #else
1850b57cec5SDimitry Andric   // __kmp_user_set_library initializes the library if needed
1860b57cec5SDimitry Andric   __kmp_user_set_library(library_throughput);
1870b57cec5SDimitry Andric #endif
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric 
FTN_SET_LIBRARY(int KMP_DEREF arg)1900b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_LIBRARY(int KMP_DEREF arg) {
1910b57cec5SDimitry Andric #ifdef KMP_STUB
1920b57cec5SDimitry Andric   __kmps_set_library(KMP_DEREF arg);
1930b57cec5SDimitry Andric #else
1940b57cec5SDimitry Andric   enum library_type lib;
1950b57cec5SDimitry Andric   lib = (enum library_type)KMP_DEREF arg;
1960b57cec5SDimitry Andric   // __kmp_user_set_library initializes the library if needed
1970b57cec5SDimitry Andric   __kmp_user_set_library(lib);
1980b57cec5SDimitry Andric #endif
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
FTN_GET_LIBRARY(void)2010b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_LIBRARY(void) {
2020b57cec5SDimitry Andric #ifdef KMP_STUB
2030b57cec5SDimitry Andric   return __kmps_get_library();
2040b57cec5SDimitry Andric #else
2050b57cec5SDimitry Andric   if (!__kmp_init_serial) {
2060b57cec5SDimitry Andric     __kmp_serial_initialize();
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric   return ((int)__kmp_library);
2090b57cec5SDimitry Andric #endif
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric 
FTN_SET_DISP_NUM_BUFFERS(int KMP_DEREF arg)2120b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_DISP_NUM_BUFFERS(int KMP_DEREF arg) {
2130b57cec5SDimitry Andric #ifdef KMP_STUB
2140b57cec5SDimitry Andric   ; // empty routine
2150b57cec5SDimitry Andric #else
2160b57cec5SDimitry Andric   // ignore after initialization because some teams have already
2170b57cec5SDimitry Andric   // allocated dispatch buffers
218fe6060f1SDimitry Andric   int num_buffers = KMP_DEREF arg;
219fe6060f1SDimitry Andric   if (__kmp_init_serial == FALSE && num_buffers >= KMP_MIN_DISP_NUM_BUFF &&
220fe6060f1SDimitry Andric       num_buffers <= KMP_MAX_DISP_NUM_BUFF) {
221fe6060f1SDimitry Andric     __kmp_dispatch_num_buffers = num_buffers;
222fe6060f1SDimitry Andric   }
2230b57cec5SDimitry Andric #endif
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
FTN_SET_AFFINITY(void ** mask)2260b57cec5SDimitry Andric int FTN_STDCALL FTN_SET_AFFINITY(void **mask) {
2270b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
2280b57cec5SDimitry Andric   return -1;
2290b57cec5SDimitry Andric #else
2300b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
2310b57cec5SDimitry Andric     __kmp_middle_initialize();
2320b57cec5SDimitry Andric   }
233fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
2340b57cec5SDimitry Andric   return __kmp_aux_set_affinity(mask);
2350b57cec5SDimitry Andric #endif
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric 
FTN_GET_AFFINITY(void ** mask)2380b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_AFFINITY(void **mask) {
2390b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
2400b57cec5SDimitry Andric   return -1;
2410b57cec5SDimitry Andric #else
2420b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
2430b57cec5SDimitry Andric     __kmp_middle_initialize();
2440b57cec5SDimitry Andric   }
245fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
246fcaf7f86SDimitry Andric   int gtid = __kmp_get_gtid();
247bdd1243dSDimitry Andric   if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 &&
248bdd1243dSDimitry Andric       __kmp_affinity.flags.reset) {
249fcaf7f86SDimitry Andric     __kmp_reset_root_init_mask(gtid);
250fcaf7f86SDimitry Andric   }
2510b57cec5SDimitry Andric   return __kmp_aux_get_affinity(mask);
2520b57cec5SDimitry Andric #endif
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
FTN_GET_AFFINITY_MAX_PROC(void)2550b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_AFFINITY_MAX_PROC(void) {
2560b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
2570b57cec5SDimitry Andric   return 0;
2580b57cec5SDimitry Andric #else
2590b57cec5SDimitry Andric   // We really only NEED serial initialization here.
2600b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
2610b57cec5SDimitry Andric     __kmp_middle_initialize();
2620b57cec5SDimitry Andric   }
263fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
2640b57cec5SDimitry Andric   return __kmp_aux_get_affinity_max_proc();
2650b57cec5SDimitry Andric #endif
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric 
FTN_CREATE_AFFINITY_MASK(void ** mask)2680b57cec5SDimitry Andric void FTN_STDCALL FTN_CREATE_AFFINITY_MASK(void **mask) {
2690b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
2700b57cec5SDimitry Andric   *mask = NULL;
2710b57cec5SDimitry Andric #else
2720b57cec5SDimitry Andric   // We really only NEED serial initialization here.
2730b57cec5SDimitry Andric   kmp_affin_mask_t *mask_internals;
2740b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
2750b57cec5SDimitry Andric     __kmp_middle_initialize();
2760b57cec5SDimitry Andric   }
277fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
2780b57cec5SDimitry Andric   mask_internals = __kmp_affinity_dispatch->allocate_mask();
2790b57cec5SDimitry Andric   KMP_CPU_ZERO(mask_internals);
2800b57cec5SDimitry Andric   *mask = mask_internals;
2810b57cec5SDimitry Andric #endif
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
FTN_DESTROY_AFFINITY_MASK(void ** mask)2840b57cec5SDimitry Andric void FTN_STDCALL FTN_DESTROY_AFFINITY_MASK(void **mask) {
2850b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
2860b57cec5SDimitry Andric // Nothing
2870b57cec5SDimitry Andric #else
2880b57cec5SDimitry Andric   // We really only NEED serial initialization here.
2890b57cec5SDimitry Andric   kmp_affin_mask_t *mask_internals;
2900b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
2910b57cec5SDimitry Andric     __kmp_middle_initialize();
2920b57cec5SDimitry Andric   }
293fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
2940b57cec5SDimitry Andric   if (__kmp_env_consistency_check) {
2950b57cec5SDimitry Andric     if (*mask == NULL) {
2960b57cec5SDimitry Andric       KMP_FATAL(AffinityInvalidMask, "kmp_destroy_affinity_mask");
2970b57cec5SDimitry Andric     }
2980b57cec5SDimitry Andric   }
2990b57cec5SDimitry Andric   mask_internals = (kmp_affin_mask_t *)(*mask);
3000b57cec5SDimitry Andric   __kmp_affinity_dispatch->deallocate_mask(mask_internals);
3010b57cec5SDimitry Andric   *mask = NULL;
3020b57cec5SDimitry Andric #endif
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
FTN_SET_AFFINITY_MASK_PROC(int KMP_DEREF proc,void ** mask)3050b57cec5SDimitry Andric int FTN_STDCALL FTN_SET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
3060b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
3070b57cec5SDimitry Andric   return -1;
3080b57cec5SDimitry Andric #else
3090b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
3100b57cec5SDimitry Andric     __kmp_middle_initialize();
3110b57cec5SDimitry Andric   }
312fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
3130b57cec5SDimitry Andric   return __kmp_aux_set_affinity_mask_proc(KMP_DEREF proc, mask);
3140b57cec5SDimitry Andric #endif
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
FTN_UNSET_AFFINITY_MASK_PROC(int KMP_DEREF proc,void ** mask)3170b57cec5SDimitry Andric int FTN_STDCALL FTN_UNSET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
3180b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
3190b57cec5SDimitry Andric   return -1;
3200b57cec5SDimitry Andric #else
3210b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
3220b57cec5SDimitry Andric     __kmp_middle_initialize();
3230b57cec5SDimitry Andric   }
324fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
3250b57cec5SDimitry Andric   return __kmp_aux_unset_affinity_mask_proc(KMP_DEREF proc, mask);
3260b57cec5SDimitry Andric #endif
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
FTN_GET_AFFINITY_MASK_PROC(int KMP_DEREF proc,void ** mask)3290b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
3300b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
3310b57cec5SDimitry Andric   return -1;
3320b57cec5SDimitry Andric #else
3330b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
3340b57cec5SDimitry Andric     __kmp_middle_initialize();
3350b57cec5SDimitry Andric   }
336fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
3370b57cec5SDimitry Andric   return __kmp_aux_get_affinity_mask_proc(KMP_DEREF proc, mask);
3380b57cec5SDimitry Andric #endif
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric /* ------------------------------------------------------------------------ */
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric /* sets the requested number of threads for the next parallel region */
KMP_EXPAND_NAME(FTN_SET_NUM_THREADS)3440b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NUM_THREADS)(int KMP_DEREF arg) {
3450b57cec5SDimitry Andric #ifdef KMP_STUB
3460b57cec5SDimitry Andric // Nothing.
3470b57cec5SDimitry Andric #else
3480b57cec5SDimitry Andric   __kmp_set_num_threads(KMP_DEREF arg, __kmp_entry_gtid());
3490b57cec5SDimitry Andric #endif
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric /* returns the number of threads in current team */
KMP_EXPAND_NAME(FTN_GET_NUM_THREADS)3530b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_THREADS)(void) {
3540b57cec5SDimitry Andric #ifdef KMP_STUB
3550b57cec5SDimitry Andric   return 1;
3560b57cec5SDimitry Andric #else
3570b57cec5SDimitry Andric   // __kmpc_bound_num_threads initializes the library if needed
3580b57cec5SDimitry Andric   return __kmpc_bound_num_threads(NULL);
3590b57cec5SDimitry Andric #endif
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_MAX_THREADS)3620b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_THREADS)(void) {
3630b57cec5SDimitry Andric #ifdef KMP_STUB
3640b57cec5SDimitry Andric   return 1;
3650b57cec5SDimitry Andric #else
3660b57cec5SDimitry Andric   int gtid;
3670b57cec5SDimitry Andric   kmp_info_t *thread;
3680b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
3690b57cec5SDimitry Andric     __kmp_middle_initialize();
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
3720b57cec5SDimitry Andric   thread = __kmp_threads[gtid];
373fcaf7f86SDimitry Andric #if KMP_AFFINITY_SUPPORTED
374bdd1243dSDimitry Andric   if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {
375fcaf7f86SDimitry Andric     __kmp_assign_root_init_mask();
376fcaf7f86SDimitry Andric   }
377fcaf7f86SDimitry Andric #endif
3780b57cec5SDimitry Andric   // return thread -> th.th_team -> t.t_current_task[
3790b57cec5SDimitry Andric   // thread->th.th_info.ds.ds_tid ] -> icvs.nproc;
3800b57cec5SDimitry Andric   return thread->th.th_current_task->td_icvs.nproc;
3810b57cec5SDimitry Andric #endif
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric 
FTN_CONTROL_TOOL(int command,int modifier,void * arg)3840b57cec5SDimitry Andric int FTN_STDCALL FTN_CONTROL_TOOL(int command, int modifier, void *arg) {
3850b57cec5SDimitry Andric #if defined(KMP_STUB) || !OMPT_SUPPORT
3860b57cec5SDimitry Andric   return -2;
3870b57cec5SDimitry Andric #else
3880b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(__kmp_entry_gtid());
3890b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
3900b57cec5SDimitry Andric     return -2;
3910b57cec5SDimitry Andric   }
3920b57cec5SDimitry Andric   kmp_info_t *this_thr = __kmp_threads[__kmp_entry_gtid()];
3930b57cec5SDimitry Andric   ompt_task_info_t *parent_task_info = OMPT_CUR_TASK_INFO(this_thr);
3940b57cec5SDimitry Andric   parent_task_info->frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
3950b57cec5SDimitry Andric   int ret = __kmp_control_tool(command, modifier, arg);
3960b57cec5SDimitry Andric   parent_task_info->frame.enter_frame.ptr = 0;
3970b57cec5SDimitry Andric   return ret;
3980b57cec5SDimitry Andric #endif
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric /* OpenMP 5.0 Memory Management support */
4020b57cec5SDimitry Andric omp_allocator_handle_t FTN_STDCALL
FTN_INIT_ALLOCATOR(omp_memspace_handle_t KMP_DEREF m,int KMP_DEREF ntraits,omp_alloctrait_t tr[])4030b57cec5SDimitry Andric FTN_INIT_ALLOCATOR(omp_memspace_handle_t KMP_DEREF m, int KMP_DEREF ntraits,
4040b57cec5SDimitry Andric                    omp_alloctrait_t tr[]) {
4050b57cec5SDimitry Andric #ifdef KMP_STUB
4060b57cec5SDimitry Andric   return NULL;
4070b57cec5SDimitry Andric #else
4080b57cec5SDimitry Andric   return __kmpc_init_allocator(__kmp_entry_gtid(), KMP_DEREF m,
4090b57cec5SDimitry Andric                                KMP_DEREF ntraits, tr);
4100b57cec5SDimitry Andric #endif
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric 
FTN_DESTROY_ALLOCATOR(omp_allocator_handle_t al)4130b57cec5SDimitry Andric void FTN_STDCALL FTN_DESTROY_ALLOCATOR(omp_allocator_handle_t al) {
4140b57cec5SDimitry Andric #ifndef KMP_STUB
4150b57cec5SDimitry Andric   __kmpc_destroy_allocator(__kmp_entry_gtid(), al);
4160b57cec5SDimitry Andric #endif
4170b57cec5SDimitry Andric }
FTN_SET_DEFAULT_ALLOCATOR(omp_allocator_handle_t al)4180b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_DEFAULT_ALLOCATOR(omp_allocator_handle_t al) {
4190b57cec5SDimitry Andric #ifndef KMP_STUB
4200b57cec5SDimitry Andric   __kmpc_set_default_allocator(__kmp_entry_gtid(), al);
4210b57cec5SDimitry Andric #endif
4220b57cec5SDimitry Andric }
FTN_GET_DEFAULT_ALLOCATOR(void)4230b57cec5SDimitry Andric omp_allocator_handle_t FTN_STDCALL FTN_GET_DEFAULT_ALLOCATOR(void) {
4240b57cec5SDimitry Andric #ifdef KMP_STUB
4250b57cec5SDimitry Andric   return NULL;
4260b57cec5SDimitry Andric #else
4270b57cec5SDimitry Andric   return __kmpc_get_default_allocator(__kmp_entry_gtid());
4280b57cec5SDimitry Andric #endif
4290b57cec5SDimitry Andric }
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric /* OpenMP 5.0 affinity format support */
4320b57cec5SDimitry Andric #ifndef KMP_STUB
__kmp_fortran_strncpy_truncate(char * buffer,size_t buf_size,char const * csrc,size_t csrc_size)4330b57cec5SDimitry Andric static void __kmp_fortran_strncpy_truncate(char *buffer, size_t buf_size,
4340b57cec5SDimitry Andric                                            char const *csrc, size_t csrc_size) {
4350b57cec5SDimitry Andric   size_t capped_src_size = csrc_size;
4360b57cec5SDimitry Andric   if (csrc_size >= buf_size) {
4370b57cec5SDimitry Andric     capped_src_size = buf_size - 1;
4380b57cec5SDimitry Andric   }
4390b57cec5SDimitry Andric   KMP_STRNCPY_S(buffer, buf_size, csrc, capped_src_size);
4400b57cec5SDimitry Andric   if (csrc_size >= buf_size) {
4410b57cec5SDimitry Andric     KMP_DEBUG_ASSERT(buffer[buf_size - 1] == '\0');
4420b57cec5SDimitry Andric     buffer[buf_size - 1] = csrc[buf_size - 1];
4430b57cec5SDimitry Andric   } else {
4440b57cec5SDimitry Andric     for (size_t i = csrc_size; i < buf_size; ++i)
4450b57cec5SDimitry Andric       buffer[i] = ' ';
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric // Convert a Fortran string to a C string by adding null byte
4500b57cec5SDimitry Andric class ConvertedString {
4510b57cec5SDimitry Andric   char *buf;
4520b57cec5SDimitry Andric   kmp_info_t *th;
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric public:
ConvertedString(char const * fortran_str,size_t size)4550b57cec5SDimitry Andric   ConvertedString(char const *fortran_str, size_t size) {
4560b57cec5SDimitry Andric     th = __kmp_get_thread();
4570b57cec5SDimitry Andric     buf = (char *)__kmp_thread_malloc(th, size + 1);
4580b57cec5SDimitry Andric     KMP_STRNCPY_S(buf, size + 1, fortran_str, size);
4590b57cec5SDimitry Andric     buf[size] = '\0';
4600b57cec5SDimitry Andric   }
~ConvertedString()4610b57cec5SDimitry Andric   ~ConvertedString() { __kmp_thread_free(th, buf); }
get()4620b57cec5SDimitry Andric   const char *get() const { return buf; }
4630b57cec5SDimitry Andric };
4640b57cec5SDimitry Andric #endif // KMP_STUB
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric /*
4670b57cec5SDimitry Andric  * Set the value of the affinity-format-var ICV on the current device to the
4680b57cec5SDimitry Andric  * format specified in the argument.
4690b57cec5SDimitry Andric  */
KMP_EXPAND_NAME_IF_APPEND(FTN_SET_AFFINITY_FORMAT)470fe6060f1SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_SET_AFFINITY_FORMAT)(
471fe6060f1SDimitry Andric     char const *format, size_t size) {
4720b57cec5SDimitry Andric #ifdef KMP_STUB
4730b57cec5SDimitry Andric   return;
4740b57cec5SDimitry Andric #else
4750b57cec5SDimitry Andric   if (!__kmp_init_serial) {
4760b57cec5SDimitry Andric     __kmp_serial_initialize();
4770b57cec5SDimitry Andric   }
4780b57cec5SDimitry Andric   ConvertedString cformat(format, size);
4790b57cec5SDimitry Andric   // Since the __kmp_affinity_format variable is a C string, do not
4800b57cec5SDimitry Andric   // use the fortran strncpy function
4810b57cec5SDimitry Andric   __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE,
4820b57cec5SDimitry Andric                          cformat.get(), KMP_STRLEN(cformat.get()));
4830b57cec5SDimitry Andric #endif
4840b57cec5SDimitry Andric }
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric /*
4870b57cec5SDimitry Andric  * Returns the number of characters required to hold the entire affinity format
4880b57cec5SDimitry Andric  * specification (not including null byte character) and writes the value of the
4890b57cec5SDimitry Andric  * affinity-format-var ICV on the current device to buffer. If the return value
4900b57cec5SDimitry Andric  * is larger than size, the affinity format specification is truncated.
4910b57cec5SDimitry Andric  */
KMP_EXPAND_NAME_IF_APPEND(FTN_GET_AFFINITY_FORMAT)492fe6060f1SDimitry Andric size_t FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_GET_AFFINITY_FORMAT)(
493fe6060f1SDimitry Andric     char *buffer, size_t size) {
4940b57cec5SDimitry Andric #ifdef KMP_STUB
4950b57cec5SDimitry Andric   return 0;
4960b57cec5SDimitry Andric #else
4970b57cec5SDimitry Andric   size_t format_size;
4980b57cec5SDimitry Andric   if (!__kmp_init_serial) {
4990b57cec5SDimitry Andric     __kmp_serial_initialize();
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric   format_size = KMP_STRLEN(__kmp_affinity_format);
5020b57cec5SDimitry Andric   if (buffer && size) {
5030b57cec5SDimitry Andric     __kmp_fortran_strncpy_truncate(buffer, size, __kmp_affinity_format,
5040b57cec5SDimitry Andric                                    format_size);
5050b57cec5SDimitry Andric   }
5060b57cec5SDimitry Andric   return format_size;
5070b57cec5SDimitry Andric #endif
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric /*
5110b57cec5SDimitry Andric  * Prints the thread affinity information of the current thread in the format
5120b57cec5SDimitry Andric  * specified by the format argument. If the format is NULL or a zero-length
5130b57cec5SDimitry Andric  * string, the value of the affinity-format-var ICV is used.
5140b57cec5SDimitry Andric  */
KMP_EXPAND_NAME_IF_APPEND(FTN_DISPLAY_AFFINITY)515fe6060f1SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_DISPLAY_AFFINITY)(
516fe6060f1SDimitry Andric     char const *format, size_t size) {
5170b57cec5SDimitry Andric #ifdef KMP_STUB
5180b57cec5SDimitry Andric   return;
5190b57cec5SDimitry Andric #else
5200b57cec5SDimitry Andric   int gtid;
5210b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
5220b57cec5SDimitry Andric     __kmp_middle_initialize();
5230b57cec5SDimitry Andric   }
524fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
5250b57cec5SDimitry Andric   gtid = __kmp_get_gtid();
526fcaf7f86SDimitry Andric #if KMP_AFFINITY_SUPPORTED
527bdd1243dSDimitry Andric   if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 &&
528bdd1243dSDimitry Andric       __kmp_affinity.flags.reset) {
529fcaf7f86SDimitry Andric     __kmp_reset_root_init_mask(gtid);
530fcaf7f86SDimitry Andric   }
531fcaf7f86SDimitry Andric #endif
5320b57cec5SDimitry Andric   ConvertedString cformat(format, size);
5330b57cec5SDimitry Andric   __kmp_aux_display_affinity(gtid, cformat.get());
5340b57cec5SDimitry Andric #endif
5350b57cec5SDimitry Andric }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric /*
5380b57cec5SDimitry Andric  * Returns the number of characters required to hold the entire affinity format
5390b57cec5SDimitry Andric  * specification (not including null byte) and prints the thread affinity
5400b57cec5SDimitry Andric  * information of the current thread into the character string buffer with the
5410b57cec5SDimitry Andric  * size of size in the format specified by the format argument. If the format is
5420b57cec5SDimitry Andric  * NULL or a zero-length string, the value of the affinity-format-var ICV is
5430b57cec5SDimitry Andric  * used. The buffer must be allocated prior to calling the routine. If the
5440b57cec5SDimitry Andric  * return value is larger than size, the affinity format specification is
5450b57cec5SDimitry Andric  * truncated.
5460b57cec5SDimitry Andric  */
KMP_EXPAND_NAME_IF_APPEND(FTN_CAPTURE_AFFINITY)547fe6060f1SDimitry Andric size_t FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_CAPTURE_AFFINITY)(
548fe6060f1SDimitry Andric     char *buffer, char const *format, size_t buf_size, size_t for_size) {
5490b57cec5SDimitry Andric #if defined(KMP_STUB)
5500b57cec5SDimitry Andric   return 0;
5510b57cec5SDimitry Andric #else
5520b57cec5SDimitry Andric   int gtid;
5530b57cec5SDimitry Andric   size_t num_required;
5540b57cec5SDimitry Andric   kmp_str_buf_t capture_buf;
5550b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
5560b57cec5SDimitry Andric     __kmp_middle_initialize();
5570b57cec5SDimitry Andric   }
558fe6060f1SDimitry Andric   __kmp_assign_root_init_mask();
5590b57cec5SDimitry Andric   gtid = __kmp_get_gtid();
560fcaf7f86SDimitry Andric #if KMP_AFFINITY_SUPPORTED
561bdd1243dSDimitry Andric   if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 &&
562bdd1243dSDimitry Andric       __kmp_affinity.flags.reset) {
563fcaf7f86SDimitry Andric     __kmp_reset_root_init_mask(gtid);
564fcaf7f86SDimitry Andric   }
565fcaf7f86SDimitry Andric #endif
5660b57cec5SDimitry Andric   __kmp_str_buf_init(&capture_buf);
5670b57cec5SDimitry Andric   ConvertedString cformat(format, for_size);
5680b57cec5SDimitry Andric   num_required = __kmp_aux_capture_affinity(gtid, cformat.get(), &capture_buf);
5690b57cec5SDimitry Andric   if (buffer && buf_size) {
5700b57cec5SDimitry Andric     __kmp_fortran_strncpy_truncate(buffer, buf_size, capture_buf.str,
5710b57cec5SDimitry Andric                                    capture_buf.used);
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric   __kmp_str_buf_free(&capture_buf);
5740b57cec5SDimitry Andric   return num_required;
5750b57cec5SDimitry Andric #endif
5760b57cec5SDimitry Andric }
5770b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)5780b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {
5790b57cec5SDimitry Andric #ifdef KMP_STUB
5800b57cec5SDimitry Andric   return 0;
5810b57cec5SDimitry Andric #else
5820b57cec5SDimitry Andric   int gtid;
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric #if KMP_OS_DARWIN || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD ||    \
5851db9f3b2SDimitry Andric     KMP_OS_OPENBSD || KMP_OS_HURD || KMP_OS_SOLARIS || KMP_OS_AIX
5860b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
5870b57cec5SDimitry Andric #elif KMP_OS_WINDOWS
5880b57cec5SDimitry Andric   if (!__kmp_init_parallel ||
5890b57cec5SDimitry Andric       (gtid = (int)((kmp_intptr_t)TlsGetValue(__kmp_gtid_threadprivate_key))) ==
5900b57cec5SDimitry Andric           0) {
5910b57cec5SDimitry Andric     // Either library isn't initialized or thread is not registered
5920b57cec5SDimitry Andric     // 0 is the correct TID in this case
5930b57cec5SDimitry Andric     return 0;
5940b57cec5SDimitry Andric   }
5950b57cec5SDimitry Andric   --gtid; // We keep (gtid+1) in TLS
5965f757f3fSDimitry Andric #elif KMP_OS_LINUX || KMP_OS_WASI
5970b57cec5SDimitry Andric #ifdef KMP_TDATA_GTID
5980b57cec5SDimitry Andric   if (__kmp_gtid_mode >= 3) {
5990b57cec5SDimitry Andric     if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {
6000b57cec5SDimitry Andric       return 0;
6010b57cec5SDimitry Andric     }
6020b57cec5SDimitry Andric   } else {
6030b57cec5SDimitry Andric #endif
6040b57cec5SDimitry Andric     if (!__kmp_init_parallel ||
605e8d8bef9SDimitry Andric         (gtid = (int)((kmp_intptr_t)(
606e8d8bef9SDimitry Andric              pthread_getspecific(__kmp_gtid_threadprivate_key)))) == 0) {
6070b57cec5SDimitry Andric       return 0;
6080b57cec5SDimitry Andric     }
6090b57cec5SDimitry Andric     --gtid;
6100b57cec5SDimitry Andric #ifdef KMP_TDATA_GTID
6110b57cec5SDimitry Andric   }
6120b57cec5SDimitry Andric #endif
6130b57cec5SDimitry Andric #else
6140b57cec5SDimitry Andric #error Unknown or unsupported OS
6150b57cec5SDimitry Andric #endif
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric   return __kmp_tid_from_gtid(gtid);
6180b57cec5SDimitry Andric #endif
6190b57cec5SDimitry Andric }
6200b57cec5SDimitry Andric 
FTN_GET_NUM_KNOWN_THREADS(void)6210b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_NUM_KNOWN_THREADS(void) {
6220b57cec5SDimitry Andric #ifdef KMP_STUB
6230b57cec5SDimitry Andric   return 1;
6240b57cec5SDimitry Andric #else
6250b57cec5SDimitry Andric   if (!__kmp_init_serial) {
6260b57cec5SDimitry Andric     __kmp_serial_initialize();
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric   /* NOTE: this is not syncronized, so it can change at any moment */
6290b57cec5SDimitry Andric   /* NOTE: this number also includes threads preallocated in hot-teams */
6300b57cec5SDimitry Andric   return TCR_4(__kmp_nth);
6310b57cec5SDimitry Andric #endif
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_NUM_PROCS)6340b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PROCS)(void) {
6350b57cec5SDimitry Andric #ifdef KMP_STUB
6360b57cec5SDimitry Andric   return 1;
6370b57cec5SDimitry Andric #else
6380b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
6390b57cec5SDimitry Andric     __kmp_middle_initialize();
6400b57cec5SDimitry Andric   }
641fcaf7f86SDimitry Andric #if KMP_AFFINITY_SUPPORTED
642bdd1243dSDimitry Andric   if (!__kmp_affinity.flags.reset) {
643fcaf7f86SDimitry Andric     // only bind root here if its affinity reset is not requested
644fcaf7f86SDimitry Andric     int gtid = __kmp_entry_gtid();
645fcaf7f86SDimitry Andric     kmp_info_t *thread = __kmp_threads[gtid];
646fcaf7f86SDimitry Andric     if (thread->th.th_team->t.t_level == 0) {
647fe6060f1SDimitry Andric       __kmp_assign_root_init_mask();
648fcaf7f86SDimitry Andric     }
649fcaf7f86SDimitry Andric   }
650fcaf7f86SDimitry Andric #endif
6510b57cec5SDimitry Andric   return __kmp_avail_proc;
6520b57cec5SDimitry Andric #endif
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_NESTED)6550b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NESTED)(int KMP_DEREF flag) {
6560b57cec5SDimitry Andric #ifdef KMP_STUB
6570b57cec5SDimitry Andric   __kmps_set_nested(KMP_DEREF flag);
6580b57cec5SDimitry Andric #else
6590b57cec5SDimitry Andric   kmp_info_t *thread;
6600b57cec5SDimitry Andric   /* For the thread-private internal controls implementation */
6610b57cec5SDimitry Andric   thread = __kmp_entry_thread();
662fe6060f1SDimitry Andric   KMP_INFORM(APIDeprecated, "omp_set_nested", "omp_set_max_active_levels");
6630b57cec5SDimitry Andric   __kmp_save_internal_controls(thread);
6640b57cec5SDimitry Andric   // Somewhat arbitrarily decide where to get a value for max_active_levels
6650b57cec5SDimitry Andric   int max_active_levels = get__max_active_levels(thread);
6660b57cec5SDimitry Andric   if (max_active_levels == 1)
6670b57cec5SDimitry Andric     max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;
6680b57cec5SDimitry Andric   set__max_active_levels(thread, (KMP_DEREF flag) ? max_active_levels : 1);
6690b57cec5SDimitry Andric #endif
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_NESTED)6720b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NESTED)(void) {
6730b57cec5SDimitry Andric #ifdef KMP_STUB
6740b57cec5SDimitry Andric   return __kmps_get_nested();
6750b57cec5SDimitry Andric #else
6760b57cec5SDimitry Andric   kmp_info_t *thread;
6770b57cec5SDimitry Andric   thread = __kmp_entry_thread();
678fe6060f1SDimitry Andric   KMP_INFORM(APIDeprecated, "omp_get_nested", "omp_get_max_active_levels");
6790b57cec5SDimitry Andric   return get__max_active_levels(thread) > 1;
6800b57cec5SDimitry Andric #endif
6810b57cec5SDimitry Andric }
6820b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_DYNAMIC)6830b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DYNAMIC)(int KMP_DEREF flag) {
6840b57cec5SDimitry Andric #ifdef KMP_STUB
6850b57cec5SDimitry Andric   __kmps_set_dynamic(KMP_DEREF flag ? TRUE : FALSE);
6860b57cec5SDimitry Andric #else
6870b57cec5SDimitry Andric   kmp_info_t *thread;
6880b57cec5SDimitry Andric   /* For the thread-private implementation of the internal controls */
6890b57cec5SDimitry Andric   thread = __kmp_entry_thread();
6900b57cec5SDimitry Andric   // !!! What if foreign thread calls it?
6910b57cec5SDimitry Andric   __kmp_save_internal_controls(thread);
692e8d8bef9SDimitry Andric   set__dynamic(thread, KMP_DEREF flag ? true : false);
6930b57cec5SDimitry Andric #endif
6940b57cec5SDimitry Andric }
6950b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_DYNAMIC)6960b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DYNAMIC)(void) {
6970b57cec5SDimitry Andric #ifdef KMP_STUB
6980b57cec5SDimitry Andric   return __kmps_get_dynamic();
6990b57cec5SDimitry Andric #else
7000b57cec5SDimitry Andric   kmp_info_t *thread;
7010b57cec5SDimitry Andric   thread = __kmp_entry_thread();
7020b57cec5SDimitry Andric   return get__dynamic(thread);
7030b57cec5SDimitry Andric #endif
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_IN_PARALLEL)7060b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_PARALLEL)(void) {
7070b57cec5SDimitry Andric #ifdef KMP_STUB
7080b57cec5SDimitry Andric   return 0;
7090b57cec5SDimitry Andric #else
7100b57cec5SDimitry Andric   kmp_info_t *th = __kmp_entry_thread();
7110b57cec5SDimitry Andric   if (th->th.th_teams_microtask) {
7120b57cec5SDimitry Andric     // AC: r_in_parallel does not work inside teams construct where real
7130b57cec5SDimitry Andric     // parallel is inactive, but all threads have same root, so setting it in
7140b57cec5SDimitry Andric     // one team affects other teams.
7150b57cec5SDimitry Andric     // The solution is to use per-team nesting level
7160b57cec5SDimitry Andric     return (th->th.th_team->t.t_active_level ? 1 : 0);
7170b57cec5SDimitry Andric   } else
7180b57cec5SDimitry Andric     return (th->th.th_root->r.r_in_parallel ? FTN_TRUE : FTN_FALSE);
7190b57cec5SDimitry Andric #endif
7200b57cec5SDimitry Andric }
7210b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_SCHEDULE)7220b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_SCHEDULE)(kmp_sched_t KMP_DEREF kind,
7230b57cec5SDimitry Andric                                                    int KMP_DEREF modifier) {
7240b57cec5SDimitry Andric #ifdef KMP_STUB
7250b57cec5SDimitry Andric   __kmps_set_schedule(KMP_DEREF kind, KMP_DEREF modifier);
7260b57cec5SDimitry Andric #else
7270b57cec5SDimitry Andric   /* TO DO: For the per-task implementation of the internal controls */
7280b57cec5SDimitry Andric   __kmp_set_schedule(__kmp_entry_gtid(), KMP_DEREF kind, KMP_DEREF modifier);
7290b57cec5SDimitry Andric #endif
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_SCHEDULE)7320b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_SCHEDULE)(kmp_sched_t *kind,
7330b57cec5SDimitry Andric                                                    int *modifier) {
7340b57cec5SDimitry Andric #ifdef KMP_STUB
7350b57cec5SDimitry Andric   __kmps_get_schedule(kind, modifier);
7360b57cec5SDimitry Andric #else
7370b57cec5SDimitry Andric   /* TO DO: For the per-task implementation of the internal controls */
7380b57cec5SDimitry Andric   __kmp_get_schedule(__kmp_entry_gtid(), kind, modifier);
7390b57cec5SDimitry Andric #endif
7400b57cec5SDimitry Andric }
7410b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_MAX_ACTIVE_LEVELS)7420b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_MAX_ACTIVE_LEVELS)(int KMP_DEREF arg) {
7430b57cec5SDimitry Andric #ifdef KMP_STUB
7440b57cec5SDimitry Andric // Nothing.
7450b57cec5SDimitry Andric #else
7460b57cec5SDimitry Andric   /* TO DO: We want per-task implementation of this internal control */
7470b57cec5SDimitry Andric   __kmp_set_max_active_levels(__kmp_entry_gtid(), KMP_DEREF arg);
7480b57cec5SDimitry Andric #endif
7490b57cec5SDimitry Andric }
7500b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_MAX_ACTIVE_LEVELS)7510b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_ACTIVE_LEVELS)(void) {
7520b57cec5SDimitry Andric #ifdef KMP_STUB
7530b57cec5SDimitry Andric   return 0;
7540b57cec5SDimitry Andric #else
7550b57cec5SDimitry Andric   /* TO DO: We want per-task implementation of this internal control */
756fe6060f1SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
757fe6060f1SDimitry Andric     __kmp_middle_initialize();
758fe6060f1SDimitry Andric   }
7590b57cec5SDimitry Andric   return __kmp_get_max_active_levels(__kmp_entry_gtid());
7600b57cec5SDimitry Andric #endif
7610b57cec5SDimitry Andric }
7620b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_ACTIVE_LEVEL)7630b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_ACTIVE_LEVEL)(void) {
7640b57cec5SDimitry Andric #ifdef KMP_STUB
7650b57cec5SDimitry Andric   return 0; // returns 0 if it is called from the sequential part of the program
7660b57cec5SDimitry Andric #else
7670b57cec5SDimitry Andric   /* TO DO: For the per-task implementation of the internal controls */
7680b57cec5SDimitry Andric   return __kmp_entry_thread()->th.th_team->t.t_active_level;
7690b57cec5SDimitry Andric #endif
7700b57cec5SDimitry Andric }
7710b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_LEVEL)7720b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_LEVEL)(void) {
7730b57cec5SDimitry Andric #ifdef KMP_STUB
7740b57cec5SDimitry Andric   return 0; // returns 0 if it is called from the sequential part of the program
7750b57cec5SDimitry Andric #else
7760b57cec5SDimitry Andric   /* TO DO: For the per-task implementation of the internal controls */
7770b57cec5SDimitry Andric   return __kmp_entry_thread()->th.th_team->t.t_level;
7780b57cec5SDimitry Andric #endif
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric int FTN_STDCALL
KMP_EXPAND_NAME(FTN_GET_ANCESTOR_THREAD_NUM)7820b57cec5SDimitry Andric KMP_EXPAND_NAME(FTN_GET_ANCESTOR_THREAD_NUM)(int KMP_DEREF level) {
7830b57cec5SDimitry Andric #ifdef KMP_STUB
7840b57cec5SDimitry Andric   return (KMP_DEREF level) ? (-1) : (0);
7850b57cec5SDimitry Andric #else
7860b57cec5SDimitry Andric   return __kmp_get_ancestor_thread_num(__kmp_entry_gtid(), KMP_DEREF level);
7870b57cec5SDimitry Andric #endif
7880b57cec5SDimitry Andric }
7890b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_TEAM_SIZE)7900b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_SIZE)(int KMP_DEREF level) {
7910b57cec5SDimitry Andric #ifdef KMP_STUB
7920b57cec5SDimitry Andric   return (KMP_DEREF level) ? (-1) : (1);
7930b57cec5SDimitry Andric #else
7940b57cec5SDimitry Andric   return __kmp_get_team_size(__kmp_entry_gtid(), KMP_DEREF level);
7950b57cec5SDimitry Andric #endif
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_THREAD_LIMIT)7980b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_LIMIT)(void) {
7990b57cec5SDimitry Andric #ifdef KMP_STUB
8000b57cec5SDimitry Andric   return 1; // TO DO: clarify whether it returns 1 or 0?
8010b57cec5SDimitry Andric #else
8020b57cec5SDimitry Andric   int gtid;
8030b57cec5SDimitry Andric   kmp_info_t *thread;
8040b57cec5SDimitry Andric   if (!__kmp_init_serial) {
8050b57cec5SDimitry Andric     __kmp_serial_initialize();
8060b57cec5SDimitry Andric   }
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
8090b57cec5SDimitry Andric   thread = __kmp_threads[gtid];
8105f757f3fSDimitry Andric   // If thread_limit for the target task is defined, return that instead of the
8115f757f3fSDimitry Andric   // regular task thread_limit
8125f757f3fSDimitry Andric   if (int thread_limit = thread->th.th_current_task->td_icvs.task_thread_limit)
8135f757f3fSDimitry Andric     return thread_limit;
8140b57cec5SDimitry Andric   return thread->th.th_current_task->td_icvs.thread_limit;
8150b57cec5SDimitry Andric #endif
8160b57cec5SDimitry Andric }
8170b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_IN_FINAL)8180b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_FINAL)(void) {
8190b57cec5SDimitry Andric #ifdef KMP_STUB
8200b57cec5SDimitry Andric   return 0; // TO DO: clarify whether it returns 1 or 0?
8210b57cec5SDimitry Andric #else
8220b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_parallel)) {
8230b57cec5SDimitry Andric     return 0;
8240b57cec5SDimitry Andric   }
8250b57cec5SDimitry Andric   return __kmp_entry_thread()->th.th_current_task->td_flags.final;
8260b57cec5SDimitry Andric #endif
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_PROC_BIND)8290b57cec5SDimitry Andric kmp_proc_bind_t FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PROC_BIND)(void) {
8300b57cec5SDimitry Andric #ifdef KMP_STUB
8310b57cec5SDimitry Andric   return __kmps_get_proc_bind();
8320b57cec5SDimitry Andric #else
8330b57cec5SDimitry Andric   return get__proc_bind(__kmp_entry_thread());
8340b57cec5SDimitry Andric #endif
8350b57cec5SDimitry Andric }
8360b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_NUM_PLACES)8370b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PLACES)(void) {
8380b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
8390b57cec5SDimitry Andric   return 0;
8400b57cec5SDimitry Andric #else
8410b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
8420b57cec5SDimitry Andric     __kmp_middle_initialize();
8430b57cec5SDimitry Andric   }
8440b57cec5SDimitry Andric   if (!KMP_AFFINITY_CAPABLE())
8450b57cec5SDimitry Andric     return 0;
846bdd1243dSDimitry Andric   if (!__kmp_affinity.flags.reset) {
847fcaf7f86SDimitry Andric     // only bind root here if its affinity reset is not requested
848fcaf7f86SDimitry Andric     int gtid = __kmp_entry_gtid();
849fcaf7f86SDimitry Andric     kmp_info_t *thread = __kmp_threads[gtid];
850fcaf7f86SDimitry Andric     if (thread->th.th_team->t.t_level == 0) {
851fcaf7f86SDimitry Andric       __kmp_assign_root_init_mask();
852fcaf7f86SDimitry Andric     }
853fcaf7f86SDimitry Andric   }
854bdd1243dSDimitry Andric   return __kmp_affinity.num_masks;
8550b57cec5SDimitry Andric #endif
8560b57cec5SDimitry Andric }
8570b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_PLACE_NUM_PROCS)8580b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM_PROCS)(int place_num) {
8590b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
8600b57cec5SDimitry Andric   return 0;
8610b57cec5SDimitry Andric #else
8620b57cec5SDimitry Andric   int i;
8630b57cec5SDimitry Andric   int retval = 0;
8640b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
8650b57cec5SDimitry Andric     __kmp_middle_initialize();
8660b57cec5SDimitry Andric   }
8670b57cec5SDimitry Andric   if (!KMP_AFFINITY_CAPABLE())
8680b57cec5SDimitry Andric     return 0;
869bdd1243dSDimitry Andric   if (!__kmp_affinity.flags.reset) {
870fcaf7f86SDimitry Andric     // only bind root here if its affinity reset is not requested
871fcaf7f86SDimitry Andric     int gtid = __kmp_entry_gtid();
872fcaf7f86SDimitry Andric     kmp_info_t *thread = __kmp_threads[gtid];
873fcaf7f86SDimitry Andric     if (thread->th.th_team->t.t_level == 0) {
874fcaf7f86SDimitry Andric       __kmp_assign_root_init_mask();
875fcaf7f86SDimitry Andric     }
876fcaf7f86SDimitry Andric   }
877bdd1243dSDimitry Andric   if (place_num < 0 || place_num >= (int)__kmp_affinity.num_masks)
8780b57cec5SDimitry Andric     return 0;
879bdd1243dSDimitry Andric   kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity.masks, place_num);
8800b57cec5SDimitry Andric   KMP_CPU_SET_ITERATE(i, mask) {
8810b57cec5SDimitry Andric     if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
8820b57cec5SDimitry Andric         (!KMP_CPU_ISSET(i, mask))) {
8830b57cec5SDimitry Andric       continue;
8840b57cec5SDimitry Andric     }
8850b57cec5SDimitry Andric     ++retval;
8860b57cec5SDimitry Andric   }
8870b57cec5SDimitry Andric   return retval;
8880b57cec5SDimitry Andric #endif
8890b57cec5SDimitry Andric }
8900b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_PLACE_PROC_IDS)8910b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_PROC_IDS)(int place_num,
8920b57cec5SDimitry Andric                                                          int *ids) {
8930b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
8940b57cec5SDimitry Andric // Nothing.
8950b57cec5SDimitry Andric #else
8960b57cec5SDimitry Andric   int i, j;
8970b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
8980b57cec5SDimitry Andric     __kmp_middle_initialize();
8990b57cec5SDimitry Andric   }
9000b57cec5SDimitry Andric   if (!KMP_AFFINITY_CAPABLE())
9010b57cec5SDimitry Andric     return;
902bdd1243dSDimitry Andric   if (!__kmp_affinity.flags.reset) {
903fcaf7f86SDimitry Andric     // only bind root here if its affinity reset is not requested
904fcaf7f86SDimitry Andric     int gtid = __kmp_entry_gtid();
905fcaf7f86SDimitry Andric     kmp_info_t *thread = __kmp_threads[gtid];
906fcaf7f86SDimitry Andric     if (thread->th.th_team->t.t_level == 0) {
907fcaf7f86SDimitry Andric       __kmp_assign_root_init_mask();
908fcaf7f86SDimitry Andric     }
909fcaf7f86SDimitry Andric   }
910bdd1243dSDimitry Andric   if (place_num < 0 || place_num >= (int)__kmp_affinity.num_masks)
9110b57cec5SDimitry Andric     return;
912bdd1243dSDimitry Andric   kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity.masks, place_num);
9130b57cec5SDimitry Andric   j = 0;
9140b57cec5SDimitry Andric   KMP_CPU_SET_ITERATE(i, mask) {
9150b57cec5SDimitry Andric     if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
9160b57cec5SDimitry Andric         (!KMP_CPU_ISSET(i, mask))) {
9170b57cec5SDimitry Andric       continue;
9180b57cec5SDimitry Andric     }
9190b57cec5SDimitry Andric     ids[j++] = i;
9200b57cec5SDimitry Andric   }
9210b57cec5SDimitry Andric #endif
9220b57cec5SDimitry Andric }
9230b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_PLACE_NUM)9240b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM)(void) {
9250b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
9260b57cec5SDimitry Andric   return -1;
9270b57cec5SDimitry Andric #else
9280b57cec5SDimitry Andric   int gtid;
9290b57cec5SDimitry Andric   kmp_info_t *thread;
9300b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
9310b57cec5SDimitry Andric     __kmp_middle_initialize();
9320b57cec5SDimitry Andric   }
9330b57cec5SDimitry Andric   if (!KMP_AFFINITY_CAPABLE())
9340b57cec5SDimitry Andric     return -1;
9350b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
9360b57cec5SDimitry Andric   thread = __kmp_thread_from_gtid(gtid);
937bdd1243dSDimitry Andric   if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {
938fcaf7f86SDimitry Andric     __kmp_assign_root_init_mask();
939fcaf7f86SDimitry Andric   }
9400b57cec5SDimitry Andric   if (thread->th.th_current_place < 0)
9410b57cec5SDimitry Andric     return -1;
9420b57cec5SDimitry Andric   return thread->th.th_current_place;
9430b57cec5SDimitry Andric #endif
9440b57cec5SDimitry Andric }
9450b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_PARTITION_NUM_PLACES)9460b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PARTITION_NUM_PLACES)(void) {
9470b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
9480b57cec5SDimitry Andric   return 0;
9490b57cec5SDimitry Andric #else
9500b57cec5SDimitry Andric   int gtid, num_places, first_place, last_place;
9510b57cec5SDimitry Andric   kmp_info_t *thread;
9520b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
9530b57cec5SDimitry Andric     __kmp_middle_initialize();
9540b57cec5SDimitry Andric   }
9550b57cec5SDimitry Andric   if (!KMP_AFFINITY_CAPABLE())
9560b57cec5SDimitry Andric     return 0;
9570b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
9580b57cec5SDimitry Andric   thread = __kmp_thread_from_gtid(gtid);
959bdd1243dSDimitry Andric   if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {
960fcaf7f86SDimitry Andric     __kmp_assign_root_init_mask();
961fcaf7f86SDimitry Andric   }
9620b57cec5SDimitry Andric   first_place = thread->th.th_first_place;
9630b57cec5SDimitry Andric   last_place = thread->th.th_last_place;
9640b57cec5SDimitry Andric   if (first_place < 0 || last_place < 0)
9650b57cec5SDimitry Andric     return 0;
9660b57cec5SDimitry Andric   if (first_place <= last_place)
9670b57cec5SDimitry Andric     num_places = last_place - first_place + 1;
9680b57cec5SDimitry Andric   else
969bdd1243dSDimitry Andric     num_places = __kmp_affinity.num_masks - first_place + last_place + 1;
9700b57cec5SDimitry Andric   return num_places;
9710b57cec5SDimitry Andric #endif
9720b57cec5SDimitry Andric }
9730b57cec5SDimitry Andric 
974fe6060f1SDimitry Andric void FTN_STDCALL
KMP_EXPAND_NAME(FTN_GET_PARTITION_PLACE_NUMS)975fe6060f1SDimitry Andric KMP_EXPAND_NAME(FTN_GET_PARTITION_PLACE_NUMS)(int *place_nums) {
9760b57cec5SDimitry Andric #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
9770b57cec5SDimitry Andric // Nothing.
9780b57cec5SDimitry Andric #else
9790b57cec5SDimitry Andric   int i, gtid, place_num, first_place, last_place, start, end;
9800b57cec5SDimitry Andric   kmp_info_t *thread;
9810b57cec5SDimitry Andric   if (!TCR_4(__kmp_init_middle)) {
9820b57cec5SDimitry Andric     __kmp_middle_initialize();
9830b57cec5SDimitry Andric   }
9840b57cec5SDimitry Andric   if (!KMP_AFFINITY_CAPABLE())
9850b57cec5SDimitry Andric     return;
9860b57cec5SDimitry Andric   gtid = __kmp_entry_gtid();
9870b57cec5SDimitry Andric   thread = __kmp_thread_from_gtid(gtid);
988bdd1243dSDimitry Andric   if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {
989fcaf7f86SDimitry Andric     __kmp_assign_root_init_mask();
990fcaf7f86SDimitry Andric   }
9910b57cec5SDimitry Andric   first_place = thread->th.th_first_place;
9920b57cec5SDimitry Andric   last_place = thread->th.th_last_place;
9930b57cec5SDimitry Andric   if (first_place < 0 || last_place < 0)
9940b57cec5SDimitry Andric     return;
9950b57cec5SDimitry Andric   if (first_place <= last_place) {
9960b57cec5SDimitry Andric     start = first_place;
9970b57cec5SDimitry Andric     end = last_place;
9980b57cec5SDimitry Andric   } else {
9990b57cec5SDimitry Andric     start = last_place;
10000b57cec5SDimitry Andric     end = first_place;
10010b57cec5SDimitry Andric   }
10020b57cec5SDimitry Andric   for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
10030b57cec5SDimitry Andric     place_nums[i] = place_num;
10040b57cec5SDimitry Andric   }
10050b57cec5SDimitry Andric #endif
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)10080b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)(void) {
10090b57cec5SDimitry Andric #ifdef KMP_STUB
10100b57cec5SDimitry Andric   return 1;
10110b57cec5SDimitry Andric #else
10120b57cec5SDimitry Andric   return __kmp_aux_get_num_teams();
10130b57cec5SDimitry Andric #endif
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)10160b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)(void) {
10170b57cec5SDimitry Andric #ifdef KMP_STUB
10180b57cec5SDimitry Andric   return 0;
10190b57cec5SDimitry Andric #else
10200b57cec5SDimitry Andric   return __kmp_aux_get_team_num();
10210b57cec5SDimitry Andric #endif
10220b57cec5SDimitry Andric }
10230b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_DEFAULT_DEVICE)10240b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DEFAULT_DEVICE)(void) {
10250b57cec5SDimitry Andric #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
10260b57cec5SDimitry Andric   return 0;
10270b57cec5SDimitry Andric #else
10280b57cec5SDimitry Andric   return __kmp_entry_thread()->th.th_current_task->td_icvs.default_device;
10290b57cec5SDimitry Andric #endif
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)10320b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {
10330b57cec5SDimitry Andric #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
10340b57cec5SDimitry Andric // Nothing.
10350b57cec5SDimitry Andric #else
10360b57cec5SDimitry Andric   __kmp_entry_thread()->th.th_current_task->td_icvs.default_device =
10370b57cec5SDimitry Andric       KMP_DEREF arg;
10380b57cec5SDimitry Andric #endif
10390b57cec5SDimitry Andric }
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric // Get number of NON-HOST devices.
10420b57cec5SDimitry Andric // libomptarget, if loaded, provides this function in api.cpp.
1043fe6060f1SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void)
1044fe6060f1SDimitry Andric     KMP_WEAK_ATTRIBUTE_EXTERNAL;
KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)10450b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void) {
10465f757f3fSDimitry Andric #if KMP_MIC || KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
10470b57cec5SDimitry Andric   return 0;
10480b57cec5SDimitry Andric #else
10490b57cec5SDimitry Andric   int (*fptr)();
1050fe6060f1SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM("__tgt_get_num_devices"))) {
10510b57cec5SDimitry Andric     return (*fptr)();
1052fe6060f1SDimitry Andric   } else if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_devices"))) {
1053fe6060f1SDimitry Andric     return (*fptr)();
1054fe6060f1SDimitry Andric   } else if ((*(void **)(&fptr) = KMP_DLSYM("_Offload_number_of_devices"))) {
10550b57cec5SDimitry Andric     return (*fptr)();
10560b57cec5SDimitry Andric   } else { // liboffload & libomptarget don't exist
10570b57cec5SDimitry Andric     return 0;
10580b57cec5SDimitry Andric   }
10590b57cec5SDimitry Andric #endif // KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB)
10600b57cec5SDimitry Andric }
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric // This function always returns true when called on host device.
1063480093f4SDimitry Andric // Compiler/libomptarget should handle when it is called inside target region.
1064fe6060f1SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void)
1065fe6060f1SDimitry Andric     KMP_WEAK_ATTRIBUTE_EXTERNAL;
KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)10660b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) {
10670b57cec5SDimitry Andric   return 1; // This is the host
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric // libomptarget, if loaded, provides this function
1071fe6060f1SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void)
1072fe6060f1SDimitry Andric     KMP_WEAK_ATTRIBUTE_EXTERNAL;
KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)1073fe6060f1SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void) {
1074e8d8bef9SDimitry Andric   // same as omp_get_num_devices()
1075fe6060f1SDimitry Andric   return KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)();
10760b57cec5SDimitry Andric }
10770b57cec5SDimitry Andric 
10780b57cec5SDimitry Andric #if defined(KMP_STUB)
10790b57cec5SDimitry Andric // Entries for stubs library
10800b57cec5SDimitry Andric // As all *target* functions are C-only parameters always passed by value
FTN_TARGET_ALLOC(size_t size,int device_num)10810b57cec5SDimitry Andric void *FTN_STDCALL FTN_TARGET_ALLOC(size_t size, int device_num) { return 0; }
10820b57cec5SDimitry Andric 
FTN_TARGET_FREE(void * device_ptr,int device_num)10830b57cec5SDimitry Andric void FTN_STDCALL FTN_TARGET_FREE(void *device_ptr, int device_num) {}
10840b57cec5SDimitry Andric 
FTN_TARGET_IS_PRESENT(void * ptr,int device_num)10850b57cec5SDimitry Andric int FTN_STDCALL FTN_TARGET_IS_PRESENT(void *ptr, int device_num) { return 0; }
10860b57cec5SDimitry Andric 
FTN_TARGET_MEMCPY(void * dst,void * src,size_t length,size_t dst_offset,size_t src_offset,int dst_device,int src_device)10870b57cec5SDimitry Andric int FTN_STDCALL FTN_TARGET_MEMCPY(void *dst, void *src, size_t length,
10880b57cec5SDimitry Andric                                   size_t dst_offset, size_t src_offset,
10890b57cec5SDimitry Andric                                   int dst_device, int src_device) {
10900b57cec5SDimitry Andric   return -1;
10910b57cec5SDimitry Andric }
10920b57cec5SDimitry Andric 
FTN_TARGET_MEMCPY_RECT(void * dst,void * src,size_t element_size,int num_dims,const size_t * volume,const size_t * dst_offsets,const size_t * src_offsets,const size_t * dst_dimensions,const size_t * src_dimensions,int dst_device,int src_device)10930b57cec5SDimitry Andric int FTN_STDCALL FTN_TARGET_MEMCPY_RECT(
10940b57cec5SDimitry Andric     void *dst, void *src, size_t element_size, int num_dims,
10950b57cec5SDimitry Andric     const size_t *volume, const size_t *dst_offsets, const size_t *src_offsets,
10960b57cec5SDimitry Andric     const size_t *dst_dimensions, const size_t *src_dimensions, int dst_device,
10970b57cec5SDimitry Andric     int src_device) {
10980b57cec5SDimitry Andric   return -1;
10990b57cec5SDimitry Andric }
11000b57cec5SDimitry Andric 
FTN_TARGET_ASSOCIATE_PTR(void * host_ptr,void * device_ptr,size_t size,size_t device_offset,int device_num)11010b57cec5SDimitry Andric int FTN_STDCALL FTN_TARGET_ASSOCIATE_PTR(void *host_ptr, void *device_ptr,
11020b57cec5SDimitry Andric                                          size_t size, size_t device_offset,
11030b57cec5SDimitry Andric                                          int device_num) {
11040b57cec5SDimitry Andric   return -1;
11050b57cec5SDimitry Andric }
11060b57cec5SDimitry Andric 
FTN_TARGET_DISASSOCIATE_PTR(void * host_ptr,int device_num)11070b57cec5SDimitry Andric int FTN_STDCALL FTN_TARGET_DISASSOCIATE_PTR(void *host_ptr, int device_num) {
11080b57cec5SDimitry Andric   return -1;
11090b57cec5SDimitry Andric }
11100b57cec5SDimitry Andric #endif // defined(KMP_STUB)
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric #ifdef KMP_STUB
11130b57cec5SDimitry Andric typedef enum { UNINIT = -1, UNLOCKED, LOCKED } kmp_stub_lock_t;
11140b57cec5SDimitry Andric #endif /* KMP_STUB */
11150b57cec5SDimitry Andric 
11160b57cec5SDimitry Andric #if KMP_USE_DYNAMIC_LOCK
FTN_INIT_LOCK_WITH_HINT(void ** user_lock,uintptr_t KMP_DEREF hint)11170b57cec5SDimitry Andric void FTN_STDCALL FTN_INIT_LOCK_WITH_HINT(void **user_lock,
11180b57cec5SDimitry Andric                                          uintptr_t KMP_DEREF hint) {
11190b57cec5SDimitry Andric #ifdef KMP_STUB
11200b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
11210b57cec5SDimitry Andric #else
11220b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
11230b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11240b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
11250b57cec5SDimitry Andric #endif
11260b57cec5SDimitry Andric   __kmpc_init_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
11270b57cec5SDimitry Andric #endif
11280b57cec5SDimitry Andric }
11290b57cec5SDimitry Andric 
FTN_INIT_NEST_LOCK_WITH_HINT(void ** user_lock,uintptr_t KMP_DEREF hint)11300b57cec5SDimitry Andric void FTN_STDCALL FTN_INIT_NEST_LOCK_WITH_HINT(void **user_lock,
11310b57cec5SDimitry Andric                                               uintptr_t KMP_DEREF hint) {
11320b57cec5SDimitry Andric #ifdef KMP_STUB
11330b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
11340b57cec5SDimitry Andric #else
11350b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
11360b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11370b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
11380b57cec5SDimitry Andric #endif
11390b57cec5SDimitry Andric   __kmpc_init_nest_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
11400b57cec5SDimitry Andric #endif
11410b57cec5SDimitry Andric }
11420b57cec5SDimitry Andric #endif
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric /* initialize the lock */
KMP_EXPAND_NAME(FTN_INIT_LOCK)11450b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_LOCK)(void **user_lock) {
11460b57cec5SDimitry Andric #ifdef KMP_STUB
11470b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
11480b57cec5SDimitry Andric #else
11490b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
11500b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11510b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
11520b57cec5SDimitry Andric #endif
11530b57cec5SDimitry Andric   __kmpc_init_lock(NULL, gtid, user_lock);
11540b57cec5SDimitry Andric #endif
11550b57cec5SDimitry Andric }
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric /* initialize the lock */
KMP_EXPAND_NAME(FTN_INIT_NEST_LOCK)11580b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_NEST_LOCK)(void **user_lock) {
11590b57cec5SDimitry Andric #ifdef KMP_STUB
11600b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
11610b57cec5SDimitry Andric #else
11620b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
11630b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11640b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
11650b57cec5SDimitry Andric #endif
11660b57cec5SDimitry Andric   __kmpc_init_nest_lock(NULL, gtid, user_lock);
11670b57cec5SDimitry Andric #endif
11680b57cec5SDimitry Andric }
11690b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_DESTROY_LOCK)11700b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_LOCK)(void **user_lock) {
11710b57cec5SDimitry Andric #ifdef KMP_STUB
11720b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNINIT;
11730b57cec5SDimitry Andric #else
11740b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
11750b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11760b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
11770b57cec5SDimitry Andric #endif
11780b57cec5SDimitry Andric   __kmpc_destroy_lock(NULL, gtid, user_lock);
11790b57cec5SDimitry Andric #endif
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_DESTROY_NEST_LOCK)11820b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_NEST_LOCK)(void **user_lock) {
11830b57cec5SDimitry Andric #ifdef KMP_STUB
11840b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNINIT;
11850b57cec5SDimitry Andric #else
11860b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
11870b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
11880b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
11890b57cec5SDimitry Andric #endif
11900b57cec5SDimitry Andric   __kmpc_destroy_nest_lock(NULL, gtid, user_lock);
11910b57cec5SDimitry Andric #endif
11920b57cec5SDimitry Andric }
11930b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_LOCK)11940b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_LOCK)(void **user_lock) {
11950b57cec5SDimitry Andric #ifdef KMP_STUB
11960b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
11970b57cec5SDimitry Andric     // TODO: Issue an error.
11980b57cec5SDimitry Andric   }
11990b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) != UNLOCKED) {
12000b57cec5SDimitry Andric     // TODO: Issue an error.
12010b57cec5SDimitry Andric   }
12020b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = LOCKED;
12030b57cec5SDimitry Andric #else
12040b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12050b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
12060b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12070b57cec5SDimitry Andric #endif
12080b57cec5SDimitry Andric   __kmpc_set_lock(NULL, gtid, user_lock);
12090b57cec5SDimitry Andric #endif
12100b57cec5SDimitry Andric }
12110b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_SET_NEST_LOCK)12120b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NEST_LOCK)(void **user_lock) {
12130b57cec5SDimitry Andric #ifdef KMP_STUB
12140b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
12150b57cec5SDimitry Andric     // TODO: Issue an error.
12160b57cec5SDimitry Andric   }
12170b57cec5SDimitry Andric   (*((int *)user_lock))++;
12180b57cec5SDimitry Andric #else
12190b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12200b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
12210b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12220b57cec5SDimitry Andric #endif
12230b57cec5SDimitry Andric   __kmpc_set_nest_lock(NULL, gtid, user_lock);
12240b57cec5SDimitry Andric #endif
12250b57cec5SDimitry Andric }
12260b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_UNSET_LOCK)12270b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_LOCK)(void **user_lock) {
12280b57cec5SDimitry Andric #ifdef KMP_STUB
12290b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
12300b57cec5SDimitry Andric     // TODO: Issue an error.
12310b57cec5SDimitry Andric   }
12320b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
12330b57cec5SDimitry Andric     // TODO: Issue an error.
12340b57cec5SDimitry Andric   }
12350b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
12360b57cec5SDimitry Andric #else
12370b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12380b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
12390b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12400b57cec5SDimitry Andric #endif
12410b57cec5SDimitry Andric   __kmpc_unset_lock(NULL, gtid, user_lock);
12420b57cec5SDimitry Andric #endif
12430b57cec5SDimitry Andric }
12440b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_UNSET_NEST_LOCK)12450b57cec5SDimitry Andric void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_NEST_LOCK)(void **user_lock) {
12460b57cec5SDimitry Andric #ifdef KMP_STUB
12470b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
12480b57cec5SDimitry Andric     // TODO: Issue an error.
12490b57cec5SDimitry Andric   }
12500b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
12510b57cec5SDimitry Andric     // TODO: Issue an error.
12520b57cec5SDimitry Andric   }
12530b57cec5SDimitry Andric   (*((int *)user_lock))--;
12540b57cec5SDimitry Andric #else
12550b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12560b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
12570b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12580b57cec5SDimitry Andric #endif
12590b57cec5SDimitry Andric   __kmpc_unset_nest_lock(NULL, gtid, user_lock);
12600b57cec5SDimitry Andric #endif
12610b57cec5SDimitry Andric }
12620b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_TEST_LOCK)12630b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_LOCK)(void **user_lock) {
12640b57cec5SDimitry Andric #ifdef KMP_STUB
12650b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
12660b57cec5SDimitry Andric     // TODO: Issue an error.
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == LOCKED) {
12690b57cec5SDimitry Andric     return 0;
12700b57cec5SDimitry Andric   }
12710b57cec5SDimitry Andric   *((kmp_stub_lock_t *)user_lock) = LOCKED;
12720b57cec5SDimitry Andric   return 1;
12730b57cec5SDimitry Andric #else
12740b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12750b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
12760b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12770b57cec5SDimitry Andric #endif
12780b57cec5SDimitry Andric   return __kmpc_test_lock(NULL, gtid, user_lock);
12790b57cec5SDimitry Andric #endif
12800b57cec5SDimitry Andric }
12810b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_TEST_NEST_LOCK)12820b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_NEST_LOCK)(void **user_lock) {
12830b57cec5SDimitry Andric #ifdef KMP_STUB
12840b57cec5SDimitry Andric   if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
12850b57cec5SDimitry Andric     // TODO: Issue an error.
12860b57cec5SDimitry Andric   }
12870b57cec5SDimitry Andric   return ++(*((int *)user_lock));
12880b57cec5SDimitry Andric #else
12890b57cec5SDimitry Andric   int gtid = __kmp_entry_gtid();
12900b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL
12910b57cec5SDimitry Andric   OMPT_STORE_RETURN_ADDRESS(gtid);
12920b57cec5SDimitry Andric #endif
12930b57cec5SDimitry Andric   return __kmpc_test_nest_lock(NULL, gtid, user_lock);
12940b57cec5SDimitry Andric #endif
12950b57cec5SDimitry Andric }
12960b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_WTIME)12970b57cec5SDimitry Andric double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTIME)(void) {
12980b57cec5SDimitry Andric #ifdef KMP_STUB
12990b57cec5SDimitry Andric   return __kmps_get_wtime();
13000b57cec5SDimitry Andric #else
13010b57cec5SDimitry Andric   double data;
13020b57cec5SDimitry Andric #if !KMP_OS_LINUX
13030b57cec5SDimitry Andric   // We don't need library initialization to get the time on Linux* OS. The
13040b57cec5SDimitry Andric   // routine can be used to measure library initialization time on Linux* OS now
13050b57cec5SDimitry Andric   if (!__kmp_init_serial) {
13060b57cec5SDimitry Andric     __kmp_serial_initialize();
13070b57cec5SDimitry Andric   }
13080b57cec5SDimitry Andric #endif
13090b57cec5SDimitry Andric   __kmp_elapsed(&data);
13100b57cec5SDimitry Andric   return data;
13110b57cec5SDimitry Andric #endif
13120b57cec5SDimitry Andric }
13130b57cec5SDimitry Andric 
KMP_EXPAND_NAME(FTN_GET_WTICK)13140b57cec5SDimitry Andric double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTICK)(void) {
13150b57cec5SDimitry Andric #ifdef KMP_STUB
13160b57cec5SDimitry Andric   return __kmps_get_wtick();
13170b57cec5SDimitry Andric #else
13180b57cec5SDimitry Andric   double data;
13190b57cec5SDimitry Andric   if (!__kmp_init_serial) {
13200b57cec5SDimitry Andric     __kmp_serial_initialize();
13210b57cec5SDimitry Andric   }
13220b57cec5SDimitry Andric   __kmp_elapsed_tick(&data);
13230b57cec5SDimitry Andric   return data;
13240b57cec5SDimitry Andric #endif
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric /* ------------------------------------------------------------------------ */
13280b57cec5SDimitry Andric 
FTN_MALLOC(size_t KMP_DEREF size)13290b57cec5SDimitry Andric void *FTN_STDCALL FTN_MALLOC(size_t KMP_DEREF size) {
13300b57cec5SDimitry Andric   // kmpc_malloc initializes the library if needed
13310b57cec5SDimitry Andric   return kmpc_malloc(KMP_DEREF size);
13320b57cec5SDimitry Andric }
13330b57cec5SDimitry Andric 
FTN_ALIGNED_MALLOC(size_t KMP_DEREF size,size_t KMP_DEREF alignment)13340b57cec5SDimitry Andric void *FTN_STDCALL FTN_ALIGNED_MALLOC(size_t KMP_DEREF size,
13350b57cec5SDimitry Andric                                      size_t KMP_DEREF alignment) {
13360b57cec5SDimitry Andric   // kmpc_aligned_malloc initializes the library if needed
13370b57cec5SDimitry Andric   return kmpc_aligned_malloc(KMP_DEREF size, KMP_DEREF alignment);
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
FTN_CALLOC(size_t KMP_DEREF nelem,size_t KMP_DEREF elsize)13400b57cec5SDimitry Andric void *FTN_STDCALL FTN_CALLOC(size_t KMP_DEREF nelem, size_t KMP_DEREF elsize) {
13410b57cec5SDimitry Andric   // kmpc_calloc initializes the library if needed
13420b57cec5SDimitry Andric   return kmpc_calloc(KMP_DEREF nelem, KMP_DEREF elsize);
13430b57cec5SDimitry Andric }
13440b57cec5SDimitry Andric 
FTN_REALLOC(void * KMP_DEREF ptr,size_t KMP_DEREF size)13450b57cec5SDimitry Andric void *FTN_STDCALL FTN_REALLOC(void *KMP_DEREF ptr, size_t KMP_DEREF size) {
13460b57cec5SDimitry Andric   // kmpc_realloc initializes the library if needed
13470b57cec5SDimitry Andric   return kmpc_realloc(KMP_DEREF ptr, KMP_DEREF size);
13480b57cec5SDimitry Andric }
13490b57cec5SDimitry Andric 
FTN_KFREE(void * KMP_DEREF ptr)13500b57cec5SDimitry Andric void FTN_STDCALL FTN_KFREE(void *KMP_DEREF ptr) {
13510b57cec5SDimitry Andric   // does nothing if the library is not initialized
13520b57cec5SDimitry Andric   kmpc_free(KMP_DEREF ptr);
13530b57cec5SDimitry Andric }
13540b57cec5SDimitry Andric 
FTN_SET_WARNINGS_ON(void)13550b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_WARNINGS_ON(void) {
13560b57cec5SDimitry Andric #ifndef KMP_STUB
13570b57cec5SDimitry Andric   __kmp_generate_warnings = kmp_warnings_explicit;
13580b57cec5SDimitry Andric #endif
13590b57cec5SDimitry Andric }
13600b57cec5SDimitry Andric 
FTN_SET_WARNINGS_OFF(void)13610b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_WARNINGS_OFF(void) {
13620b57cec5SDimitry Andric #ifndef KMP_STUB
13630b57cec5SDimitry Andric   __kmp_generate_warnings = FALSE;
13640b57cec5SDimitry Andric #endif
13650b57cec5SDimitry Andric }
13660b57cec5SDimitry Andric 
FTN_SET_DEFAULTS(char const * str,int len)13670b57cec5SDimitry Andric void FTN_STDCALL FTN_SET_DEFAULTS(char const *str
13680b57cec5SDimitry Andric #ifndef PASS_ARGS_BY_VALUE
13690b57cec5SDimitry Andric                                   ,
13700b57cec5SDimitry Andric                                   int len
13710b57cec5SDimitry Andric #endif
13720b57cec5SDimitry Andric ) {
13730b57cec5SDimitry Andric #ifndef KMP_STUB
13740b57cec5SDimitry Andric #ifdef PASS_ARGS_BY_VALUE
13750b57cec5SDimitry Andric   int len = (int)KMP_STRLEN(str);
13760b57cec5SDimitry Andric #endif
13770b57cec5SDimitry Andric   __kmp_aux_set_defaults(str, len);
13780b57cec5SDimitry Andric #endif
13790b57cec5SDimitry Andric }
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric /* ------------------------------------------------------------------------ */
13820b57cec5SDimitry Andric 
13830b57cec5SDimitry Andric /* returns the status of cancellation */
KMP_EXPAND_NAME(FTN_GET_CANCELLATION)13840b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_CANCELLATION)(void) {
13850b57cec5SDimitry Andric #ifdef KMP_STUB
13860b57cec5SDimitry Andric   return 0 /* false */;
13870b57cec5SDimitry Andric #else
13880b57cec5SDimitry Andric   // initialize the library if needed
13890b57cec5SDimitry Andric   if (!__kmp_init_serial) {
13900b57cec5SDimitry Andric     __kmp_serial_initialize();
13910b57cec5SDimitry Andric   }
13920b57cec5SDimitry Andric   return __kmp_omp_cancellation;
13930b57cec5SDimitry Andric #endif
13940b57cec5SDimitry Andric }
13950b57cec5SDimitry Andric 
FTN_GET_CANCELLATION_STATUS(int cancel_kind)13960b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_CANCELLATION_STATUS(int cancel_kind) {
13970b57cec5SDimitry Andric #ifdef KMP_STUB
13980b57cec5SDimitry Andric   return 0 /* false */;
13990b57cec5SDimitry Andric #else
14000b57cec5SDimitry Andric   return __kmp_get_cancellation_status(cancel_kind);
14010b57cec5SDimitry Andric #endif
14020b57cec5SDimitry Andric }
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric /* returns the maximum allowed task priority */
KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)14050b57cec5SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) {
14060b57cec5SDimitry Andric #ifdef KMP_STUB
14070b57cec5SDimitry Andric   return 0;
14080b57cec5SDimitry Andric #else
14090b57cec5SDimitry Andric   if (!__kmp_init_serial) {
14100b57cec5SDimitry Andric     __kmp_serial_initialize();
14110b57cec5SDimitry Andric   }
14120b57cec5SDimitry Andric   return __kmp_max_task_priority;
14130b57cec5SDimitry Andric #endif
14140b57cec5SDimitry Andric }
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric // This function will be defined in libomptarget. When libomptarget is not
14170b57cec5SDimitry Andric // loaded, we assume we are on the host and return KMP_HOST_DEVICE.
14180b57cec5SDimitry Andric // Compiler/libomptarget will handle this if called inside target.
1419979e22ffSDimitry Andric int FTN_STDCALL FTN_GET_DEVICE_NUM(void) KMP_WEAK_ATTRIBUTE_EXTERNAL;
FTN_GET_DEVICE_NUM(void)1420fe6060f1SDimitry Andric int FTN_STDCALL FTN_GET_DEVICE_NUM(void) {
1421fe6060f1SDimitry Andric   return KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)();
1422fe6060f1SDimitry Andric }
14230b57cec5SDimitry Andric 
14240b57cec5SDimitry Andric // Compiler will ensure that this is only called from host in sequential region
KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE)1425fe6060f1SDimitry Andric int FTN_STDCALL KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE)(kmp_pause_status_t kind,
1426fe6060f1SDimitry Andric                                                     int device_num) {
14270b57cec5SDimitry Andric #ifdef KMP_STUB
14280b57cec5SDimitry Andric   return 1; // just fail
14290b57cec5SDimitry Andric #else
1430fe6060f1SDimitry Andric   if (device_num == KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)())
14310b57cec5SDimitry Andric     return __kmpc_pause_resource(kind);
14320b57cec5SDimitry Andric   else {
14330b57cec5SDimitry Andric     int (*fptr)(kmp_pause_status_t, int);
1434fe6060f1SDimitry Andric     if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))
14350b57cec5SDimitry Andric       return (*fptr)(kind, device_num);
14360b57cec5SDimitry Andric     else
14370b57cec5SDimitry Andric       return 1; // just fail if there is no libomptarget
14380b57cec5SDimitry Andric   }
14390b57cec5SDimitry Andric #endif
14400b57cec5SDimitry Andric }
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric // Compiler will ensure that this is only called from host in sequential region
1443fe6060f1SDimitry Andric int FTN_STDCALL
KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE_ALL)1444fe6060f1SDimitry Andric     KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE_ALL)(kmp_pause_status_t kind) {
14450b57cec5SDimitry Andric #ifdef KMP_STUB
14460b57cec5SDimitry Andric   return 1; // just fail
14470b57cec5SDimitry Andric #else
14480b57cec5SDimitry Andric   int fails = 0;
14490b57cec5SDimitry Andric   int (*fptr)(kmp_pause_status_t, int);
1450fe6060f1SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))
14510b57cec5SDimitry Andric     fails = (*fptr)(kind, KMP_DEVICE_ALL); // pause devices
14520b57cec5SDimitry Andric   fails += __kmpc_pause_resource(kind); // pause host
14530b57cec5SDimitry Andric   return fails;
14540b57cec5SDimitry Andric #endif
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric // Returns the maximum number of nesting levels supported by implementation
FTN_GET_SUPPORTED_ACTIVE_LEVELS(void)14580b57cec5SDimitry Andric int FTN_STDCALL FTN_GET_SUPPORTED_ACTIVE_LEVELS(void) {
14590b57cec5SDimitry Andric #ifdef KMP_STUB
14600b57cec5SDimitry Andric   return 1;
14610b57cec5SDimitry Andric #else
14620b57cec5SDimitry Andric   return KMP_MAX_ACTIVE_LEVELS_LIMIT;
14630b57cec5SDimitry Andric #endif
14640b57cec5SDimitry Andric }
14650b57cec5SDimitry Andric 
FTN_FULFILL_EVENT(kmp_event_t * event)14660b57cec5SDimitry Andric void FTN_STDCALL FTN_FULFILL_EVENT(kmp_event_t *event) {
14670b57cec5SDimitry Andric #ifndef KMP_STUB
14680b57cec5SDimitry Andric   __kmp_fulfill_event(event);
14690b57cec5SDimitry Andric #endif
14700b57cec5SDimitry Andric }
14710b57cec5SDimitry Andric 
1472fe6060f1SDimitry Andric // nteams-var per-device ICV
FTN_SET_NUM_TEAMS(int KMP_DEREF num_teams)1473fe6060f1SDimitry Andric void FTN_STDCALL FTN_SET_NUM_TEAMS(int KMP_DEREF num_teams) {
1474fe6060f1SDimitry Andric #ifdef KMP_STUB
1475fe6060f1SDimitry Andric // Nothing.
1476fe6060f1SDimitry Andric #else
1477fe6060f1SDimitry Andric   if (!__kmp_init_serial) {
1478fe6060f1SDimitry Andric     __kmp_serial_initialize();
1479fe6060f1SDimitry Andric   }
1480fe6060f1SDimitry Andric   __kmp_set_num_teams(KMP_DEREF num_teams);
1481fe6060f1SDimitry Andric #endif
1482fe6060f1SDimitry Andric }
FTN_GET_MAX_TEAMS(void)1483fe6060f1SDimitry Andric int FTN_STDCALL FTN_GET_MAX_TEAMS(void) {
1484fe6060f1SDimitry Andric #ifdef KMP_STUB
1485fe6060f1SDimitry Andric   return 1;
1486fe6060f1SDimitry Andric #else
1487fe6060f1SDimitry Andric   if (!__kmp_init_serial) {
1488fe6060f1SDimitry Andric     __kmp_serial_initialize();
1489fe6060f1SDimitry Andric   }
1490fe6060f1SDimitry Andric   return __kmp_get_max_teams();
1491fe6060f1SDimitry Andric #endif
1492fe6060f1SDimitry Andric }
1493fe6060f1SDimitry Andric // teams-thread-limit-var per-device ICV
FTN_SET_TEAMS_THREAD_LIMIT(int KMP_DEREF limit)1494fe6060f1SDimitry Andric void FTN_STDCALL FTN_SET_TEAMS_THREAD_LIMIT(int KMP_DEREF limit) {
1495fe6060f1SDimitry Andric #ifdef KMP_STUB
1496fe6060f1SDimitry Andric // Nothing.
1497fe6060f1SDimitry Andric #else
1498fe6060f1SDimitry Andric   if (!__kmp_init_serial) {
1499fe6060f1SDimitry Andric     __kmp_serial_initialize();
1500fe6060f1SDimitry Andric   }
1501fe6060f1SDimitry Andric   __kmp_set_teams_thread_limit(KMP_DEREF limit);
1502fe6060f1SDimitry Andric #endif
1503fe6060f1SDimitry Andric }
FTN_GET_TEAMS_THREAD_LIMIT(void)1504fe6060f1SDimitry Andric int FTN_STDCALL FTN_GET_TEAMS_THREAD_LIMIT(void) {
1505fe6060f1SDimitry Andric #ifdef KMP_STUB
1506fe6060f1SDimitry Andric   return 1;
1507fe6060f1SDimitry Andric #else
1508fe6060f1SDimitry Andric   if (!__kmp_init_serial) {
1509fe6060f1SDimitry Andric     __kmp_serial_initialize();
1510fe6060f1SDimitry Andric   }
1511fe6060f1SDimitry Andric   return __kmp_get_teams_thread_limit();
1512fe6060f1SDimitry Andric #endif
1513fe6060f1SDimitry Andric }
1514fe6060f1SDimitry Andric 
15151fd87a68SDimitry Andric /// TODO: Include the `omp.h` of the current build
15161fd87a68SDimitry Andric /* OpenMP 5.1 interop */
15171fd87a68SDimitry Andric typedef intptr_t omp_intptr_t;
15181fd87a68SDimitry Andric 
15191fd87a68SDimitry Andric /* 0..omp_get_num_interop_properties()-1 are reserved for implementation-defined
15201fd87a68SDimitry Andric  * properties */
15211fd87a68SDimitry Andric typedef enum omp_interop_property {
15221fd87a68SDimitry Andric   omp_ipr_fr_id = -1,
15231fd87a68SDimitry Andric   omp_ipr_fr_name = -2,
15241fd87a68SDimitry Andric   omp_ipr_vendor = -3,
15251fd87a68SDimitry Andric   omp_ipr_vendor_name = -4,
15261fd87a68SDimitry Andric   omp_ipr_device_num = -5,
15271fd87a68SDimitry Andric   omp_ipr_platform = -6,
15281fd87a68SDimitry Andric   omp_ipr_device = -7,
15291fd87a68SDimitry Andric   omp_ipr_device_context = -8,
15301fd87a68SDimitry Andric   omp_ipr_targetsync = -9,
15311fd87a68SDimitry Andric   omp_ipr_first = -9
15321fd87a68SDimitry Andric } omp_interop_property_t;
15331fd87a68SDimitry Andric 
15341fd87a68SDimitry Andric #define omp_interop_none 0
15351fd87a68SDimitry Andric 
15361fd87a68SDimitry Andric typedef enum omp_interop_rc {
15371fd87a68SDimitry Andric   omp_irc_no_value = 1,
15381fd87a68SDimitry Andric   omp_irc_success = 0,
15391fd87a68SDimitry Andric   omp_irc_empty = -1,
15401fd87a68SDimitry Andric   omp_irc_out_of_range = -2,
15411fd87a68SDimitry Andric   omp_irc_type_int = -3,
15421fd87a68SDimitry Andric   omp_irc_type_ptr = -4,
15431fd87a68SDimitry Andric   omp_irc_type_str = -5,
15441fd87a68SDimitry Andric   omp_irc_other = -6
15451fd87a68SDimitry Andric } omp_interop_rc_t;
15461fd87a68SDimitry Andric 
15471fd87a68SDimitry Andric typedef enum omp_interop_fr {
15481fd87a68SDimitry Andric   omp_ifr_cuda = 1,
15491fd87a68SDimitry Andric   omp_ifr_cuda_driver = 2,
15501fd87a68SDimitry Andric   omp_ifr_opencl = 3,
15511fd87a68SDimitry Andric   omp_ifr_sycl = 4,
15521fd87a68SDimitry Andric   omp_ifr_hip = 5,
15531fd87a68SDimitry Andric   omp_ifr_level_zero = 6,
15541fd87a68SDimitry Andric   omp_ifr_last = 7
15551fd87a68SDimitry Andric } omp_interop_fr_t;
15561fd87a68SDimitry Andric 
15571fd87a68SDimitry Andric typedef void *omp_interop_t;
15581fd87a68SDimitry Andric 
15591fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop)15601fd87a68SDimitry Andric int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) {
15615f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
15621fd87a68SDimitry Andric   return 0;
15631fd87a68SDimitry Andric #else
15641fd87a68SDimitry Andric   int (*fptr)(const omp_interop_t);
15651fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_interop_properties")))
15661fd87a68SDimitry Andric     return (*fptr)(interop);
15671fd87a68SDimitry Andric   return 0;
156806c3fb27SDimitry Andric #endif
15691fd87a68SDimitry Andric }
15701fd87a68SDimitry Andric 
15711fd87a68SDimitry Andric /// TODO Convert FTN_GET_INTEROP_XXX functions into a macro like interop.cpp
15721fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_INTEROP_INT(const omp_interop_t interop,omp_interop_property_t property_id,int * err)15731fd87a68SDimitry Andric intptr_t FTN_STDCALL FTN_GET_INTEROP_INT(const omp_interop_t interop,
15741fd87a68SDimitry Andric                                          omp_interop_property_t property_id,
15751fd87a68SDimitry Andric                                          int *err) {
15765f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
157706c3fb27SDimitry Andric   return 0;
157806c3fb27SDimitry Andric #else
15791fd87a68SDimitry Andric   intptr_t (*fptr)(const omp_interop_t, omp_interop_property_t, int *);
15801fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_int")))
15811fd87a68SDimitry Andric     return (*fptr)(interop, property_id, err);
15821fd87a68SDimitry Andric   return 0;
158306c3fb27SDimitry Andric #endif
15841fd87a68SDimitry Andric }
15851fd87a68SDimitry Andric 
15861fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_INTEROP_PTR(const omp_interop_t interop,omp_interop_property_t property_id,int * err)15871fd87a68SDimitry Andric void *FTN_STDCALL FTN_GET_INTEROP_PTR(const omp_interop_t interop,
15881fd87a68SDimitry Andric                                       omp_interop_property_t property_id,
15891fd87a68SDimitry Andric                                       int *err) {
15905f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
159106c3fb27SDimitry Andric   return nullptr;
159206c3fb27SDimitry Andric #else
15931fd87a68SDimitry Andric   void *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);
15941fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_ptr")))
15951fd87a68SDimitry Andric     return (*fptr)(interop, property_id, err);
15961fd87a68SDimitry Andric   return nullptr;
159706c3fb27SDimitry Andric #endif
15981fd87a68SDimitry Andric }
15991fd87a68SDimitry Andric 
16001fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_INTEROP_STR(const omp_interop_t interop,omp_interop_property_t property_id,int * err)16011fd87a68SDimitry Andric const char *FTN_STDCALL FTN_GET_INTEROP_STR(const omp_interop_t interop,
16021fd87a68SDimitry Andric                                             omp_interop_property_t property_id,
16031fd87a68SDimitry Andric                                             int *err) {
16045f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
160506c3fb27SDimitry Andric   return nullptr;
160606c3fb27SDimitry Andric #else
16071fd87a68SDimitry Andric   const char *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);
16081fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_str")))
16091fd87a68SDimitry Andric     return (*fptr)(interop, property_id, err);
16101fd87a68SDimitry Andric   return nullptr;
161106c3fb27SDimitry Andric #endif
16121fd87a68SDimitry Andric }
16131fd87a68SDimitry Andric 
16141fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_INTEROP_NAME(const omp_interop_t interop,omp_interop_property_t property_id)16151fd87a68SDimitry Andric const char *FTN_STDCALL FTN_GET_INTEROP_NAME(
16161fd87a68SDimitry Andric     const omp_interop_t interop, omp_interop_property_t property_id) {
16175f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
161806c3fb27SDimitry Andric   return nullptr;
161906c3fb27SDimitry Andric #else
16201fd87a68SDimitry Andric   const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
16211fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_name")))
16221fd87a68SDimitry Andric     return (*fptr)(interop, property_id);
16231fd87a68SDimitry Andric   return nullptr;
162406c3fb27SDimitry Andric #endif
16251fd87a68SDimitry Andric }
16261fd87a68SDimitry Andric 
16271fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_INTEROP_TYPE_DESC(const omp_interop_t interop,omp_interop_property_t property_id)16281fd87a68SDimitry Andric const char *FTN_STDCALL FTN_GET_INTEROP_TYPE_DESC(
16291fd87a68SDimitry Andric     const omp_interop_t interop, omp_interop_property_t property_id) {
16305f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
163106c3fb27SDimitry Andric   return nullptr;
163206c3fb27SDimitry Andric #else
16331fd87a68SDimitry Andric   const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
16341fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_type_desc")))
16351fd87a68SDimitry Andric     return (*fptr)(interop, property_id);
16361fd87a68SDimitry Andric   return nullptr;
163706c3fb27SDimitry Andric #endif
16381fd87a68SDimitry Andric }
16391fd87a68SDimitry Andric 
16401fd87a68SDimitry Andric // libomptarget, if loaded, provides this function
FTN_GET_INTEROP_RC_DESC(const omp_interop_t interop,omp_interop_property_t property_id)16411fd87a68SDimitry Andric const char *FTN_STDCALL FTN_GET_INTEROP_RC_DESC(
16421fd87a68SDimitry Andric     const omp_interop_t interop, omp_interop_property_t property_id) {
16435f757f3fSDimitry Andric #if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
164406c3fb27SDimitry Andric   return nullptr;
164506c3fb27SDimitry Andric #else
16461fd87a68SDimitry Andric   const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
16471fd87a68SDimitry Andric   if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_rec_desc")))
16481fd87a68SDimitry Andric     return (*fptr)(interop, property_id);
16491fd87a68SDimitry Andric   return nullptr;
165006c3fb27SDimitry Andric #endif
16511fd87a68SDimitry Andric }
16521fd87a68SDimitry Andric 
16535ffd83dbSDimitry Andric // display environment variables when requested
FTN_DISPLAY_ENV(int verbose)16545ffd83dbSDimitry Andric void FTN_STDCALL FTN_DISPLAY_ENV(int verbose) {
16555ffd83dbSDimitry Andric #ifndef KMP_STUB
16565ffd83dbSDimitry Andric   __kmp_omp_display_env(verbose);
16575ffd83dbSDimitry Andric #endif
16585ffd83dbSDimitry Andric }
16595ffd83dbSDimitry Andric 
FTN_IN_EXPLICIT_TASK(void)166081ad6265SDimitry Andric int FTN_STDCALL FTN_IN_EXPLICIT_TASK(void) {
166181ad6265SDimitry Andric #ifdef KMP_STUB
166281ad6265SDimitry Andric   return 0;
166381ad6265SDimitry Andric #else
166481ad6265SDimitry Andric   int gtid = __kmp_entry_gtid();
166581ad6265SDimitry Andric   return __kmp_thread_from_gtid(gtid)->th.th_current_task->td_flags.tasktype;
166681ad6265SDimitry Andric #endif
166781ad6265SDimitry Andric }
166881ad6265SDimitry Andric 
16690b57cec5SDimitry Andric // GCC compatibility (versioned symbols)
16700b57cec5SDimitry Andric #ifdef KMP_USE_VERSION_SYMBOLS
16710b57cec5SDimitry Andric 
16720b57cec5SDimitry Andric /* These following sections create versioned symbols for the
16730b57cec5SDimitry Andric    omp_* routines. The KMP_VERSION_SYMBOL macro expands the API name and
16740b57cec5SDimitry Andric    then maps it to a versioned symbol.
16750b57cec5SDimitry Andric    libgomp ``versions'' its symbols (OMP_1.0, OMP_2.0, OMP_3.0, ...) while also
16760b57cec5SDimitry Andric    retaining the default version which libomp uses: VERSION (defined in
16770b57cec5SDimitry Andric    exports_so.txt). If you want to see the versioned symbols for libgomp.so.1
16780b57cec5SDimitry Andric    then just type:
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric    objdump -T /path/to/libgomp.so.1 | grep omp_
16810b57cec5SDimitry Andric 
16820b57cec5SDimitry Andric    Example:
16830b57cec5SDimitry Andric    Step 1) Create __kmp_api_omp_set_num_threads_10_alias which is alias of
16840b57cec5SDimitry Andric      __kmp_api_omp_set_num_threads
16850b57cec5SDimitry Andric    Step 2) Set __kmp_api_omp_set_num_threads_10_alias to version:
16860b57cec5SDimitry Andric      omp_set_num_threads@OMP_1.0
16870b57cec5SDimitry Andric    Step 2B) Set __kmp_api_omp_set_num_threads to default version:
16880b57cec5SDimitry Andric      omp_set_num_threads@@VERSION
16890b57cec5SDimitry Andric */
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric // OMP_1.0 versioned symbols
16920b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_NUM_THREADS, 10, "OMP_1.0");
16930b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_NUM_THREADS, 10, "OMP_1.0");
16940b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_MAX_THREADS, 10, "OMP_1.0");
16950b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_THREAD_NUM, 10, "OMP_1.0");
16960b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_NUM_PROCS, 10, "OMP_1.0");
16970b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_IN_PARALLEL, 10, "OMP_1.0");
16980b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_DYNAMIC, 10, "OMP_1.0");
16990b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_DYNAMIC, 10, "OMP_1.0");
17000b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_NESTED, 10, "OMP_1.0");
17010b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_NESTED, 10, "OMP_1.0");
17020b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 10, "OMP_1.0");
17030b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 10, "OMP_1.0");
17040b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 10, "OMP_1.0");
17050b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 10, "OMP_1.0");
17060b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_LOCK, 10, "OMP_1.0");
17070b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 10, "OMP_1.0");
17080b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 10, "OMP_1.0");
17090b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 10, "OMP_1.0");
17100b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 10, "OMP_1.0");
17110b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 10, "OMP_1.0");
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric // OMP_2.0 versioned symbols
17140b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_WTICK, 20, "OMP_2.0");
17150b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_WTIME, 20, "OMP_2.0");
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric // OMP_3.0 versioned symbols
17180b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_SCHEDULE, 30, "OMP_3.0");
17190b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_SCHEDULE, 30, "OMP_3.0");
17200b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_THREAD_LIMIT, 30, "OMP_3.0");
17210b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
17220b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
17230b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_ANCESTOR_THREAD_NUM, 30, "OMP_3.0");
17240b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_LEVEL, 30, "OMP_3.0");
17250b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_TEAM_SIZE, 30, "OMP_3.0");
17260b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_ACTIVE_LEVEL, 30, "OMP_3.0");
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric // the lock routines have a 1.0 and 3.0 version
17290b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 30, "OMP_3.0");
17300b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 30, "OMP_3.0");
17310b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 30, "OMP_3.0");
17320b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 30, "OMP_3.0");
17330b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_LOCK, 30, "OMP_3.0");
17340b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 30, "OMP_3.0");
17350b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 30, "OMP_3.0");
17360b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 30, "OMP_3.0");
17370b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 30, "OMP_3.0");
17380b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 30, "OMP_3.0");
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric // OMP_3.1 versioned symbol
17410b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_IN_FINAL, 31, "OMP_3.1");
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric // OMP_4.0 versioned symbols
17440b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_PROC_BIND, 40, "OMP_4.0");
17450b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_NUM_TEAMS, 40, "OMP_4.0");
17460b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_TEAM_NUM, 40, "OMP_4.0");
17470b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_CANCELLATION, 40, "OMP_4.0");
17480b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_DEFAULT_DEVICE, 40, "OMP_4.0");
17490b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_DEFAULT_DEVICE, 40, "OMP_4.0");
17500b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_IS_INITIAL_DEVICE, 40, "OMP_4.0");
17510b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_NUM_DEVICES, 40, "OMP_4.0");
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric // OMP_4.5 versioned symbols
17540b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_MAX_TASK_PRIORITY, 45, "OMP_4.5");
17550b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_NUM_PLACES, 45, "OMP_4.5");
17560b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM_PROCS, 45, "OMP_4.5");
17570b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_PLACE_PROC_IDS, 45, "OMP_4.5");
17580b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM, 45, "OMP_4.5");
17590b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_PARTITION_NUM_PLACES, 45, "OMP_4.5");
17600b57cec5SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5");
1761fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5");
17620b57cec5SDimitry Andric 
17630b57cec5SDimitry Andric // OMP_5.0 versioned symbols
17640b57cec5SDimitry Andric // KMP_VERSION_SYMBOL(FTN_GET_DEVICE_NUM, 50, "OMP_5.0");
1765fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE, 50, "OMP_5.0");
1766fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE_ALL, 50, "OMP_5.0");
1767fe6060f1SDimitry Andric // The C versions (KMP_FTN_PLAIN) of these symbols are in kmp_csupport.c
1768fe6060f1SDimitry Andric #if KMP_FTN_ENTRIES == KMP_FTN_APPEND
1769fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_CAPTURE_AFFINITY, 50, "OMP_5.0");
1770fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_DISPLAY_AFFINITY, 50, "OMP_5.0");
1771fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_GET_AFFINITY_FORMAT, 50, "OMP_5.0");
1772fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(FTN_SET_AFFINITY_FORMAT, 50, "OMP_5.0");
1773fe6060f1SDimitry Andric #endif
17740b57cec5SDimitry Andric // KMP_VERSION_SYMBOL(FTN_GET_SUPPORTED_ACTIVE_LEVELS, 50, "OMP_5.0");
17750b57cec5SDimitry Andric // KMP_VERSION_SYMBOL(FTN_FULFILL_EVENT, 50, "OMP_5.0");
17760b57cec5SDimitry Andric 
17770b57cec5SDimitry Andric #endif // KMP_USE_VERSION_SYMBOLS
17780b57cec5SDimitry Andric 
17790b57cec5SDimitry Andric #ifdef __cplusplus
17800b57cec5SDimitry Andric } // extern "C"
17810b57cec5SDimitry Andric #endif // __cplusplus
17820b57cec5SDimitry Andric 
17830b57cec5SDimitry Andric // end of file //
1784