diff --git a/openmp/runtime/cmake/LibompHandleFlags.cmake b/openmp/runtime/cmake/LibompHandleFlags.cmake index 4a25359a788c..82a2e884bc41 100644 --- a/openmp/runtime/cmake/LibompHandleFlags.cmake +++ b/openmp/runtime/cmake/LibompHandleFlags.cmake @@ -126,6 +126,9 @@ function(libomp_get_libflags libflags) if(${IA32}) libomp_append(libflags_local -lirc_pic LIBOMP_HAVE_IRC_PIC_LIBRARY) endif() + if(MINGW) + libomp_append(libflags_local -lpsapi LIBOMP_HAVE_LIBPSAPI) + endif() if(LIBOMP_HAVE_SHM_OPEN_WITH_LRT) libomp_append(libflags_local -lrt) endif() diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h index cf44019f94be..935feacc34f2 100644 --- a/openmp/runtime/src/kmp_ftn_entry.h +++ b/openmp/runtime/src/kmp_ftn_entry.h @@ -941,13 +941,15 @@ void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) { // libomptarget, if loaded, provides this function in api.cpp. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void) KMP_WEAK_ATTRIBUTE_EXTERNAL; int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void) { -#if KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB) +#if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB) return 0; #else int (*fptr)(); - if ((*(void **)(&fptr) = dlsym(RTLD_DEFAULT, "_Offload_number_of_devices"))) { + if ((*(void **)(&fptr) = KMP_DLSYM("__tgt_get_num_devices"))) { return (*fptr)(); - } else if ((*(void **)(&fptr) = dlsym(RTLD_NEXT, "omp_get_num_devices"))) { + } else if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_devices"))) { + return (*fptr)(); + } else if ((*(void **)(&fptr) = KMP_DLSYM("_Offload_number_of_devices"))) { return (*fptr)(); } else { // liboffload & libomptarget don't exist return 0; @@ -963,20 +965,11 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) { } // libomptarget, if loaded, provides this function -int FTN_STDCALL FTN_GET_INITIAL_DEVICE(void) KMP_WEAK_ATTRIBUTE_EXTERNAL; -int FTN_STDCALL FTN_GET_INITIAL_DEVICE(void) { -#if KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB) +int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void) + KMP_WEAK_ATTRIBUTE_EXTERNAL; +int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void) { // same as omp_get_num_devices() - return 0; -#else - int (*fptr)(); - if ((*(void **)(&fptr) = dlsym(RTLD_NEXT, "omp_get_initial_device"))) { - return (*fptr)(); - } else { // liboffload & libomptarget don't exist - // same as omp_get_num_devices() - return 0; - } -#endif + return KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(); } #if defined(KMP_STUB) @@ -1321,22 +1314,22 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) { // loaded, we assume we are on the host and return KMP_HOST_DEVICE. // Compiler/libomptarget will handle this if called inside target. int FTN_STDCALL FTN_GET_DEVICE_NUM(void) KMP_WEAK_ATTRIBUTE_EXTERNAL; -int FTN_STDCALL FTN_GET_DEVICE_NUM(void) { return FTN_GET_INITIAL_DEVICE(); } +int FTN_STDCALL FTN_GET_DEVICE_NUM(void) { + return KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(); +} // Compiler will ensure that this is only called from host in sequential region int FTN_STDCALL FTN_PAUSE_RESOURCE(kmp_pause_status_t kind, int device_num) { #ifdef KMP_STUB return 1; // just fail #else - if (device_num == FTN_GET_INITIAL_DEVICE()) + if (device_num == KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)()) return __kmpc_pause_resource(kind); else { -#if !KMP_OS_WINDOWS int (*fptr)(kmp_pause_status_t, int); - if ((*(void **)(&fptr) = dlsym(RTLD_DEFAULT, "tgt_pause_resource"))) + if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource"))) return (*fptr)(kind, device_num); else -#endif return 1; // just fail if there is no libomptarget } #endif @@ -1348,11 +1341,9 @@ int FTN_STDCALL FTN_PAUSE_RESOURCE_ALL(kmp_pause_status_t kind) { return 1; // just fail #else int fails = 0; -#if !KMP_OS_WINDOWS int (*fptr)(kmp_pause_status_t, int); - if ((*(void **)(&fptr) = dlsym(RTLD_DEFAULT, "tgt_pause_resource"))) + if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource"))) fails = (*fptr)(kind, KMP_DEVICE_ALL); // pause devices -#endif fails += __kmpc_pause_resource(kind); // pause host return fails; #endif @@ -1515,7 +1506,7 @@ KMP_VERSION_SYMBOL(FTN_GET_PLACE_PROC_IDS, 45, "OMP_4.5"); KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM, 45, "OMP_4.5"); KMP_VERSION_SYMBOL(FTN_GET_PARTITION_NUM_PLACES, 45, "OMP_4.5"); KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5"); -// KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5"); +KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5"); // OMP_5.0 versioned symbols // KMP_VERSION_SYMBOL(FTN_GET_DEVICE_NUM, 50, "OMP_5.0"); diff --git a/openmp/runtime/src/kmp_os.h b/openmp/runtime/src/kmp_os.h index 5ceae9857b32..590a2c710cc9 100644 --- a/openmp/runtime/src/kmp_os.h +++ b/openmp/runtime/src/kmp_os.h @@ -1077,6 +1077,16 @@ bool __kmp_atomic_compare_store_rel(std::atomic<T> *p, T expected, T desired) { expected, desired, std::memory_order_release, std::memory_order_relaxed); } +// Symbol lookup on Linux/Windows +#if KMP_OS_WINDOWS +extern void *__kmp_lookup_symbol(const char *name); +#define KMP_DLSYM(name) __kmp_lookup_symbol(name) +#define KMP_DLSYM_NEXT(name) nullptr +#else +#define KMP_DLSYM(name) dlsym(RTLD_DEFAULT, name) +#define KMP_DLSYM_NEXT(name) dlsym(RTLD_NEXT, name) +#endif + #endif /* KMP_OS_H */ // Safe C API #include "kmp_safe_c_api.h" diff --git a/openmp/runtime/src/z_Windows_NT_util.cpp b/openmp/runtime/src/z_Windows_NT_util.cpp index 551c4146f5f9..7a22df02eb2e 100644 --- a/openmp/runtime/src/z_Windows_NT_util.cpp +++ b/openmp/runtime/src/z_Windows_NT_util.cpp @@ -23,6 +23,8 @@ #include <ntsecapi.h> // UNICODE_STRING #include <ntstatus.h> +#include <psapi.h> +#pragma comment(lib, "psapi.lib") enum SYSTEM_INFORMATION_CLASS { SystemProcessInformation = 5 @@ -1632,6 +1634,29 @@ finish: // Clean up and exit. return running_threads; } //__kmp_get_load_balance() +// Find symbol from the loaded modules +void *__kmp_lookup_symbol(const char *name) { + HANDLE process = GetCurrentProcess(); + DWORD needed; + HMODULE *modules = nullptr; + if (!EnumProcessModules(process, modules, 0, &needed)) + return nullptr; + DWORD num_modules = needed / sizeof(HMODULE); + modules = (HMODULE *)malloc(num_modules * sizeof(HMODULE)); + if (!EnumProcessModules(process, modules, needed, &needed)) { + free(modules); + return nullptr; + } + void *proc = nullptr; + for (uint32_t i = 0; i < num_modules; i++) { + proc = (void *)GetProcAddress(modules[i], name); + if (proc) + break; + } + free(modules); + return proc; +} + // Functions for hidden helper task void __kmp_hidden_helper_worker_thread_wait() { KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");