Index: runtime/CMakeLists.txt =================================================================== --- runtime/CMakeLists.txt +++ runtime/CMakeLists.txt @@ -273,7 +273,6 @@ endif() # OMPT-support -# TODO: Make this a real feature check set(LIBOMP_OMPT_SUPPORT FALSE CACHE BOOL "OMPT-support?") set(LIBOMP_OMPT_BLAME TRUE CACHE BOOL Index: runtime/cmake/LibompMicroTests.cmake =================================================================== --- runtime/cmake/LibompMicroTests.cmake +++ runtime/cmake/LibompMicroTests.cmake @@ -175,6 +175,7 @@ set(libomp_expected_library_deps /usr/lib/libSystem.B.dylib) elseif(WIN32) set(libomp_expected_library_deps kernel32.dll) + libomp_append(libomp_expected_library_deps psapi.dll LIBOMP_OMPT_SUPPORT) else() if(${MIC}) set(libomp_expected_library_deps libc.so.6 libpthread.so.0 libdl.so.2) Index: runtime/cmake/config-ix.cmake =================================================================== --- runtime/cmake/config-ix.cmake +++ runtime/cmake/config-ix.cmake @@ -13,6 +13,7 @@ include(CheckCSourceCompiles) include(CheckCXXCompilerFlag) include(CheckLibraryExists) +include(CheckIncludeFiles) include(LibompCheckLinkerFlag) include(LibompCheckFortranFlag) @@ -187,8 +188,26 @@ endif() # Check if OMPT support is available -if(NOT WIN32) - set(LIBOMP_HAVE_OMPT_SUPPORT TRUE) -else() +# Currently, __builtin_frame_address() is required for OMPT +# Weak attribute is required for Unices, LIBPSAPI is used for Windows +check_c_source_compiles("int main(int argc, char** argv) { + void* p = __builtin_frame_address(0); + return 0;}" LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS) +check_c_source_compiles("__attribute__ ((weak)) int foo(int a) { return a*a; } + int main(int argc, char** argv) { + return foo(argc);}" LIBOMP_HAVE_WEAK_ATTRIBUTE) +check_include_files("windows.h;psapi.h" LIBOMP_HAVE_PSAPI_H) +check_library_exists(psapi EnumProcessModules "" LIBOMP_HAVE_LIBPSAPI) +if(LIBOMP_HAVE_PSAPI_H AND LIBOMP_HAVE_LIBPSAPI) + set(LIBOMP_HAVE_PSAPI TRUE) +endif() +if(NOT LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS) set(LIBOMP_HAVE_OMPT_SUPPORT FALSE) +else() + if(LIBOMP_HAVE_WEAK_ATTRIBUTE OR LIBOMP_HAVE_PSAPI) + set(LIBOMP_HAVE_OMPT_SUPPORT TRUE) + else() + set(LIBOMP_HAVE_OMPT_SUPPORT FALSE) + endif() endif() + Index: runtime/src/kmp_config.h.cmake =================================================================== --- runtime/src/kmp_config.h.cmake +++ runtime/src/kmp_config.h.cmake @@ -27,6 +27,10 @@ #if LIBOMP_USE_VERSION_SYMBOLS # define KMP_USE_VERSION_SYMBOLS #endif +#cmakedefine01 LIBOMP_HAVE_WEAK_ATTRIBUTE +#define KMP_HAVE_WEAK_ATTRIBUTE LIBOMP_HAVE_WEAK_ATTRIBUTE +#cmakedefine01 LIBOMP_HAVE_PSAPI +#define KMP_HAVE_PSAPI LIBOMP_HAVE_PSAPI #cmakedefine01 LIBOMP_STATS #define KMP_STATS_ENABLED LIBOMP_STATS #cmakedefine01 LIBOMP_USE_DEBUGGER Index: runtime/src/ompt-general.c =================================================================== --- runtime/src/ompt-general.c +++ runtime/src/ompt-general.c @@ -87,17 +87,103 @@ OMPT_API_ROUTINE ompt_thread_id_t ompt_get_thread_id(void); - /***************************************************************************** * initialization and finalization (private operations) ****************************************************************************/ -_OMP_EXTERN __attribute__ (( weak )) +/* On Unix-like systems that support weak symbols the following implementation + * of ompt_tool() will be used in case no tool-supplied implementation of + * this function is present in the address space of a process. + * On Windows the RTL will look for the ompt_tool symbol across all modules + * loaded by a process. If ompt_tool is found it is used (through the pointer) + * by the RTL to initialize the tool. Otherwise, the stub function + * ompt_aux_tool() is used.*/ +_OMP_EXTERN +#if KMP_HAVE_WEAK_ATTRIBUTE +__attribute__ (( weak )) ompt_initialize_t ompt_tool() { +#if KMP_DEBUG + printf("ompt_tool() is called from the RTL\n"); +#endif + return NULL; +} + +#elif KMP_HAVE_PSAPI + +#include +#pragma comment(lib, "psapi.lib") + +// The number of loaded modules to start enumeration with EnumProcessModules() +#define NUM_MODULES 128 + +static +ompt_initialize_t ompt_aux_tool() +{ +#if KMP_DEBUG + printf("ompt_aux_tool() is called from the RTL\n"); +#endif return NULL; } +ompt_initialize_t (*ompt_tool_p)(); + +static +void __ompt_symbol_lookup( const char *function) +{ + int i; + DWORD needed, new_size; + HMODULE *modules; + HANDLE process = GetCurrentProcess(); + modules = (HMODULE*)malloc( NUM_MODULES * sizeof(HMODULE) ); + +#if KMP_DEBUG + printf("__ompt_symbol_lookup(): looking for %s\n", function); +#endif + if( !EnumProcessModules( process, modules, NUM_MODULES * sizeof(HMODULE), + &needed ) ) { + // Regardless of the error reason use the stub initialization function + ompt_tool_p = &ompt_aux_tool; + return; + } + // Check if NUM_MODULES is enough to list all modules + new_size = needed / sizeof(HMODULE); + if( new_size > NUM_MODULES ) { +#if KMP_DEBUG + printf("__ompt_symbol_lookup(): resize buffer to %d bytes\n", needed); +#endif + modules = (HMODULE*)realloc( modules, needed ); + // If resizing failed use the stub function. + if( !EnumProcessModules( process, modules, needed, &needed ) ) { + ompt_tool_p = &ompt_aux_tool; + return; + } + } + for( i = 0; i < new_size; ++i ) { + (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], function); + if( ompt_tool_p ) { +#if KMP_DEBUG + TCHAR modName[MAX_PATH]; + if( GetModuleFileName(modules[i], modName, MAX_PATH)) + printf("__ompt_symbol_lookup(): %s found in module %s\n", + function, modName); +#endif + break; + } + else { + ompt_tool_p = &ompt_aux_tool; +#if KMP_DEBUG + TCHAR modName[MAX_PATH]; + if( GetModuleFileName(modules[i], modName, MAX_PATH) ) + printf("__ompt_symbol_lookup(): %s not found in module %s\n", + function, modName); +#endif + } + } + return; +} + +#endif // KMP_HAVE_WEAK_ATTRIBUTE void ompt_pre_init() { @@ -118,18 +204,26 @@ if (!ompt_env_var || !strcmp(ompt_env_var, "")) tool_setting = omp_tool_unset; - else if (!strcasecmp(ompt_env_var, "disabled")) + else if (__kmp_str_match(ompt_env_var, 0, "disabled")) tool_setting = omp_tool_disabled; - else if (!strcasecmp(ompt_env_var, "enabled")) + else if (__kmp_str_match(ompt_env_var, 0, "enabled")) tool_setting = omp_tool_enabled; +#if KMP_DEBUG + printf("ompt_pre_init(): tool_setting = %d\n", tool_setting); +#endif switch(tool_setting) { case omp_tool_disabled: break; case omp_tool_unset: case omp_tool_enabled: +#if KMP_HAVE_PSAPI + __ompt_symbol_lookup("ompt_tool"); + ompt_initialize_fn = ompt_tool_p(); +#else ompt_initialize_fn = ompt_tool(); +#endif if (ompt_initialize_fn) { ompt_enabled = 1; } @@ -142,7 +236,9 @@ "\"enabled\").\n", ompt_env_var); break; } - +#if KMP_DEBUG + printf("ompt_pre_init():ompt_enabled = %d\n", ompt_enabled); +#endif } Index: runtime/src/ompt-specific.c =================================================================== --- runtime/src/ompt-specific.c +++ runtime/src/ompt-specific.c @@ -29,7 +29,7 @@ #define NEXT_ID(id_ptr,tid) \ ((KMP_TEST_THEN_INC64(id_ptr) << OMPT_THREAD_ID_BITS) | (tid)) #else -#define NEXT_ID(id_ptr,tid) (KMP_TEST_THEN_INC64(id_ptr)) +#define NEXT_ID(id_ptr,tid) (KMP_TEST_THEN_INC64((volatile kmp_int64 *)id_ptr)) #endif //******************************************************************************