Bug Summary

File:projects/openmp/runtime/src/ompt-specific.cpp
Warning:line 423, column 23
Dereference of null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ompt-general.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D omp_EXPORTS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/projects/openmp/runtime/src -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/i18n -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/include/50 -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/thirdparty/ittnotify -U NDEBUG -D _GNU_SOURCE -D _REENTRANT -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-switch -Wno-missing-field-initializers -Wno-missing-braces -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/projects/openmp/runtime/src -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fno-rtti -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/ompt-general.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/ompt-general.cpp

1/*
2 * ompt-general.cpp -- OMPT implementation of interface functions
3 */
4
5//===----------------------------------------------------------------------===//
6//
7// The LLVM Compiler Infrastructure
8//
9// This file is dual licensed under the MIT and the University of Illinois Open
10// Source Licenses. See LICENSE.txt for details.
11//
12//===----------------------------------------------------------------------===//
13
14/*****************************************************************************
15 * system include files
16 ****************************************************************************/
17
18#include <assert.h>
19
20#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#if KMP_OS_UNIX1
25#include <dlfcn.h>
26#endif
27
28/*****************************************************************************
29 * ompt include files
30 ****************************************************************************/
31
32#include "ompt-specific.cpp"
33
34/*****************************************************************************
35 * macros
36 ****************************************************************************/
37
38#define ompt_get_callback_success1 1
39#define ompt_get_callback_failure0 0
40
41#define no_tool_present0 0
42
43#define OMPT_API_ROUTINEstatic static
44
45#ifndef OMPT_STR_MATCH
46#define OMPT_STR_MATCH(haystack, needle)__kmp_str_match(haystack, 0, needle) (!strcasecmp(haystack, needle))
47#endif
48
49/*****************************************************************************
50 * types
51 ****************************************************************************/
52
53typedef struct {
54 const char *state_name;
55 omp_state_t state_id;
56} omp_state_info_t;
57
58typedef struct {
59 const char *name;
60 kmp_mutex_impl_t id;
61} kmp_mutex_impl_info_t;
62
63enum tool_setting_e {
64 omp_tool_error,
65 omp_tool_unset,
66 omp_tool_disabled,
67 omp_tool_enabled
68};
69
70/*****************************************************************************
71 * global variables
72 ****************************************************************************/
73
74ompt_callbacks_active_t ompt_enabled;
75
76omp_state_info_t omp_state_info[] = {
77#define omp_state_macro(state, code) {#state, state},
78 FOREACH_OMP_STATE(omp_state_macro)omp_state_macro (omp_state_undefined, 0x102) omp_state_macro (
omp_state_work_serial, 0x000) omp_state_macro (omp_state_work_parallel
, 0x001) omp_state_macro (omp_state_work_reduction, 0x002) omp_state_macro
(omp_state_wait_barrier, 0x010) omp_state_macro (omp_state_wait_barrier_implicit_parallel
, 0x011) omp_state_macro (omp_state_wait_barrier_implicit_workshare
, 0x012) omp_state_macro (omp_state_wait_barrier_implicit, 0x013
) omp_state_macro (omp_state_wait_barrier_explicit, 0x014) omp_state_macro
(omp_state_wait_taskwait, 0x020) omp_state_macro (omp_state_wait_taskgroup
, 0x021) omp_state_macro (omp_state_wait_mutex, 0x040) omp_state_macro
(omp_state_wait_lock, 0x041) omp_state_macro (omp_state_wait_critical
, 0x042) omp_state_macro (omp_state_wait_atomic, 0x043) omp_state_macro
(omp_state_wait_ordered, 0x044) omp_state_macro (omp_state_wait_target
, 0x080) omp_state_macro (omp_state_wait_target_map, 0x081) omp_state_macro
(omp_state_wait_target_update, 0x082) omp_state_macro (omp_state_idle
, 0x100) omp_state_macro (omp_state_overhead, 0x101)
79#undef omp_state_macro
80};
81
82kmp_mutex_impl_info_t kmp_mutex_impl_info[] = {
83#define kmp_mutex_impl_macro(name, id) {#name, name},
84 FOREACH_KMP_MUTEX_IMPL(kmp_mutex_impl_macro)kmp_mutex_impl_macro (ompt_mutex_impl_unknown, 0) kmp_mutex_impl_macro
(kmp_mutex_impl_spin, 1) kmp_mutex_impl_macro (kmp_mutex_impl_queuing
, 2) kmp_mutex_impl_macro (kmp_mutex_impl_speculative, 3)
85#undef kmp_mutex_impl_macro
86};
87
88ompt_callbacks_internal_t ompt_callbacks;
89
90static ompt_start_tool_result_t *ompt_start_tool_result = NULL__null;
91
92/*****************************************************************************
93 * forward declarations
94 ****************************************************************************/
95
96static ompt_interface_fn_t ompt_fn_lookup(const char *s);
97
98OMPT_API_ROUTINEstatic ompt_data_t *ompt_get_thread_data(void);
99
100/*****************************************************************************
101 * initialization and finalization (private operations)
102 ****************************************************************************/
103
104typedef ompt_start_tool_result_t *(*ompt_start_tool_t)(unsigned int,
105 const char *);
106
107#if KMP_OS_DARWIN0
108
109// While Darwin supports weak symbols, the library that wishes to provide a new
110// implementation has to link against this runtime which defeats the purpose
111// of having tools that are agnostic of the underlying runtime implementation.
112//
113// Fortunately, the linker includes all symbols of an executable in the global
114// symbol table by default so dlsym() even finds static implementations of
115// ompt_start_tool. For this to work on Linux, -Wl,--export-dynamic needs to be
116// passed when building the application which we don't want to rely on.
117
118static ompt_start_tool_result_t *ompt_tool_darwin(unsigned int omp_version,
119 const char *runtime_version) {
120 ompt_start_tool_result_t *ret = NULL__null;
121 // Search symbol in the current address space.
122 ompt_start_tool_t start_tool =
123 (ompt_start_tool_t)dlsym(RTLD_DEFAULT((void *) 0), "ompt_start_tool");
124 if (start_tool) {
125 ret = start_tool(omp_version, runtime_version);
126 }
127 return ret;
128}
129
130#elif OMPT_HAVE_WEAK_ATTRIBUTE1
131
132// On Unix-like systems that support weak symbols the following implementation
133// of ompt_start_tool() will be used in case no tool-supplied implementation of
134// this function is present in the address space of a process.
135
136_OMP_EXTERNextern "C" OMPT_WEAK_ATTRIBUTE__attribute__((weak)) ompt_start_tool_result_t *
137ompt_start_tool(unsigned int omp_version, const char *runtime_version) {
138 ompt_start_tool_result_t *ret = NULL__null;
139 // Search next symbol in the current address space. This can happen if the
140 // runtime library is linked before the tool. Since glibc 2.2 strong symbols
141 // don't override weak symbols that have been found before unless the user
142 // sets the environment variable LD_DYNAMIC_WEAK.
143 ompt_start_tool_t next_tool =
144 (ompt_start_tool_t)dlsym(RTLD_NEXT((void *) -1l), "ompt_start_tool");
145 if (next_tool) {
146 ret = next_tool(omp_version, runtime_version);
147 }
148 return ret;
149}
150
151#elif OMPT_HAVE_PSAPI0
152
153// On Windows, the ompt_tool_windows function is used to find the
154// ompt_start_tool symbol across all modules loaded by a process. If
155// ompt_start_tool is found, ompt_start_tool's return value is used to
156// initialize the tool. Otherwise, NULL is returned and OMPT won't be enabled.
157
158#include <psapi.h>
159#pragma comment(lib, "psapi.lib")
160
161// The number of loaded modules to start enumeration with EnumProcessModules()
162#define NUM_MODULES 128
163
164static ompt_start_tool_result_t *
165ompt_tool_windows(unsigned int omp_version, const char *runtime_version) {
166 int i;
167 DWORD needed, new_size;
168 HMODULE *modules;
169 HANDLE process = GetCurrentProcess();
170 modules = (HMODULE *)malloc(NUM_MODULES * sizeof(HMODULE));
171 ompt_start_tool_t ompt_tool_p = NULL__null;
172
173#if OMPT_DEBUG0
174 printf("ompt_tool_windows(): looking for ompt_start_tool\n");
175#endif
176 if (!EnumProcessModules(process, modules, NUM_MODULES * sizeof(HMODULE),
177 &needed)) {
178 // Regardless of the error reason use the stub initialization function
179 free(modules);
180 return NULL__null;
181 }
182 // Check if NUM_MODULES is enough to list all modules
183 new_size = needed / sizeof(HMODULE);
184 if (new_size > NUM_MODULES) {
185#if OMPT_DEBUG0
186 printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed);
187#endif
188 modules = (HMODULE *)realloc(modules, needed);
189 // If resizing failed use the stub function.
190 if (!EnumProcessModules(process, modules, needed, &needed)) {
191 free(modules);
192 return NULL__null;
193 }
194 }
195 for (i = 0; i < new_size; ++i) {
196 (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_start_tool");
197 if (ompt_tool_p) {
198#if OMPT_DEBUG0
199 TCHAR modName[MAX_PATH];
200 if (GetModuleFileName(modules[i], modName, MAX_PATH))
201 printf("ompt_tool_windows(): ompt_start_tool found in module %s\n",
202 modName);
203#endif
204 free(modules);
205 return (*ompt_tool_p)(omp_version, runtime_version);
206 }
207#if OMPT_DEBUG0
208 else {
209 TCHAR modName[MAX_PATH];
210 if (GetModuleFileName(modules[i], modName, MAX_PATH))
211 printf("ompt_tool_windows(): ompt_start_tool not found in module %s\n",
212 modName);
213 }
214#endif
215 }
216 free(modules);
217 return NULL__null;
218}
219#else
220#error Activation of OMPT is not supported on this platform.
221#endif
222
223static ompt_start_tool_result_t *
224ompt_try_start_tool(unsigned int omp_version, const char *runtime_version) {
225 ompt_start_tool_result_t *ret = NULL__null;
226 ompt_start_tool_t start_tool = NULL__null;
227#if KMP_OS_WINDOWS0
228 // Cannot use colon to describe a list of absolute paths on Windows
229 const char *sep = ";";
230#else
231 const char *sep = ":";
232#endif
233
234#if KMP_OS_DARWIN0
235 // Try in the current address space
236 ret = ompt_tool_darwin(omp_version, runtime_version);
237#elif OMPT_HAVE_WEAK_ATTRIBUTE1
238 ret = ompt_start_tool(omp_version, runtime_version);
239#elif OMPT_HAVE_PSAPI0
240 ret = ompt_tool_windows(omp_version, runtime_version);
241#else
242#error Activation of OMPT is not supported on this platform.
243#endif
244 if (ret)
245 return ret;
246
247 // Try tool-libraries-var ICV
248 const char *tool_libs = getenv("OMP_TOOL_LIBRARIES");
249 if (tool_libs) {
250 char *libs = __kmp_str_format("%s", tool_libs);
251 char *buf;
252 char *fname = __kmp_str_token(libs, sep, &buf);
253 while (fname) {
254#if KMP_OS_UNIX1
255 void *h = dlopen(fname, RTLD_LAZY0x00001);
256 if (h) {
257 start_tool = (ompt_start_tool_t)dlsym(h, "ompt_start_tool");
258#elif KMP_OS_WINDOWS0
259 HMODULE h = LoadLibrary(fname);
260 if (h) {
261 start_tool = (ompt_start_tool_t)GetProcAddress(h, "ompt_start_tool");
262#else
263#error Activation of OMPT is not supported on this platform.
264#endif
265 if (start_tool && (ret = (*start_tool)(omp_version, runtime_version)))
266 break;
267 }
268 fname = __kmp_str_token(NULL__null, sep, &buf);
269 }
270 __kmp_str_free(&libs);
271 }
272 return ret;
273}
274
275void ompt_pre_init() {
276 //--------------------------------------------------
277 // Execute the pre-initialization logic only once.
278 //--------------------------------------------------
279 static int ompt_pre_initialized = 0;
280
281 if (ompt_pre_initialized)
282 return;
283
284 ompt_pre_initialized = 1;
285
286 //--------------------------------------------------
287 // Use a tool iff a tool is enabled and available.
288 //--------------------------------------------------
289 const char *ompt_env_var = getenv("OMP_TOOL");
290 tool_setting_e tool_setting = omp_tool_error;
291
292 if (!ompt_env_var || !strcmp(ompt_env_var, ""))
293 tool_setting = omp_tool_unset;
294 else if (OMPT_STR_MATCH(ompt_env_var, "disabled")__kmp_str_match(ompt_env_var, 0, "disabled"))
295 tool_setting = omp_tool_disabled;
296 else if (OMPT_STR_MATCH(ompt_env_var, "enabled")__kmp_str_match(ompt_env_var, 0, "enabled"))
297 tool_setting = omp_tool_enabled;
298
299#if OMPT_DEBUG0
300 printf("ompt_pre_init(): tool_setting = %d\n", tool_setting);
301#endif
302 switch (tool_setting) {
303 case omp_tool_disabled:
304 break;
305
306 case omp_tool_unset:
307 case omp_tool_enabled:
308
309 //--------------------------------------------------
310 // Load tool iff specified in environment variable
311 //--------------------------------------------------
312 ompt_start_tool_result =
313 ompt_try_start_tool(__kmp_openmp_version, ompt_get_runtime_version());
314
315 memset(&ompt_enabled, 0, sizeof(ompt_enabled));
316 break;
317
318 case omp_tool_error:
319 fprintf(stderrstderr, "Warning: OMP_TOOL has invalid value \"%s\".\n"
320 " legal values are (NULL,\"\",\"disabled\","
321 "\"enabled\").\n",
322 ompt_env_var);
323 break;
324 }
325#if OMPT_DEBUG0
326 printf("ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled);
327#endif
328}
329
330void ompt_post_init() {
331 //--------------------------------------------------
332 // Execute the post-initialization logic only once.
333 //--------------------------------------------------
334 static int ompt_post_initialized = 0;
335
336 if (ompt_post_initialized)
337 return;
338
339 ompt_post_initialized = 1;
340
341 //--------------------------------------------------
342 // Initialize the tool if so indicated.
343 //--------------------------------------------------
344 if (ompt_start_tool_result) {
345 ompt_enabled.enabled = !!ompt_start_tool_result->initialize(
346 ompt_fn_lookup, &(ompt_start_tool_result->tool_data));
347
348 if (!ompt_enabled.enabled) {
349 // tool not enabled, zero out the bitmap, and done
350 memset(&ompt_enabled, 0, sizeof(ompt_enabled));
351 return;
352 }
353
354 kmp_info_t *root_thread = ompt_get_thread();
355
356 ompt_set_thread_state(root_thread, omp_state_overhead);
357
358 if (ompt_enabled.ompt_callback_thread_begin) {
359 ompt_callbacks.ompt_callback(ompt_callback_thread_begin)ompt_callback_thread_begin_callback(
360 ompt_thread_initial, __ompt_get_thread_data_internal());
361 }
362 ompt_data_t *task_data;
363 __ompt_get_task_info_internal(0, NULL__null, &task_data, NULL__null, NULL__null, NULL__null);
364 if (ompt_enabled.ompt_callback_task_create) {
365 ompt_callbacks.ompt_callback(ompt_callback_task_create)ompt_callback_task_create_callback(
366 NULL__null, NULL__null, task_data, ompt_task_initial, 0, NULL__null);
367 }
368
369 ompt_set_thread_state(root_thread, omp_state_work_serial);
370 }
371}
372
373void ompt_fini() {
374 if (ompt_enabled.enabled) {
375 ompt_start_tool_result->finalize(&(ompt_start_tool_result->tool_data));
376 }
377
378 memset(&ompt_enabled, 0, sizeof(ompt_enabled));
379}
380
381/*****************************************************************************
382 * interface operations
383 ****************************************************************************/
384
385/*****************************************************************************
386 * state
387 ****************************************************************************/
388
389OMPT_API_ROUTINEstatic int ompt_enumerate_states(int current_state, int *next_state,
390 const char **next_state_name) {
391 const static int len = sizeof(omp_state_info) / sizeof(omp_state_info_t);
392 int i = 0;
393
394 for (i = 0; i < len - 1; i++) {
395 if (omp_state_info[i].state_id == current_state) {
396 *next_state = omp_state_info[i + 1].state_id;
397 *next_state_name = omp_state_info[i + 1].state_name;
398 return 1;
399 }
400 }
401
402 return 0;
403}
404
405OMPT_API_ROUTINEstatic int ompt_enumerate_mutex_impls(int current_impl,
406 int *next_impl,
407 const char **next_impl_name) {
408 const static int len =
409 sizeof(kmp_mutex_impl_info) / sizeof(kmp_mutex_impl_info_t);
410 int i = 0;
411 for (i = 0; i < len - 1; i++) {
412 if (kmp_mutex_impl_info[i].id != current_impl)
413 continue;
414 *next_impl = kmp_mutex_impl_info[i + 1].id;
415 *next_impl_name = kmp_mutex_impl_info[i + 1].name;
416 return 1;
417 }
418 return 0;
419}
420
421/*****************************************************************************
422 * callbacks
423 ****************************************************************************/
424
425OMPT_API_ROUTINEstatic int ompt_set_callback(ompt_callbacks_t which,
426 ompt_callback_t callback) {
427 switch (which) {
428
429#define ompt_event_macro(event_name, callback_type, event_id) \
430 case event_name: \
431 if (ompt_event_implementation_status(event_name)event_name_implemented) { \
432 ompt_callbacks.ompt_callback(event_name)event_name_callback = (callback_type)callback; \
433 ompt_enabled.event_name = (callback != 0); \
434 } \
435 if (callback) \
436 return ompt_event_implementation_status(event_name)event_name_implemented; \
437 else \
438 return ompt_set_always;
439
440 FOREACH_OMPT_EVENT(ompt_event_macro)ompt_event_macro (ompt_callback_thread_begin, ompt_callback_thread_begin_t
, 1) ompt_event_macro (ompt_callback_thread_end, ompt_callback_thread_end_t
, 2) ompt_event_macro (ompt_callback_parallel_begin, ompt_callback_parallel_begin_t
, 3) ompt_event_macro (ompt_callback_parallel_end, ompt_callback_parallel_end_t
, 4) ompt_event_macro (ompt_callback_task_create, ompt_callback_task_create_t
, 5) ompt_event_macro (ompt_callback_task_schedule, ompt_callback_task_schedule_t
, 6) ompt_event_macro (ompt_callback_implicit_task, ompt_callback_implicit_task_t
, 7) ompt_event_macro (ompt_callback_target, ompt_callback_target_t
, 8) ompt_event_macro (ompt_callback_target_data_op, ompt_callback_target_data_op_t
, 9) ompt_event_macro (ompt_callback_target_submit, ompt_callback_target_submit_t
, 10) ompt_event_macro (ompt_callback_control_tool, ompt_callback_control_tool_t
, 11) ompt_event_macro (ompt_callback_device_initialize, ompt_callback_device_initialize_t
, 12) ompt_event_macro (ompt_callback_device_finalize, ompt_callback_device_finalize_t
, 13) ompt_event_macro (ompt_callback_device_load, ompt_callback_device_load_t
, 14) ompt_event_macro (ompt_callback_device_unload, ompt_callback_device_unload_t
, 15) ompt_event_macro (ompt_callback_sync_region_wait, ompt_callback_sync_region_t
, 16) ompt_event_macro (ompt_callback_mutex_released, ompt_callback_mutex_t
, 17) ompt_event_macro (ompt_callback_task_dependences, ompt_callback_task_dependences_t
, 18) ompt_event_macro (ompt_callback_task_dependence, ompt_callback_task_dependence_t
, 19) ompt_event_macro (ompt_callback_work, ompt_callback_work_t
, 20) ompt_event_macro (ompt_callback_master, ompt_callback_master_t
, 21) ompt_event_macro (ompt_callback_target_map, ompt_callback_target_map_t
, 22) ompt_event_macro (ompt_callback_sync_region, ompt_callback_sync_region_t
, 23) ompt_event_macro (ompt_callback_lock_init, ompt_callback_mutex_acquire_t
, 24) ompt_event_macro (ompt_callback_lock_destroy, ompt_callback_mutex_t
, 25) ompt_event_macro (ompt_callback_mutex_acquire, ompt_callback_mutex_acquire_t
, 26) ompt_event_macro (ompt_callback_mutex_acquired, ompt_callback_mutex_t
, 27) ompt_event_macro (ompt_callback_nest_lock, ompt_callback_nest_lock_t
, 28) ompt_event_macro (ompt_callback_flush, ompt_callback_flush_t
, 29) ompt_event_macro (ompt_callback_cancel, ompt_callback_cancel_t
, 30) ompt_event_macro (ompt_callback_reduction, ompt_callback_sync_region_t
, 31) ompt_event_macro (ompt_callback_dispatch, ompt_callback_dispatch_t
, 32)
441
442#undef ompt_event_macro
443
444 default:
445 return ompt_set_error;
446 }
447}
448
449OMPT_API_ROUTINEstatic int ompt_get_callback(ompt_callbacks_t which,
450 ompt_callback_t *callback) {
451 switch (which) {
452
453#define ompt_event_macro(event_name, callback_type, event_id) \
454 case event_name: \
455 if (ompt_event_implementation_status(event_name)event_name_implemented) { \
456 ompt_callback_t mycb = \
457 (ompt_callback_t)ompt_callbacks.ompt_callback(event_name)event_name_callback; \
458 if (mycb) { \
459 *callback = mycb; \
460 return ompt_get_callback_success1; \
461 } \
462 } \
463 return ompt_get_callback_failure0;
464
465 FOREACH_OMPT_EVENT(ompt_event_macro)ompt_event_macro (ompt_callback_thread_begin, ompt_callback_thread_begin_t
, 1) ompt_event_macro (ompt_callback_thread_end, ompt_callback_thread_end_t
, 2) ompt_event_macro (ompt_callback_parallel_begin, ompt_callback_parallel_begin_t
, 3) ompt_event_macro (ompt_callback_parallel_end, ompt_callback_parallel_end_t
, 4) ompt_event_macro (ompt_callback_task_create, ompt_callback_task_create_t
, 5) ompt_event_macro (ompt_callback_task_schedule, ompt_callback_task_schedule_t
, 6) ompt_event_macro (ompt_callback_implicit_task, ompt_callback_implicit_task_t
, 7) ompt_event_macro (ompt_callback_target, ompt_callback_target_t
, 8) ompt_event_macro (ompt_callback_target_data_op, ompt_callback_target_data_op_t
, 9) ompt_event_macro (ompt_callback_target_submit, ompt_callback_target_submit_t
, 10) ompt_event_macro (ompt_callback_control_tool, ompt_callback_control_tool_t
, 11) ompt_event_macro (ompt_callback_device_initialize, ompt_callback_device_initialize_t
, 12) ompt_event_macro (ompt_callback_device_finalize, ompt_callback_device_finalize_t
, 13) ompt_event_macro (ompt_callback_device_load, ompt_callback_device_load_t
, 14) ompt_event_macro (ompt_callback_device_unload, ompt_callback_device_unload_t
, 15) ompt_event_macro (ompt_callback_sync_region_wait, ompt_callback_sync_region_t
, 16) ompt_event_macro (ompt_callback_mutex_released, ompt_callback_mutex_t
, 17) ompt_event_macro (ompt_callback_task_dependences, ompt_callback_task_dependences_t
, 18) ompt_event_macro (ompt_callback_task_dependence, ompt_callback_task_dependence_t
, 19) ompt_event_macro (ompt_callback_work, ompt_callback_work_t
, 20) ompt_event_macro (ompt_callback_master, ompt_callback_master_t
, 21) ompt_event_macro (ompt_callback_target_map, ompt_callback_target_map_t
, 22) ompt_event_macro (ompt_callback_sync_region, ompt_callback_sync_region_t
, 23) ompt_event_macro (ompt_callback_lock_init, ompt_callback_mutex_acquire_t
, 24) ompt_event_macro (ompt_callback_lock_destroy, ompt_callback_mutex_t
, 25) ompt_event_macro (ompt_callback_mutex_acquire, ompt_callback_mutex_acquire_t
, 26) ompt_event_macro (ompt_callback_mutex_acquired, ompt_callback_mutex_t
, 27) ompt_event_macro (ompt_callback_nest_lock, ompt_callback_nest_lock_t
, 28) ompt_event_macro (ompt_callback_flush, ompt_callback_flush_t
, 29) ompt_event_macro (ompt_callback_cancel, ompt_callback_cancel_t
, 30) ompt_event_macro (ompt_callback_reduction, ompt_callback_sync_region_t
, 31) ompt_event_macro (ompt_callback_dispatch, ompt_callback_dispatch_t
, 32)
466
467#undef ompt_event_macro
468
469 default:
470 return ompt_get_callback_failure0;
471 }
472}
473
474/*****************************************************************************
475 * parallel regions
476 ****************************************************************************/
477
478OMPT_API_ROUTINEstatic int ompt_get_parallel_info(int ancestor_level,
479 ompt_data_t **parallel_data,
480 int *team_size) {
481 return __ompt_get_parallel_info_internal(ancestor_level, parallel_data,
482 team_size);
483}
484
485OMPT_API_ROUTINEstatic omp_state_t ompt_get_state(omp_wait_id_t *wait_id) {
486 omp_state_t thread_state = __ompt_get_state_internal(wait_id);
487
488 if (thread_state == omp_state_undefined) {
489 thread_state = omp_state_work_serial;
490 }
491
492 return thread_state;
493}
494
495/*****************************************************************************
496 * tasks
497 ****************************************************************************/
498
499OMPT_API_ROUTINEstatic ompt_data_t *ompt_get_thread_data(void) {
500 return __ompt_get_thread_data_internal();
501}
502
503OMPT_API_ROUTINEstatic int ompt_get_task_info(int ancestor_level, int *type,
504 ompt_data_t **task_data,
505 omp_frame_t **task_frame,
506 ompt_data_t **parallel_data,
507 int *thread_num) {
508 return __ompt_get_task_info_internal(ancestor_level, type, task_data,
1
Calling '__ompt_get_task_info_internal'
509 task_frame, parallel_data, thread_num);
510}
511
512OMPT_API_ROUTINEstatic int ompt_get_task_memory(void **addr, size_t *size,
513 int block) {
514 // stub
515 return 0;
516}
517
518/*****************************************************************************
519 * num_procs
520 ****************************************************************************/
521
522OMPT_API_ROUTINEstatic int ompt_get_num_procs(void) {
523 // copied from kmp_ftn_entry.h (but modified: OMPT can only be called when
524 // runtime is initialized)
525 return __kmp_avail_proc;
526}
527
528/*****************************************************************************
529 * places
530 ****************************************************************************/
531
532OMPT_API_ROUTINEstatic int ompt_get_num_places(void) {
533// copied from kmp_ftn_entry.h (but modified)
534#if !KMP_AFFINITY_SUPPORTED1
535 return 0;
536#else
537 if (!KMP_AFFINITY_CAPABLE()(__kmp_affin_mask_size > 0))
538 return 0;
539 return __kmp_affinity_num_masks;
540#endif
541}
542
543OMPT_API_ROUTINEstatic int ompt_get_place_proc_ids(int place_num, int ids_size,
544 int *ids) {
545// copied from kmp_ftn_entry.h (but modified)
546#if !KMP_AFFINITY_SUPPORTED1
547 return 0;
548#else
549 int i, count;
550 int tmp_ids[ids_size];
551 if (!KMP_AFFINITY_CAPABLE()(__kmp_affin_mask_size > 0))
552 return 0;
553 if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
554 return 0;
555 /* TODO: Is this safe for asynchronous call from signal handler during runtime
556 * shutdown? */
557 kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num)__kmp_affinity_dispatch->index_mask_array(__kmp_affinity_masks
, place_num)
;
558 count = 0;
559 KMP_CPU_SET_ITERATE(i, mask)for (i = (mask)->begin(); (int)i != (mask)->end(); i = (
mask)->next(i))
{
560 if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)(__kmp_affin_fullMask)->is_set(i)) ||
561 (!KMP_CPU_ISSET(i, mask)(mask)->is_set(i))) {
562 continue;
563 }
564 if (count < ids_size)
565 tmp_ids[count] = i;
566 count++;
567 }
568 if (ids_size >= count) {
569 for (i = 0; i < count; i++) {
570 ids[i] = tmp_ids[i];
571 }
572 }
573 return count;
574#endif
575}
576
577OMPT_API_ROUTINEstatic int ompt_get_place_num(void) {
578// copied from kmp_ftn_entry.h (but modified)
579#if !KMP_AFFINITY_SUPPORTED1
580 return -1;
581#else
582 if (__kmp_get_gtid()__kmp_get_global_thread_id() < 0)
583 return -1;
584
585 int gtid;
586 kmp_info_t *thread;
587 if (!KMP_AFFINITY_CAPABLE()(__kmp_affin_mask_size > 0))
588 return -1;
589 gtid = __kmp_entry_gtid()__kmp_get_global_thread_id_reg();
590 thread = __kmp_thread_from_gtid(gtid);
591 if (thread == NULL__null || thread->th.th_current_place < 0)
592 return -1;
593 return thread->th.th_current_place;
594#endif
595}
596
597OMPT_API_ROUTINEstatic int ompt_get_partition_place_nums(int place_nums_size,
598 int *place_nums) {
599// copied from kmp_ftn_entry.h (but modified)
600#if !KMP_AFFINITY_SUPPORTED1
601 return 0;
602#else
603 if (__kmp_get_gtid()__kmp_get_global_thread_id() < 0)
604 return 0;
605
606 int i, gtid, place_num, first_place, last_place, start, end;
607 kmp_info_t *thread;
608 if (!KMP_AFFINITY_CAPABLE()(__kmp_affin_mask_size > 0))
609 return 0;
610 gtid = __kmp_entry_gtid()__kmp_get_global_thread_id_reg();
611 thread = __kmp_thread_from_gtid(gtid);
612 if (thread == NULL__null)
613 return 0;
614 first_place = thread->th.th_first_place;
615 last_place = thread->th.th_last_place;
616 if (first_place < 0 || last_place < 0)
617 return 0;
618 if (first_place <= last_place) {
619 start = first_place;
620 end = last_place;
621 } else {
622 start = last_place;
623 end = first_place;
624 }
625 if (end - start <= place_nums_size)
626 for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
627 place_nums[i] = place_num;
628 }
629 return end - start + 1;
630#endif
631}
632
633/*****************************************************************************
634 * places
635 ****************************************************************************/
636
637OMPT_API_ROUTINEstatic int ompt_get_proc_id(void) {
638 if (__kmp_get_gtid()__kmp_get_global_thread_id() < 0)
639 return -1;
640#if KMP_OS_LINUX1
641 return sched_getcpu();
642#elif KMP_OS_WINDOWS0
643 PROCESSOR_NUMBER pn;
644 GetCurrentProcessorNumberEx(&pn);
645 return 64 * pn.Group + pn.Number;
646#else
647 return -1;
648#endif
649}
650
651/*****************************************************************************
652 * compatability
653 ****************************************************************************/
654
655/*
656 * Currently unused function
657OMPT_API_ROUTINE int ompt_get_ompt_version() { return OMPT_VERSION; }
658*/
659
660/*****************************************************************************
661* application-facing API
662 ****************************************************************************/
663
664/*----------------------------------------------------------------------------
665 | control
666 ---------------------------------------------------------------------------*/
667
668int __kmp_control_tool(uint64_t command, uint64_t modifier, void *arg) {
669
670 if (ompt_enabled.enabled) {
671 if (ompt_enabled.ompt_callback_control_tool) {
672 return ompt_callbacks.ompt_callback(ompt_callback_control_tool)ompt_callback_control_tool_callback(
673 command, modifier, arg, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid())__ompt_load_return_address(__kmp_get_global_thread_id_reg()));
674 } else {
675 return -1;
676 }
677 } else {
678 return -2;
679 }
680}
681
682/*****************************************************************************
683 * misc
684 ****************************************************************************/
685
686OMPT_API_ROUTINEstatic uint64_t ompt_get_unique_id(void) {
687 return __ompt_get_unique_id_internal();
688}
689
690OMPT_API_ROUTINEstatic void ompt_finalize_tool(void) {
691 // stub
692}
693
694/*****************************************************************************
695 * Target
696 ****************************************************************************/
697
698OMPT_API_ROUTINEstatic int ompt_get_target_info(uint64_t *device_num,
699 ompt_id_t *target_id,
700 ompt_id_t *host_op_id) {
701 return 0; // thread is not in a target region
702}
703
704OMPT_API_ROUTINEstatic int ompt_get_num_devices(void) {
705 return 1; // only one device (the current device) is available
706}
707
708/*****************************************************************************
709 * API inquiry for tool
710 ****************************************************************************/
711
712static ompt_interface_fn_t ompt_fn_lookup(const char *s) {
713
714#define ompt_interface_fn(fn)fn_t fn_f = fn; if (strcmp(s, "fn") == 0) return (ompt_interface_fn_t
)fn_f;
\
715 fn##_t fn##_f = fn; \
716 if (strcmp(s, #fn) == 0) \
717 return (ompt_interface_fn_t)fn##_f;
718
719 FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn)ompt_enumerate_states_t ompt_enumerate_states_f = ompt_enumerate_states
; if (strcmp(s, "ompt_enumerate_states") == 0) return (ompt_interface_fn_t
)ompt_enumerate_states_f; ompt_enumerate_mutex_impls_t ompt_enumerate_mutex_impls_f
= ompt_enumerate_mutex_impls; if (strcmp(s, "ompt_enumerate_mutex_impls"
) == 0) return (ompt_interface_fn_t)ompt_enumerate_mutex_impls_f
; ompt_set_callback_t ompt_set_callback_f = ompt_set_callback
; if (strcmp(s, "ompt_set_callback") == 0) return (ompt_interface_fn_t
)ompt_set_callback_f; ompt_get_callback_t ompt_get_callback_f
= ompt_get_callback; if (strcmp(s, "ompt_get_callback") == 0
) return (ompt_interface_fn_t)ompt_get_callback_f; ompt_get_state_t
ompt_get_state_f = ompt_get_state; if (strcmp(s, "ompt_get_state"
) == 0) return (ompt_interface_fn_t)ompt_get_state_f; ompt_get_parallel_info_t
ompt_get_parallel_info_f = ompt_get_parallel_info; if (strcmp
(s, "ompt_get_parallel_info") == 0) return (ompt_interface_fn_t
)ompt_get_parallel_info_f; ompt_get_task_info_t ompt_get_task_info_f
= ompt_get_task_info; if (strcmp(s, "ompt_get_task_info") ==
0) return (ompt_interface_fn_t)ompt_get_task_info_f; ompt_get_task_memory_t
ompt_get_task_memory_f = ompt_get_task_memory; if (strcmp(s,
"ompt_get_task_memory") == 0) return (ompt_interface_fn_t)ompt_get_task_memory_f
; ompt_get_thread_data_t ompt_get_thread_data_f = ompt_get_thread_data
; if (strcmp(s, "ompt_get_thread_data") == 0) return (ompt_interface_fn_t
)ompt_get_thread_data_f; ompt_get_unique_id_t ompt_get_unique_id_f
= ompt_get_unique_id; if (strcmp(s, "ompt_get_unique_id") ==
0) return (ompt_interface_fn_t)ompt_get_unique_id_f; ompt_finalize_tool_t
ompt_finalize_tool_f = ompt_finalize_tool; if (strcmp(s, "ompt_finalize_tool"
) == 0) return (ompt_interface_fn_t)ompt_finalize_tool_f; ompt_get_num_procs_t
ompt_get_num_procs_f = ompt_get_num_procs; if (strcmp(s, "ompt_get_num_procs"
) == 0) return (ompt_interface_fn_t)ompt_get_num_procs_f; ompt_get_num_places_t
ompt_get_num_places_f = ompt_get_num_places; if (strcmp(s, "ompt_get_num_places"
) == 0) return (ompt_interface_fn_t)ompt_get_num_places_f; ompt_get_place_proc_ids_t
ompt_get_place_proc_ids_f = ompt_get_place_proc_ids; if (strcmp
(s, "ompt_get_place_proc_ids") == 0) return (ompt_interface_fn_t
)ompt_get_place_proc_ids_f; ompt_get_place_num_t ompt_get_place_num_f
= ompt_get_place_num; if (strcmp(s, "ompt_get_place_num") ==
0) return (ompt_interface_fn_t)ompt_get_place_num_f; ompt_get_partition_place_nums_t
ompt_get_partition_place_nums_f = ompt_get_partition_place_nums
; if (strcmp(s, "ompt_get_partition_place_nums") == 0) return
(ompt_interface_fn_t)ompt_get_partition_place_nums_f; ompt_get_proc_id_t
ompt_get_proc_id_f = ompt_get_proc_id; if (strcmp(s, "ompt_get_proc_id"
) == 0) return (ompt_interface_fn_t)ompt_get_proc_id_f; ompt_get_target_info_t
ompt_get_target_info_f = ompt_get_target_info; if (strcmp(s,
"ompt_get_target_info") == 0) return (ompt_interface_fn_t)ompt_get_target_info_f
; ompt_get_num_devices_t ompt_get_num_devices_f = ompt_get_num_devices
; if (strcmp(s, "ompt_get_num_devices") == 0) return (ompt_interface_fn_t
)ompt_get_num_devices_f;
720
721 return (ompt_interface_fn_t)0;
722}

/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/ompt-specific.cpp

1/*
2 * ompt-specific.cpp -- OMPT internal functions
3 */
4
5//===----------------------------------------------------------------------===//
6//
7// The LLVM Compiler Infrastructure
8//
9// This file is dual licensed under the MIT and the University of Illinois Open
10// Source Licenses. See LICENSE.txt for details.
11//
12//===----------------------------------------------------------------------===//
13
14//******************************************************************************
15// include files
16//******************************************************************************
17
18#include "kmp.h"
19#include "ompt-specific.h"
20
21#if KMP_OS_UNIX1
22#include <dlfcn.h>
23#endif
24
25#if KMP_OS_WINDOWS0
26#define THREAD_LOCAL__thread __declspec(thread)
27#else
28#define THREAD_LOCAL__thread __thread
29#endif
30
31#define OMPT_WEAK_ATTRIBUTE__attribute__((weak)) KMP_WEAK_ATTRIBUTE__attribute__((weak))
32
33//******************************************************************************
34// macros
35//******************************************************************************
36
37#define LWT_FROM_TEAM(team)(team)->t.ompt_serialized_team_info (team)->t.ompt_serialized_team_info
38
39#define OMPT_THREAD_ID_BITS16 16
40
41//******************************************************************************
42// private operations
43//******************************************************************************
44
45//----------------------------------------------------------
46// traverse the team and task hierarchy
47// note: __ompt_get_teaminfo and __ompt_get_task_info_object
48// traverse the hierarchy similarly and need to be
49// kept consistent
50//----------------------------------------------------------
51
52ompt_team_info_t *__ompt_get_teaminfo(int depth, int *size) {
53 kmp_info_t *thr = ompt_get_thread();
54
55 if (thr) {
56 kmp_team *team = thr->th.th_team;
57 if (team == NULL__null)
58 return NULL__null;
59
60 ompt_lw_taskteam_t *next_lwt = LWT_FROM_TEAM(team)(team)->t.ompt_serialized_team_info, *lwt = NULL__null;
61
62 while (depth > 0) {
63 // next lightweight team (if any)
64 if (lwt)
65 lwt = lwt->parent;
66
67 // next heavyweight team (if any) after
68 // lightweight teams are exhausted
69 if (!lwt && team) {
70 if (next_lwt) {
71 lwt = next_lwt;
72 next_lwt = NULL__null;
73 } else {
74 team = team->t.t_parent;
75 if (team) {
76 next_lwt = LWT_FROM_TEAM(team)(team)->t.ompt_serialized_team_info;
77 }
78 }
79 }
80
81 depth--;
82 }
83
84 if (lwt) {
85 // lightweight teams have one task
86 if (size)
87 *size = 1;
88
89 // return team info for lightweight team
90 return &lwt->ompt_team_info;
91 } else if (team) {
92 // extract size from heavyweight team
93 if (size)
94 *size = team->t.t_nproc;
95
96 // return team info for heavyweight team
97 return &team->t.ompt_team_info;
98 }
99 }
100
101 return NULL__null;
102}
103
104ompt_task_info_t *__ompt_get_task_info_object(int depth) {
105 ompt_task_info_t *info = NULL__null;
106 kmp_info_t *thr = ompt_get_thread();
107
108 if (thr) {
109 kmp_taskdata_t *taskdata = thr->th.th_current_task;
110 ompt_lw_taskteam_t *lwt = NULL__null,
111 *next_lwt = LWT_FROM_TEAM(taskdata->td_team)(taskdata->td_team)->t.ompt_serialized_team_info;
112
113 while (depth > 0) {
114 // next lightweight team (if any)
115 if (lwt)
116 lwt = lwt->parent;
117
118 // next heavyweight team (if any) after
119 // lightweight teams are exhausted
120 if (!lwt && taskdata) {
121 if (next_lwt) {
122 lwt = next_lwt;
123 next_lwt = NULL__null;
124 } else {
125 taskdata = taskdata->td_parent;
126 if (taskdata) {
127 next_lwt = LWT_FROM_TEAM(taskdata->td_team)(taskdata->td_team)->t.ompt_serialized_team_info;
128 }
129 }
130 }
131 depth--;
132 }
133
134 if (lwt) {
135 info = &lwt->ompt_task_info;
136 } else if (taskdata) {
137 info = &taskdata->ompt_task_info;
138 }
139 }
140
141 return info;
142}
143
144ompt_task_info_t *__ompt_get_scheduling_taskinfo(int depth) {
145 ompt_task_info_t *info = NULL__null;
146 kmp_info_t *thr = ompt_get_thread();
147
148 if (thr) {
149 kmp_taskdata_t *taskdata = thr->th.th_current_task;
150
151 ompt_lw_taskteam_t *lwt = NULL__null,
152 *next_lwt = LWT_FROM_TEAM(taskdata->td_team)(taskdata->td_team)->t.ompt_serialized_team_info;
153
154 while (depth > 0) {
155 // next lightweight team (if any)
156 if (lwt)
157 lwt = lwt->parent;
158
159 // next heavyweight team (if any) after
160 // lightweight teams are exhausted
161 if (!lwt && taskdata) {
162 // first try scheduling parent (for explicit task scheduling)
163 if (taskdata->ompt_task_info.scheduling_parent) {
164 taskdata = taskdata->ompt_task_info.scheduling_parent;
165 } else if (next_lwt) {
166 lwt = next_lwt;
167 next_lwt = NULL__null;
168 } else {
169 // then go for implicit tasks
170 taskdata = taskdata->td_parent;
171 if (taskdata) {
172 next_lwt = LWT_FROM_TEAM(taskdata->td_team)(taskdata->td_team)->t.ompt_serialized_team_info;
173 }
174 }
175 }
176 depth--;
177 }
178
179 if (lwt) {
180 info = &lwt->ompt_task_info;
181 } else if (taskdata) {
182 info = &taskdata->ompt_task_info;
183 }
184 }
185
186 return info;
187}
188
189//******************************************************************************
190// interface operations
191//******************************************************************************
192
193//----------------------------------------------------------
194// thread support
195//----------------------------------------------------------
196
197ompt_data_t *__ompt_get_thread_data_internal() {
198 if (__kmp_get_gtid()__kmp_get_global_thread_id() >= 0) {
199 kmp_info_t *thread = ompt_get_thread();
200 if (thread == NULL__null)
201 return NULL__null;
202 return &(thread->th.ompt_thread_info.thread_data);
203 }
204 return NULL__null;
205}
206
207//----------------------------------------------------------
208// state support
209//----------------------------------------------------------
210
211void __ompt_thread_assign_wait_id(void *variable) {
212 kmp_info_t *ti = ompt_get_thread();
213
214 ti->th.ompt_thread_info.wait_id = (omp_wait_id_t)variable;
215}
216
217omp_state_t __ompt_get_state_internal(omp_wait_id_t *omp_wait_id) {
218 kmp_info_t *ti = ompt_get_thread();
219
220 if (ti) {
221 if (omp_wait_id)
222 *omp_wait_id = ti->th.ompt_thread_info.wait_id;
223 return ti->th.ompt_thread_info.state;
224 }
225 return omp_state_undefined;
226}
227
228//----------------------------------------------------------
229// parallel region support
230//----------------------------------------------------------
231
232int __ompt_get_parallel_info_internal(int ancestor_level,
233 ompt_data_t **parallel_data,
234 int *team_size) {
235 if (__kmp_get_gtid()__kmp_get_global_thread_id() >= 0) {
236 ompt_team_info_t *info;
237 if (team_size) {
238 info = __ompt_get_teaminfo(ancestor_level, team_size);
239 } else {
240 info = __ompt_get_teaminfo(ancestor_level, NULL__null);
241 }
242 if (parallel_data) {
243 *parallel_data = info ? &(info->parallel_data) : NULL__null;
244 }
245 return info ? 2 : 0;
246 } else {
247 return 0;
248 }
249}
250
251//----------------------------------------------------------
252// lightweight task team support
253//----------------------------------------------------------
254
255void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid,
256 ompt_data_t *ompt_pid, void *codeptr) {
257 // initialize parallel_data with input, return address to parallel_data on
258 // exit
259 lwt->ompt_team_info.parallel_data = *ompt_pid;
260 lwt->ompt_team_info.master_return_address = codeptr;
261 lwt->ompt_task_info.task_data.value = 0;
262 lwt->ompt_task_info.frame.enter_frame = NULL__null;
263 lwt->ompt_task_info.frame.exit_frame = NULL__null;
264 lwt->ompt_task_info.scheduling_parent = NULL__null;
265 lwt->ompt_task_info.deps = NULL__null;
266 lwt->ompt_task_info.ndeps = 0;
267 lwt->heap = 0;
268 lwt->parent = 0;
269}
270
271void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr,
272 int on_heap) {
273 ompt_lw_taskteam_t *link_lwt = lwt;
274 if (thr->th.th_team->t.t_serialized >
275 1) { // we already have a team, so link the new team and swap values
276 if (on_heap) { // the lw_taskteam cannot stay on stack, allocate it on heap
277 link_lwt =
278 (ompt_lw_taskteam_t *)__kmp_allocate(sizeof(ompt_lw_taskteam_t))___kmp_allocate((sizeof(ompt_lw_taskteam_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/ompt-specific.cpp"
, 278)
;
279 }
280 link_lwt->heap = on_heap;
281
282 // would be swap in the (on_stack) case.
283 ompt_team_info_t tmp_team = lwt->ompt_team_info;
284 link_lwt->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr)(&(thr->th.th_team->t.ompt_team_info));
285 *OMPT_CUR_TEAM_INFO(thr)(&(thr->th.th_team->t.ompt_team_info)) = tmp_team;
286
287 ompt_task_info_t tmp_task = lwt->ompt_task_info;
288 link_lwt->ompt_task_info = *OMPT_CUR_TASK_INFO(thr)(&(thr->th.th_current_task->ompt_task_info));
289 *OMPT_CUR_TASK_INFO(thr)(&(thr->th.th_current_task->ompt_task_info)) = tmp_task;
290
291 // link the taskteam into the list of taskteams:
292 ompt_lw_taskteam_t *my_parent =
293 thr->th.th_team->t.ompt_serialized_team_info;
294 link_lwt->parent = my_parent;
295 thr->th.th_team->t.ompt_serialized_team_info = link_lwt;
296 } else {
297 // this is the first serialized team, so we just store the values in the
298 // team and drop the taskteam-object
299 *OMPT_CUR_TEAM_INFO(thr)(&(thr->th.th_team->t.ompt_team_info)) = lwt->ompt_team_info;
300 *OMPT_CUR_TASK_INFO(thr)(&(thr->th.th_current_task->ompt_task_info)) = lwt->ompt_task_info;
301 }
302}
303
304void __ompt_lw_taskteam_unlink(kmp_info_t *thr) {
305 ompt_lw_taskteam_t *lwtask = thr->th.th_team->t.ompt_serialized_team_info;
306 if (lwtask) {
307 thr->th.th_team->t.ompt_serialized_team_info = lwtask->parent;
308
309 ompt_team_info_t tmp_team = lwtask->ompt_team_info;
310 lwtask->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr)(&(thr->th.th_team->t.ompt_team_info));
311 *OMPT_CUR_TEAM_INFO(thr)(&(thr->th.th_team->t.ompt_team_info)) = tmp_team;
312
313 ompt_task_info_t tmp_task = lwtask->ompt_task_info;
314 lwtask->ompt_task_info = *OMPT_CUR_TASK_INFO(thr)(&(thr->th.th_current_task->ompt_task_info));
315 *OMPT_CUR_TASK_INFO(thr)(&(thr->th.th_current_task->ompt_task_info)) = tmp_task;
316
317 if (lwtask->heap) {
318 __kmp_free(lwtask)___kmp_free((lwtask), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/ompt-specific.cpp"
, 318)
;
319 lwtask = NULL__null;
320 }
321 }
322 // return lwtask;
323}
324
325//----------------------------------------------------------
326// task support
327//----------------------------------------------------------
328
329int __ompt_get_task_info_internal(int ancestor_level, int *type,
330 ompt_data_t **task_data,
331 omp_frame_t **task_frame,
332 ompt_data_t **parallel_data,
333 int *thread_num) {
334 if (__kmp_get_gtid()__kmp_get_global_thread_id() < 0)
2
Taking false branch
335 return 0;
336
337 if (ancestor_level < 0)
3
Assuming 'ancestor_level' is >= 0
4
Taking false branch
338 return 0;
339
340 // copied from __ompt_get_scheduling_taskinfo
341 ompt_task_info_t *info = NULL__null;
342 ompt_team_info_t *team_info = NULL__null;
343 kmp_info_t *thr = ompt_get_thread();
344 int level = ancestor_level;
345
346 if (thr) {
5
Assuming 'thr' is non-null
6
Taking true branch
347 kmp_taskdata_t *taskdata = thr->th.th_current_task;
348 if (taskdata == NULL__null)
7
Assuming 'taskdata' is not equal to NULL
8
Taking false branch
349 return 0;
350 kmp_team *team = thr->th.th_team, *prev_team = NULL__null;
351 if (team == NULL__null)
9
Assuming 'team' is not equal to NULL
10
Taking false branch
352 return 0;
353 ompt_lw_taskteam_t *lwt = NULL__null,
354 *next_lwt = LWT_FROM_TEAM(taskdata->td_team)(taskdata->td_team)->t.ompt_serialized_team_info,
355 *prev_lwt = NULL__null;
356
357 while (ancestor_level > 0) {
11
Assuming 'ancestor_level' is > 0
12
Loop condition is true. Entering loop body
22
Assuming 'ancestor_level' is > 0
23
Loop condition is true. Entering loop body
29
Assuming 'ancestor_level' is <= 0
30
Loop condition is false. Execution continues on line 388
358 // needed for thread_num
359 prev_team = team;
24
Value assigned to 'prev_team'
360 prev_lwt = lwt;
361 // next lightweight team (if any)
362 if (lwt)
13
Taking false branch
25
Taking false branch
363 lwt = lwt->parent;
364
365 // next heavyweight team (if any) after
366 // lightweight teams are exhausted
367 if (!lwt && taskdata) {
14
Taking true branch
26
Taking true branch
368 // first try scheduling parent (for explicit task scheduling)
369 if (taskdata->ompt_task_info.scheduling_parent) {
15
Assuming the condition is false
16
Taking false branch
27
Assuming the condition is true
28
Taking true branch
370 taskdata = taskdata->ompt_task_info.scheduling_parent;
371 } else if (next_lwt) {
17
Assuming 'next_lwt' is null
18
Taking false branch
372 lwt = next_lwt;
373 next_lwt = NULL__null;
374 } else {
375 // then go for implicit tasks
376 taskdata = taskdata->td_parent;
377 if (team == NULL__null)
19
Taking false branch
378 return 0;
379 team = team->t.t_parent;
380 if (taskdata) {
20
Assuming 'taskdata' is non-null
21
Taking true branch
381 next_lwt = LWT_FROM_TEAM(taskdata->td_team)(taskdata->td_team)->t.ompt_serialized_team_info;
382 }
383 }
384 }
385 ancestor_level--;
386 }
387
388 if (lwt) {
31
Taking false branch
389 info = &lwt->ompt_task_info;
390 team_info = &lwt->ompt_team_info;
391 if (type) {
392 *type = ompt_task_implicit;
393 }
394 } else if (taskdata) {
32
Taking true branch
395 info = &taskdata->ompt_task_info;
396 team_info = &team->t.ompt_team_info;
397 if (type) {
33
Assuming 'type' is null
34
Taking false branch
398 if (taskdata->td_parent) {
399 *type = (taskdata->td_flags.tasktype ? ompt_task_explicit
400 : ompt_task_implicit) |
401 TASK_TYPE_DETAILS_FORMAT(taskdata)((taskdata->td_flags.task_serial || taskdata->td_flags.
tasking_ser) ? ompt_task_undeferred : 0x0) | ((!(taskdata->
td_flags.tiedness)) ? ompt_task_untied : 0x0) | (taskdata->
td_flags.final ? ompt_task_final : 0x0) | (taskdata->td_flags
.merged_if0 ? ompt_task_mergeable : 0x0)
;
402 } else {
403 *type = ompt_task_initial;
404 }
405 }
406 }
407 if (task_data) {
35
Assuming 'task_data' is null
36
Taking false branch
408 *task_data = info ? &info->task_data : NULL__null;
409 }
410 if (task_frame) {
37
Assuming 'task_frame' is null
38
Taking false branch
411 // OpenMP spec asks for the scheduling task to be returned.
412 *task_frame = info ? &info->frame : NULL__null;
413 }
414 if (parallel_data) {
39
Assuming 'parallel_data' is non-null
40
Taking true branch
415 *parallel_data = team_info ? &(team_info->parallel_data) : NULL__null;
41
Assuming 'team_info' is null
42
Assuming pointer value is null
43
'?' condition is false
416 }
417 if (thread_num) {
44
Assuming 'thread_num' is non-null
45
Taking true branch
418 if (level == 0)
46
Taking false branch
419 *thread_num = __kmp_get_tid()(__kmp_tid_from_gtid(__kmp_get_global_thread_id()));
420 else if (prev_lwt)
47
Taking false branch
421 *thread_num = 0;
422 else
423 *thread_num = prev_team->t.t_master_tid;
48
Dereference of null pointer
424 // *thread_num = team->t.t_master_tid;
425 }
426 return info ? 2 : 0;
427 }
428 return 0;
429}
430
431//----------------------------------------------------------
432// team support
433//----------------------------------------------------------
434
435void __ompt_team_assign_id(kmp_team_t *team, ompt_data_t ompt_pid) {
436 team->t.ompt_team_info.parallel_data = ompt_pid;
437}
438
439//----------------------------------------------------------
440// misc
441//----------------------------------------------------------
442
443static uint64_t __ompt_get_unique_id_internal() {
444 static uint64_t thread = 1;
445 static THREAD_LOCAL__thread uint64_t ID = 0;
446 if (ID == 0) {
447 uint64_t new_thread = KMP_TEST_THEN_INC64((kmp_int64 *)&thread)__sync_fetch_and_add((volatile kmp_int64 *)((kmp_int64 *)&
thread), 1LL)
;
448 ID = new_thread << (sizeof(uint64_t) * 8 - OMPT_THREAD_ID_BITS16);
449 }
450 return ++ID;
451}