From 2f6eba7516b267bf3bbfee840fd61f7fb8cde1c3 Mon Sep 17 00:00:00 2001 From: Hansang Bae Date: Thu, 4 May 2023 11:06:12 -0500 Subject: [PATCH] [OpenMP][libomp] Implement KMP_DLSYM_NEXT on Windows The interop API routines try to invoke external entries, but we did not have support for KMP_DLSYM_NEXT on Windows. Also added proper guards for STUB build. Differential Revision: https://reviews.llvm.org/D149892 --- openmp/runtime/src/kmp_ftn_entry.h | 28 ++++++++++++++++++++++++++-- openmp/runtime/src/kmp_os.h | 4 ++-- openmp/runtime/src/z_Windows_NT_util.cpp | 13 ++++++++++++- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h index bfd582a..038bccf 100644 --- a/openmp/runtime/src/kmp_ftn_entry.h +++ b/openmp/runtime/src/kmp_ftn_entry.h @@ -1549,14 +1549,14 @@ typedef void *omp_interop_t; // libomptarget, if loaded, provides this function int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) { -#if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB) +#if KMP_OS_DARWIN || defined(KMP_STUB) return 0; #else int (*fptr)(const omp_interop_t); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_interop_properties"))) return (*fptr)(interop); return 0; -#endif // KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB) +#endif } /// TODO Convert FTN_GET_INTEROP_XXX functions into a macro like interop.cpp @@ -1564,57 +1564,81 @@ int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) { intptr_t FTN_STDCALL FTN_GET_INTEROP_INT(const omp_interop_t interop, omp_interop_property_t property_id, int *err) { +#if KMP_OS_DARWIN || defined(KMP_STUB) + return 0; +#else intptr_t (*fptr)(const omp_interop_t, omp_interop_property_t, int *); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_int"))) return (*fptr)(interop, property_id, err); return 0; +#endif } // libomptarget, if loaded, provides this function void *FTN_STDCALL FTN_GET_INTEROP_PTR(const omp_interop_t interop, omp_interop_property_t property_id, int *err) { +#if KMP_OS_DARWIN || defined(KMP_STUB) + return nullptr; +#else void *(*fptr)(const omp_interop_t, omp_interop_property_t, int *); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_ptr"))) return (*fptr)(interop, property_id, err); return nullptr; +#endif } // libomptarget, if loaded, provides this function const char *FTN_STDCALL FTN_GET_INTEROP_STR(const omp_interop_t interop, omp_interop_property_t property_id, int *err) { +#if KMP_OS_DARWIN || defined(KMP_STUB) + return nullptr; +#else const char *(*fptr)(const omp_interop_t, omp_interop_property_t, int *); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_str"))) return (*fptr)(interop, property_id, err); return nullptr; +#endif } // libomptarget, if loaded, provides this function const char *FTN_STDCALL FTN_GET_INTEROP_NAME( const omp_interop_t interop, omp_interop_property_t property_id) { +#if KMP_OS_DARWIN || defined(KMP_STUB) + return nullptr; +#else const char *(*fptr)(const omp_interop_t, omp_interop_property_t); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_name"))) return (*fptr)(interop, property_id); return nullptr; +#endif } // libomptarget, if loaded, provides this function const char *FTN_STDCALL FTN_GET_INTEROP_TYPE_DESC( const omp_interop_t interop, omp_interop_property_t property_id) { +#if KMP_OS_DARWIN || defined(KMP_STUB) + return nullptr; +#else const char *(*fptr)(const omp_interop_t, omp_interop_property_t); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_type_desc"))) return (*fptr)(interop, property_id); return nullptr; +#endif } // libomptarget, if loaded, provides this function const char *FTN_STDCALL FTN_GET_INTEROP_RC_DESC( const omp_interop_t interop, omp_interop_property_t property_id) { +#if KMP_OS_DARWIN || defined(KMP_STUB) + return nullptr; +#else const char *(*fptr)(const omp_interop_t, omp_interop_property_t); if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_rec_desc"))) return (*fptr)(interop, property_id); return nullptr; +#endif } // display environment variables when requested diff --git a/openmp/runtime/src/kmp_os.h b/openmp/runtime/src/kmp_os.h index c78f3ee..fec589a 100644 --- a/openmp/runtime/src/kmp_os.h +++ b/openmp/runtime/src/kmp_os.h @@ -1282,9 +1282,9 @@ bool __kmp_atomic_compare_store_rel(std::atomic *p, T expected, T desired) { // Symbol lookup on Linux/Windows #if KMP_OS_WINDOWS -extern void *__kmp_lookup_symbol(const char *name); +extern void *__kmp_lookup_symbol(const char *name, bool next = false); #define KMP_DLSYM(name) __kmp_lookup_symbol(name) -#define KMP_DLSYM_NEXT(name) nullptr +#define KMP_DLSYM_NEXT(name) __kmp_lookup_symbol(name, true) #else #define KMP_DLSYM(name) dlsym(RTLD_DEFAULT, name) #define KMP_DLSYM_NEXT(name) dlsym(RTLD_NEXT, name) diff --git a/openmp/runtime/src/z_Windows_NT_util.cpp b/openmp/runtime/src/z_Windows_NT_util.cpp index ed62bc3..eb18efc 100644 --- a/openmp/runtime/src/z_Windows_NT_util.cpp +++ b/openmp/runtime/src/z_Windows_NT_util.cpp @@ -1669,7 +1669,7 @@ finish: // Clean up and exit. } //__kmp_get_load_balance() // Find symbol from the loaded modules -void *__kmp_lookup_symbol(const char *name) { +void *__kmp_lookup_symbol(const char *name, bool next) { HANDLE process = GetCurrentProcess(); DWORD needed; HMODULE *modules = nullptr; @@ -1681,8 +1681,19 @@ void *__kmp_lookup_symbol(const char *name) { free(modules); return nullptr; } + HMODULE curr_module = nullptr; + if (next) { + // Current module needs to be skipped if next flag is true + if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (LPCTSTR)&__kmp_lookup_symbol, &curr_module)) { + free(modules); + return nullptr; + } + } void *proc = nullptr; for (uint32_t i = 0; i < num_modules; i++) { + if (next && modules[i] == curr_module) + continue; proc = (void *)GetProcAddress(modules[i], name); if (proc) break; -- 2.7.4