Index: openmp/trunk/runtime/CMakeLists.txt =================================================================== --- openmp/trunk/runtime/CMakeLists.txt +++ openmp/trunk/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: openmp/trunk/runtime/cmake/LibompMicroTests.cmake =================================================================== --- openmp/trunk/runtime/cmake/LibompMicroTests.cmake +++ openmp/trunk/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: openmp/trunk/runtime/cmake/config-ix.cmake =================================================================== --- openmp/trunk/runtime/cmake/config-ix.cmake +++ openmp/trunk/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: openmp/trunk/runtime/src/kmp_config.h.cmake =================================================================== --- openmp/trunk/runtime/src/kmp_config.h.cmake +++ openmp/trunk/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: openmp/trunk/runtime/src/ompt-general.c =================================================================== --- openmp/trunk/runtime/src/ompt-general.c +++ openmp/trunk/runtime/src/ompt-general.c @@ -15,7 +15,6 @@ * ompt include files ****************************************************************************/ -#include "kmp_config.h" #include "ompt-internal.h" #include "ompt-specific.c" @@ -32,6 +31,9 @@ #define OMPT_API_ROUTINE static +#ifndef OMPT_STR_MATCH +#define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle)) +#endif /***************************************************************************** @@ -87,17 +89,93 @@ 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 ompt_tool_windows function is used to find the + * ompt_tool symbol across all modules loaded by a process. If ompt_tool is + * found, ompt_tool's return value is used to initialize the tool. Otherwise, + * NULL is returned and OMPT won't be enabled */ +#if OMPT_HAVE_WEAK_ATTRIBUTE +_OMP_EXTERN +__attribute__ (( weak )) ompt_initialize_t ompt_tool() { +#if OMPT_DEBUG + printf("ompt_tool() is called from the RTL\n"); +#endif return NULL; } +#elif OMPT_HAVE_PSAPI + +#include +#pragma comment(lib, "psapi.lib") +#define ompt_tool ompt_tool_windows + +// The number of loaded modules to start enumeration with EnumProcessModules() +#define NUM_MODULES 128 + +static +ompt_initialize_t ompt_tool_windows() +{ + int i; + DWORD needed, new_size; + HMODULE *modules; + HANDLE process = GetCurrentProcess(); + modules = (HMODULE*)malloc( NUM_MODULES * sizeof(HMODULE) ); + ompt_initialize_t (*ompt_tool_p)() = NULL; + +#if OMPT_DEBUG + printf("ompt_tool_windows(): looking for ompt_tool\n"); +#endif + if( !EnumProcessModules( process, modules, NUM_MODULES * sizeof(HMODULE), + &needed ) ) { + // Regardless of the error reason use the stub initialization function + return NULL; + } + // Check if NUM_MODULES is enough to list all modules + new_size = needed / sizeof(HMODULE); + if( new_size > NUM_MODULES ) { +#if OMPT_DEBUG + printf("ompt_tool_windows(): 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 ) ) { + return NULL; + } + } + for( i = 0; i < new_size; ++i ) { + (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_tool"); + if( ompt_tool_p ) { +#if OMPT_DEBUG + TCHAR modName[MAX_PATH]; + if( GetModuleFileName(modules[i], modName, MAX_PATH)) + printf("ompt_tool_windows(): ompt_tool found in module %s\n", + modName); +#endif + return ompt_tool_p(); + } +#if OMPT_DEBUG + else { + TCHAR modName[MAX_PATH]; + if( GetModuleFileName(modules[i], modName, MAX_PATH) ) + printf("ompt_tool_windows(): ompt_tool not found in module %s\n", + modName); + } +#endif + } + return NULL; +} +#else +# error Either __attribute__((weak)) or psapi.dll are required for OMPT support +#endif // OMPT_HAVE_WEAK_ATTRIBUTE void ompt_pre_init() { @@ -118,11 +196,14 @@ if (!ompt_env_var || !strcmp(ompt_env_var, "")) tool_setting = omp_tool_unset; - else if (!strcasecmp(ompt_env_var, "disabled")) + else if (OMPT_STR_MATCH(ompt_env_var, "disabled")) tool_setting = omp_tool_disabled; - else if (!strcasecmp(ompt_env_var, "enabled")) + else if (OMPT_STR_MATCH(ompt_env_var, "enabled")) tool_setting = omp_tool_enabled; +#if OMPT_DEBUG + printf("ompt_pre_init(): tool_setting = %d\n", tool_setting); +#endif switch(tool_setting) { case omp_tool_disabled: break; @@ -142,7 +223,9 @@ "\"enabled\").\n", ompt_env_var); break; } - +#if OMPT_DEBUG + printf("ompt_pre_init():ompt_enabled = %d\n", ompt_enabled); +#endif } Index: openmp/trunk/runtime/src/ompt-specific.h =================================================================== --- openmp/trunk/runtime/src/ompt-specific.h +++ openmp/trunk/runtime/src/ompt-specific.h @@ -34,6 +34,14 @@ ompt_frame_t *__ompt_get_task_frame_internal(int depth); +/***************************************************************************** + * macros + ****************************************************************************/ +#define OMPT_DEBUG KMP_DEBUG +#define OMPT_HAVE_WEAK_ATTRIBUTE KMP_HAVE_WEAK_ATTRIBUTE +#define OMPT_HAVE_PSAPI KMP_HAVE_PSAPI +#define OMPT_STR_MATCH(haystack, needle) __kmp_str_match(haystack, 0, needle) + //****************************************************************************** // inline functions Index: openmp/trunk/runtime/src/ompt-specific.c =================================================================== --- openmp/trunk/runtime/src/ompt-specific.c +++ openmp/trunk/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 //******************************************************************************