forked from OSchip/llvm-project
[OMPT] Windows Support for OMPT
The problem is that the ompt_tool() function (which must be implemented by a performance tool) should be defined in the RTL as well to cover the case when the tool is not present in the address space of the process. This functionality is accomplished with weak symbols in Unices. Unfortunately, Windows does not support weak symbols. The solution in these changes is to grab the list of all modules loaded by the process and then search for symbol "ompt_tool()" within them. The function ompt_tool_windows() performs the search of the ompt_tool symbol. If ompt_tool is found, then its return value is used to initialize the tool. If ompt_tool is not found, then ompt_tool_windows() returns NULL and OMPT is thus, disabled. While doing these changes, the OMPT_SUPPORT detection in CMake was changed to test for the required featuers for OMPT_SUPPORT, namely: builtin_frame_address() existence, weak attribute existence and psapi.dll existence. For LIBOMP_HAVE_OMPT_SUPPORT to be true, it must be that the builtin_frame_address() intrinsic exists AND one of: either weak attributes exist or psapi.dll exists. Also, since Process Status API is used I had to add new dependency -- psapi.dll to the library dependency micro test. Differential Revision: http://reviews.llvm.org/D14027 llvm-svn: 251654
This commit is contained in:
parent
e8df6750f4
commit
69e596a5e7
|
@ -273,7 +273,6 @@ if(LIBOMP_STATS)
|
|||
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
|
||||
|
|
|
@ -175,6 +175,7 @@ elseif(APPLE)
|
|||
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)
|
||||
|
|
|
@ -13,6 +13,7 @@ include(CheckCCompilerFlag)
|
|||
include(CheckCSourceCompiles)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckIncludeFiles)
|
||||
include(LibompCheckLinkerFlag)
|
||||
include(LibompCheckFortranFlag)
|
||||
|
||||
|
@ -187,8 +188,26 @@ else()
|
|||
endif()
|
||||
|
||||
# Check if OMPT support is available
|
||||
if(NOT WIN32)
|
||||
# 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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 @@ static ompt_interface_fn_t ompt_fn_lookup(const char *s);
|
|||
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 <psapi.h>
|
||||
#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 @@ void ompt_pre_init()
|
|||
|
||||
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 @@ void ompt_pre_init()
|
|||
"\"enabled\").\n", ompt_env_var);
|
||||
break;
|
||||
}
|
||||
|
||||
#if OMPT_DEBUG
|
||||
printf("ompt_pre_init():ompt_enabled = %d\n", ompt_enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
//******************************************************************************
|
||||
|
|
|
@ -34,6 +34,14 @@ ompt_task_id_t __ompt_get_task_id_internal(int depth);
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue