Skip to content

Commit 69e596a

Browse files
committedOct 29, 2015
[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
1 parent e8df675 commit 69e596a

File tree

7 files changed

+125
-11
lines changed

7 files changed

+125
-11
lines changed
 

‎openmp/runtime/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ if(LIBOMP_STATS)
273273
endif()
274274

275275
# OMPT-support
276-
# TODO: Make this a real feature check
277276
set(LIBOMP_OMPT_SUPPORT FALSE CACHE BOOL
278277
"OMPT-support?")
279278
set(LIBOMP_OMPT_BLAME TRUE CACHE BOOL

‎openmp/runtime/cmake/LibompMicroTests.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ elseif(APPLE)
175175
set(libomp_expected_library_deps /usr/lib/libSystem.B.dylib)
176176
elseif(WIN32)
177177
set(libomp_expected_library_deps kernel32.dll)
178+
libomp_append(libomp_expected_library_deps psapi.dll LIBOMP_OMPT_SUPPORT)
178179
else()
179180
if(${MIC})
180181
set(libomp_expected_library_deps libc.so.6 libpthread.so.0 libdl.so.2)

‎openmp/runtime/cmake/config-ix.cmake

+22-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ include(CheckCCompilerFlag)
1313
include(CheckCSourceCompiles)
1414
include(CheckCXXCompilerFlag)
1515
include(CheckLibraryExists)
16+
include(CheckIncludeFiles)
1617
include(LibompCheckLinkerFlag)
1718
include(LibompCheckFortranFlag)
1819

@@ -187,8 +188,26 @@ else()
187188
endif()
188189

189190
# Check if OMPT support is available
190-
if(NOT WIN32)
191-
set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
192-
else()
191+
# Currently, __builtin_frame_address() is required for OMPT
192+
# Weak attribute is required for Unices, LIBPSAPI is used for Windows
193+
check_c_source_compiles("int main(int argc, char** argv) {
194+
void* p = __builtin_frame_address(0);
195+
return 0;}" LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
196+
check_c_source_compiles("__attribute__ ((weak)) int foo(int a) { return a*a; }
197+
int main(int argc, char** argv) {
198+
return foo(argc);}" LIBOMP_HAVE_WEAK_ATTRIBUTE)
199+
check_include_files("windows.h;psapi.h" LIBOMP_HAVE_PSAPI_H)
200+
check_library_exists(psapi EnumProcessModules "" LIBOMP_HAVE_LIBPSAPI)
201+
if(LIBOMP_HAVE_PSAPI_H AND LIBOMP_HAVE_LIBPSAPI)
202+
set(LIBOMP_HAVE_PSAPI TRUE)
203+
endif()
204+
if(NOT LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
193205
set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
206+
else()
207+
if(LIBOMP_HAVE_WEAK_ATTRIBUTE OR LIBOMP_HAVE_PSAPI)
208+
set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
209+
else()
210+
set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
211+
endif()
194212
endif()
213+

‎openmp/runtime/src/kmp_config.h.cmake

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#if LIBOMP_USE_VERSION_SYMBOLS
2828
# define KMP_USE_VERSION_SYMBOLS
2929
#endif
30+
#cmakedefine01 LIBOMP_HAVE_WEAK_ATTRIBUTE
31+
#define KMP_HAVE_WEAK_ATTRIBUTE LIBOMP_HAVE_WEAK_ATTRIBUTE
32+
#cmakedefine01 LIBOMP_HAVE_PSAPI
33+
#define KMP_HAVE_PSAPI LIBOMP_HAVE_PSAPI
3034
#cmakedefine01 LIBOMP_STATS
3135
#define KMP_STATS_ENABLED LIBOMP_STATS
3236
#cmakedefine01 LIBOMP_USE_DEBUGGER

‎openmp/runtime/src/ompt-general.c

+89-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* ompt include files
1616
****************************************************************************/
1717

18-
#include "kmp_config.h"
1918
#include "ompt-internal.h"
2019
#include "ompt-specific.c"
2120

@@ -32,6 +31,9 @@
3231

3332
#define OMPT_API_ROUTINE static
3433

34+
#ifndef OMPT_STR_MATCH
35+
#define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle))
36+
#endif
3537

3638

3739
/*****************************************************************************
@@ -87,17 +89,93 @@ static ompt_interface_fn_t ompt_fn_lookup(const char *s);
8789
OMPT_API_ROUTINE ompt_thread_id_t ompt_get_thread_id(void);
8890

8991

90-
9192
/*****************************************************************************
9293
* initialization and finalization (private operations)
9394
****************************************************************************/
9495

95-
_OMP_EXTERN __attribute__ (( weak ))
96+
/* On Unix-like systems that support weak symbols the following implementation
97+
* of ompt_tool() will be used in case no tool-supplied implementation of
98+
* this function is present in the address space of a process.
99+
*
100+
* On Windows, the ompt_tool_windows function is used to find the
101+
* ompt_tool symbol across all modules loaded by a process. If ompt_tool is
102+
* found, ompt_tool's return value is used to initialize the tool. Otherwise,
103+
* NULL is returned and OMPT won't be enabled */
104+
#if OMPT_HAVE_WEAK_ATTRIBUTE
105+
_OMP_EXTERN
106+
__attribute__ (( weak ))
96107
ompt_initialize_t ompt_tool()
97108
{
109+
#if OMPT_DEBUG
110+
printf("ompt_tool() is called from the RTL\n");
111+
#endif
98112
return NULL;
99113
}
100114

115+
#elif OMPT_HAVE_PSAPI
116+
117+
#include <psapi.h>
118+
#pragma comment(lib, "psapi.lib")
119+
#define ompt_tool ompt_tool_windows
120+
121+
// The number of loaded modules to start enumeration with EnumProcessModules()
122+
#define NUM_MODULES 128
123+
124+
static
125+
ompt_initialize_t ompt_tool_windows()
126+
{
127+
int i;
128+
DWORD needed, new_size;
129+
HMODULE *modules;
130+
HANDLE process = GetCurrentProcess();
131+
modules = (HMODULE*)malloc( NUM_MODULES * sizeof(HMODULE) );
132+
ompt_initialize_t (*ompt_tool_p)() = NULL;
133+
134+
#if OMPT_DEBUG
135+
printf("ompt_tool_windows(): looking for ompt_tool\n");
136+
#endif
137+
if( !EnumProcessModules( process, modules, NUM_MODULES * sizeof(HMODULE),
138+
&needed ) ) {
139+
// Regardless of the error reason use the stub initialization function
140+
return NULL;
141+
}
142+
// Check if NUM_MODULES is enough to list all modules
143+
new_size = needed / sizeof(HMODULE);
144+
if( new_size > NUM_MODULES ) {
145+
#if OMPT_DEBUG
146+
printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed);
147+
#endif
148+
modules = (HMODULE*)realloc( modules, needed );
149+
// If resizing failed use the stub function.
150+
if( !EnumProcessModules( process, modules, needed, &needed ) ) {
151+
return NULL;
152+
}
153+
}
154+
for( i = 0; i < new_size; ++i ) {
155+
(FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_tool");
156+
if( ompt_tool_p ) {
157+
#if OMPT_DEBUG
158+
TCHAR modName[MAX_PATH];
159+
if( GetModuleFileName(modules[i], modName, MAX_PATH))
160+
printf("ompt_tool_windows(): ompt_tool found in module %s\n",
161+
modName);
162+
#endif
163+
return ompt_tool_p();
164+
}
165+
#if OMPT_DEBUG
166+
else {
167+
TCHAR modName[MAX_PATH];
168+
if( GetModuleFileName(modules[i], modName, MAX_PATH) )
169+
printf("ompt_tool_windows(): ompt_tool not found in module %s\n",
170+
modName);
171+
}
172+
#endif
173+
}
174+
return NULL;
175+
}
176+
#else
177+
# error Either __attribute__((weak)) or psapi.dll are required for OMPT support
178+
#endif // OMPT_HAVE_WEAK_ATTRIBUTE
101179

102180
void ompt_pre_init()
103181
{
@@ -118,11 +196,14 @@ void ompt_pre_init()
118196

119197
if (!ompt_env_var || !strcmp(ompt_env_var, ""))
120198
tool_setting = omp_tool_unset;
121-
else if (!strcasecmp(ompt_env_var, "disabled"))
199+
else if (OMPT_STR_MATCH(ompt_env_var, "disabled"))
122200
tool_setting = omp_tool_disabled;
123-
else if (!strcasecmp(ompt_env_var, "enabled"))
201+
else if (OMPT_STR_MATCH(ompt_env_var, "enabled"))
124202
tool_setting = omp_tool_enabled;
125203

204+
#if OMPT_DEBUG
205+
printf("ompt_pre_init(): tool_setting = %d\n", tool_setting);
206+
#endif
126207
switch(tool_setting) {
127208
case omp_tool_disabled:
128209
break;
@@ -142,7 +223,9 @@ void ompt_pre_init()
142223
"\"enabled\").\n", ompt_env_var);
143224
break;
144225
}
145-
226+
#if OMPT_DEBUG
227+
printf("ompt_pre_init():ompt_enabled = %d\n", ompt_enabled);
228+
#endif
146229
}
147230

148231

‎openmp/runtime/src/ompt-specific.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#define NEXT_ID(id_ptr,tid) \
3030
((KMP_TEST_THEN_INC64(id_ptr) << OMPT_THREAD_ID_BITS) | (tid))
3131
#else
32-
#define NEXT_ID(id_ptr,tid) (KMP_TEST_THEN_INC64(id_ptr))
32+
#define NEXT_ID(id_ptr,tid) (KMP_TEST_THEN_INC64((volatile kmp_int64 *)id_ptr))
3333
#endif
3434

3535
//******************************************************************************

‎openmp/runtime/src/ompt-specific.h

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ ompt_task_id_t __ompt_get_task_id_internal(int depth);
3434
ompt_frame_t *__ompt_get_task_frame_internal(int depth);
3535

3636

37+
/*****************************************************************************
38+
* macros
39+
****************************************************************************/
40+
#define OMPT_DEBUG KMP_DEBUG
41+
#define OMPT_HAVE_WEAK_ATTRIBUTE KMP_HAVE_WEAK_ATTRIBUTE
42+
#define OMPT_HAVE_PSAPI KMP_HAVE_PSAPI
43+
#define OMPT_STR_MATCH(haystack, needle) __kmp_str_match(haystack, 0, needle)
44+
3745

3846
//******************************************************************************
3947
// inline functions

0 commit comments

Comments
 (0)
Please sign in to comment.