summaryrefslogtreecommitdiffstats
path: root/openmp/runtime
diff options
context:
space:
mode:
authorJonathan Peyton <jonathan.l.peyton@intel.com>2015-10-29 20:56:24 +0000
committerJonathan Peyton <jonathan.l.peyton@intel.com>2015-10-29 20:56:24 +0000
commit69e596a5e7dc0038191a7d10cddf7c6cf77f4ff7 (patch)
tree7d0c4f9eb892ee53f9dd3fc2a80eec96f8e90a73 /openmp/runtime
parente8df6750f434af5ce85a8683e6dea445973c9eb7 (diff)
downloadbcm5719-llvm-69e596a5e7dc0038191a7d10cddf7c6cf77f4ff7.tar.gz
bcm5719-llvm-69e596a5e7dc0038191a7d10cddf7c6cf77f4ff7.zip
[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
Diffstat (limited to 'openmp/runtime')
-rw-r--r--openmp/runtime/CMakeLists.txt1
-rw-r--r--openmp/runtime/cmake/LibompMicroTests.cmake1
-rw-r--r--openmp/runtime/cmake/config-ix.cmake25
-rw-r--r--openmp/runtime/src/kmp_config.h.cmake4
-rw-r--r--openmp/runtime/src/ompt-general.c95
-rw-r--r--openmp/runtime/src/ompt-specific.c2
-rw-r--r--openmp/runtime/src/ompt-specific.h8
7 files changed, 125 insertions, 11 deletions
diff --git a/openmp/runtime/CMakeLists.txt b/openmp/runtime/CMakeLists.txt
index 4ca5450b966..995cf901aca 100644
--- a/openmp/runtime/CMakeLists.txt
+++ b/openmp/runtime/CMakeLists.txt
@@ -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
diff --git a/openmp/runtime/cmake/LibompMicroTests.cmake b/openmp/runtime/cmake/LibompMicroTests.cmake
index dd24748766b..4087703f387 100644
--- a/openmp/runtime/cmake/LibompMicroTests.cmake
+++ b/openmp/runtime/cmake/LibompMicroTests.cmake
@@ -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)
diff --git a/openmp/runtime/cmake/config-ix.cmake b/openmp/runtime/cmake/config-ix.cmake
index 875b5519a26..9c7848b3bcf 100644
--- a/openmp/runtime/cmake/config-ix.cmake
+++ b/openmp/runtime/cmake/config-ix.cmake
@@ -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)
- 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()
+
diff --git a/openmp/runtime/src/kmp_config.h.cmake b/openmp/runtime/src/kmp_config.h.cmake
index 16d0b20a382..aa0a1aa9a50 100644
--- a/openmp/runtime/src/kmp_config.h.cmake
+++ b/openmp/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
diff --git a/openmp/runtime/src/ompt-general.c b/openmp/runtime/src/ompt-general.c
index 3d2aba2f388..88f2d2e8f66 100644
--- a/openmp/runtime/src/ompt-general.c
+++ b/openmp/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 @@ 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
}
diff --git a/openmp/runtime/src/ompt-specific.c b/openmp/runtime/src/ompt-specific.c
index c249e86beb1..49f668af100 100644
--- a/openmp/runtime/src/ompt-specific.c
+++ b/openmp/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
//******************************************************************************
diff --git a/openmp/runtime/src/ompt-specific.h b/openmp/runtime/src/ompt-specific.h
index 7512ad94096..bcbfdd3cf2d 100644
--- a/openmp/runtime/src/ompt-specific.h
+++ b/openmp/runtime/src/ompt-specific.h
@@ -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
OpenPOWER on IntegriCloud