5 //===----------------------------------------------------------------------===//
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //===----------------------------------------------------------------------===//
14 #include <omp-tools.h>
25 #define OMPD_WEAK_ATTR __attribute__((weak))
27 struct _ompd_aspace_cont
{
30 struct _ompd_thread_cont
{
33 ompd_address_space_context_t acontext
= {42};
37 ompd_rc_t
_print(const char *str
, int category
);
39 // NOTE: implement functions to check parameters of OMPD API functions for
41 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_api_version(ompd_word_t
*addr
) {
42 static ompd_rc_t (*my_get_api_version
)(ompd_word_t
*) = NULL
;
43 if (!my_get_api_version
) {
44 my_get_api_version
= dlsym(ompd_library
, "ompd_get_api_version");
49 return my_get_api_version(addr
);
52 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_version_string(const char **string
) {
53 static ompd_rc_t (*my_get_version_string
)(const char **) = NULL
;
54 if (!my_get_version_string
) {
55 my_get_version_string
= dlsym(ompd_library
, "ompd_get_version_string");
60 return my_get_version_string(string
);
63 OMPD_WEAK_ATTR ompd_rc_t
ompd_finalize(void) {
64 static ompd_rc_t (*my_ompd_finalize
)(void) = NULL
;
65 if (!my_ompd_finalize
) {
66 my_ompd_finalize
= dlsym(ompd_library
, "ompd_finalize");
71 return my_ompd_finalize();
74 OMPD_WEAK_ATTR ompd_rc_t
75 ompd_process_initialize(ompd_address_space_context_t
*context
,
76 ompd_address_space_handle_t
**handle
) {
77 static ompd_rc_t (*my_ompd_process_initialize
)(
78 ompd_address_space_context_t
*, ompd_address_space_handle_t
**) = NULL
;
79 if (!my_ompd_process_initialize
) {
80 my_ompd_process_initialize
= dlsym(ompd_library
, "ompd_process_initialize");
85 return my_ompd_process_initialize(context
, handle
);
88 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_omp_version(
89 ompd_address_space_handle_t
*address_space
, ompd_word_t
*omp_version
) {
90 static ompd_rc_t (*my_ompd_get_omp_version
)(ompd_address_space_handle_t
*,
91 ompd_word_t
*) = NULL
;
92 if (!my_ompd_get_omp_version
) {
93 my_ompd_get_omp_version
= dlsym(ompd_library
, "ompd_get_omp_version");
98 return my_ompd_get_omp_version(address_space
, omp_version
);
101 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_omp_version_string(
102 ompd_address_space_handle_t
*address_space
, const char **string
) {
103 static ompd_rc_t (*my_ompd_get_omp_version_string
)(
104 ompd_address_space_handle_t
*, const char **) = NULL
;
105 if (!my_ompd_get_omp_version_string
) {
106 my_ompd_get_omp_version_string
=
107 dlsym(ompd_library
, "ompd_get_omp_version_string");
109 return ompd_rc_error
;
112 return my_ompd_get_omp_version_string(address_space
, string
);
115 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_thread_handle(
116 ompd_address_space_handle_t
*handle
, ompd_thread_id_t kind
,
117 ompd_size_t tidSize
, const void *tid
, ompd_thread_handle_t
**threadHandle
) {
118 static ompd_rc_t (*my_get_thread_handle
)(
119 ompd_address_space_handle_t
*, ompd_thread_id_t
, ompd_size_t
,
120 const void *, ompd_thread_handle_t
**) = NULL
;
121 if (!my_get_thread_handle
) {
122 my_get_thread_handle
= dlsym(ompd_library
, "ompd_get_thread_handle");
124 return ompd_rc_error
;
127 return my_get_thread_handle(handle
, kind
, tidSize
, tid
, threadHandle
);
130 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_thread_in_parallel(
131 ompd_parallel_handle_t
*parallelHandle
, int threadNum
,
132 ompd_thread_handle_t
**threadHandle
) {
133 static ompd_rc_t (*my_get_thread_in_parallel
)(ompd_parallel_handle_t
*, int,
134 ompd_thread_handle_t
**) = NULL
;
135 if (!my_get_thread_in_parallel
) {
136 my_get_thread_in_parallel
=
137 dlsym(ompd_library
, "ompd_get_thread_in_parallel");
139 return ompd_rc_error
;
142 return my_get_thread_in_parallel(parallelHandle
, threadNum
, threadHandle
);
145 OMPD_WEAK_ATTR ompd_rc_t
ompd_thread_handle_compare(
146 ompd_thread_handle_t
*thread_handle1
, ompd_thread_handle_t
*thread_handle2
,
148 static ompd_rc_t (*my_thread_handle_compare
)(
149 ompd_thread_handle_t
*, ompd_thread_handle_t
*, int *) = NULL
;
150 if (!my_thread_handle_compare
) {
151 my_thread_handle_compare
=
152 dlsym(ompd_library
, "ompd_thread_handle_compare");
154 return ompd_rc_error
;
157 return my_thread_handle_compare(thread_handle1
, thread_handle2
, cmp_value
);
160 OMPD_WEAK_ATTR ompd_rc_t
161 ompd_get_curr_parallel_handle(ompd_thread_handle_t
*threadHandle
,
162 ompd_parallel_handle_t
**parallelHandle
) {
163 static ompd_rc_t (*my_get_current_parallel_handle
)(
164 ompd_thread_handle_t
*, ompd_parallel_handle_t
**) = NULL
;
165 if (!my_get_current_parallel_handle
) {
166 my_get_current_parallel_handle
=
167 dlsym(ompd_library
, "ompd_get_curr_parallel_handle");
169 return ompd_rc_error
;
172 return my_get_current_parallel_handle(threadHandle
, parallelHandle
);
175 OMPD_WEAK_ATTR ompd_rc_t
ompd_parallel_handle_compare(
176 ompd_parallel_handle_t
*parallel_handle_1
,
177 ompd_parallel_handle_t
*parallel_handle_2
, int *cmp_value
) {
178 static ompd_rc_t (*my_parallel_handle_compare
)(
179 ompd_parallel_handle_t
*, ompd_parallel_handle_t
*, int *) = NULL
;
180 if (!my_parallel_handle_compare
) {
181 my_parallel_handle_compare
=
182 dlsym(ompd_library
, "ompd_parallel_handle_compare");
184 return ompd_rc_error
;
187 return my_parallel_handle_compare(parallel_handle_1
, parallel_handle_2
,
191 OMPD_WEAK_ATTR ompd_rc_t
192 ompd_get_enclosing_parallel_handle(ompd_parallel_handle_t
*parallelHandle
,
193 ompd_parallel_handle_t
**enclosing
) {
194 static ompd_rc_t (*my_get_enclosing_parallel_handle
)(
195 ompd_parallel_handle_t
*, ompd_parallel_handle_t
**) = NULL
;
196 if (!my_get_enclosing_parallel_handle
) {
197 my_get_enclosing_parallel_handle
=
198 dlsym(ompd_library
, "ompd_get_enclosing_parallel_handle");
200 return ompd_rc_error
;
203 return my_get_enclosing_parallel_handle(parallelHandle
, enclosing
);
206 OMPD_WEAK_ATTR ompd_rc_t
207 ompd_get_task_parallel_handle(ompd_task_handle_t
*taskHandle
,
208 ompd_parallel_handle_t
**taskParallelHandle
) {
209 static ompd_rc_t (*my_get_task_parallel_handle
)(
210 ompd_task_handle_t
*, ompd_parallel_handle_t
**) = NULL
;
211 if (!my_get_task_parallel_handle
) {
212 my_get_task_parallel_handle
=
213 dlsym(ompd_library
, "ompd_get_task_parallel_handle");
215 return ompd_rc_error
;
218 return my_get_task_parallel_handle(taskHandle
, taskParallelHandle
);
221 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_curr_task_handle(
222 ompd_thread_handle_t
*threadHandle
, ompd_task_handle_t
**taskHandle
) {
223 static ompd_rc_t (*my_get_current_task_handle
)(ompd_thread_handle_t
*,
224 ompd_task_handle_t
**) = NULL
;
225 if (!my_get_current_task_handle
) {
226 my_get_current_task_handle
=
227 dlsym(ompd_library
, "ompd_get_curr_task_handle");
229 return ompd_rc_error
;
232 return my_get_current_task_handle(threadHandle
, taskHandle
);
235 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_generating_task_handle(
236 ompd_task_handle_t
*taskHandle
, ompd_task_handle_t
**generating
) {
237 static ompd_rc_t (*my_get_generating_task_handle
)(
238 ompd_task_handle_t
*, ompd_task_handle_t
**) = NULL
;
239 if (!my_get_generating_task_handle
) {
240 my_get_generating_task_handle
=
241 dlsym(ompd_library
, "ompd_get_generating_task_handle");
243 return ompd_rc_error
;
246 return my_get_generating_task_handle(taskHandle
, generating
);
249 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_scheduling_task_handle(
250 ompd_task_handle_t
*taskHandle
, ompd_task_handle_t
**scheduling
) {
251 static ompd_rc_t (*my_get_scheduling_task_handle
)(
252 ompd_task_handle_t
*, ompd_task_handle_t
**) = NULL
;
253 if (!my_get_scheduling_task_handle
) {
254 my_get_scheduling_task_handle
=
255 dlsym(ompd_library
, "ompd_get_scheduling_task_handle");
257 return ompd_rc_error
;
260 return my_get_scheduling_task_handle(taskHandle
, scheduling
);
263 OMPD_WEAK_ATTR ompd_rc_t
264 ompd_get_task_in_parallel(ompd_parallel_handle_t
*parallelHandle
, int threadNum
,
265 ompd_task_handle_t
**taskHandle
) {
266 static ompd_rc_t (*my_get_task_in_parallel
)(ompd_parallel_handle_t
*, int,
267 ompd_task_handle_t
**) = NULL
;
268 if (!my_get_task_in_parallel
) {
269 my_get_task_in_parallel
= dlsym(ompd_library
, "ompd_get_task_in_parallel");
271 return ompd_rc_error
;
274 return my_get_task_in_parallel(parallelHandle
, threadNum
, taskHandle
);
277 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_task_frame(ompd_task_handle_t
*taskHandle
,
278 ompd_frame_info_t
*exitFrame
,
279 ompd_frame_info_t
*enterFrame
) {
280 static ompd_rc_t (*my_get_task_frame
)(
281 ompd_task_handle_t
*, ompd_frame_info_t
*, ompd_frame_info_t
*) = NULL
;
282 if (!my_get_task_frame
) {
283 my_get_task_frame
= dlsym(ompd_library
, "ompd_get_task_frame");
285 return ompd_rc_error
;
288 return my_get_task_frame(taskHandle
, exitFrame
, enterFrame
);
291 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_icv_from_scope(void *handle
,
294 ompd_word_t
*icvValue
) {
295 static ompd_rc_t (*my_get_icv_from_scope
)(void *, ompd_scope_t
, ompd_icv_id_t
,
296 ompd_word_t
*) = NULL
;
297 if (!my_get_icv_from_scope
) {
298 my_get_icv_from_scope
= dlsym(ompd_library
, "ompd_get_icv_from_scope");
300 return ompd_rc_error
;
303 return my_get_icv_from_scope(handle
, scope
, icvId
, icvValue
);
306 OMPD_WEAK_ATTR ompd_rc_t
307 ompd_enumerate_icvs(ompd_address_space_handle_t
*handle
, ompd_icv_id_t current
,
308 ompd_icv_id_t
*next
, const char **nextIcvName
,
309 ompd_scope_t
*nextScope
, int *more
) {
310 static ompd_rc_t (*my_enumerate_icvs
)(
311 ompd_address_space_handle_t
*, ompd_icv_id_t
, ompd_icv_id_t
*,
312 const char **, ompd_scope_t
*, int *) = NULL
;
313 if (!my_enumerate_icvs
) {
314 my_enumerate_icvs
= dlsym(ompd_library
, "ompd_enumerate_icvs");
316 return ompd_rc_error
;
319 return my_enumerate_icvs(handle
, current
, next
, nextIcvName
, nextScope
, more
);
322 OMPD_WEAK_ATTR ompd_rc_t
323 ompd_enumerate_states(ompd_address_space_handle_t
*addrSpaceHandle
,
324 ompd_word_t currentState
, ompd_word_t
*nextState
,
325 const char **nextStateName
, ompd_word_t
*moreEnums
) {
326 static ompd_rc_t (*my_enumerate_states
)(ompd_address_space_handle_t
*,
327 ompd_word_t
, ompd_word_t
*,
328 const char **, ompd_word_t
*) = NULL
;
329 if (!my_enumerate_states
) {
330 my_enumerate_states
= dlsym(ompd_library
, "ompd_enumerate_states");
332 return ompd_rc_error
;
335 return my_enumerate_states(addrSpaceHandle
, currentState
, nextState
,
336 nextStateName
, moreEnums
);
339 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_state(ompd_thread_handle_t
*threadHandle
,
341 ompd_wait_id_t
*waitId
) {
342 static ompd_rc_t (*my_get_state
)(ompd_thread_handle_t
*, ompd_word_t
*,
343 ompd_wait_id_t
*) = NULL
;
345 my_get_state
= dlsym(ompd_library
, "ompd_get_state");
347 return ompd_rc_error
;
350 return my_get_state(threadHandle
, state
, waitId
);
353 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_task_function(ompd_task_handle_t
*taskHandle
,
354 ompd_address_t
*entryPoint
) {
355 static ompd_rc_t (*my_get_task_function
)(ompd_task_handle_t
*,
356 ompd_address_t
*) = NULL
;
357 if (!my_get_task_function
) {
358 my_get_task_function
= dlsym(ompd_library
, "ompd_get_task_function");
360 return ompd_rc_error
;
363 return my_get_task_function(taskHandle
, entryPoint
);
366 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_thread_id(ompd_thread_handle_t
*threadHandle
,
367 ompd_thread_id_t kind
,
368 ompd_size_t tidSize
, void *tid
) {
369 static ompd_rc_t (*my_get_thread_id
)(ompd_thread_handle_t
*, ompd_thread_id_t
,
370 ompd_size_t
, void *) = NULL
;
371 if (!my_get_thread_id
) {
372 my_get_thread_id
= dlsym(ompd_library
, "ompd_get_thread_id");
374 return ompd_rc_error
;
377 return my_get_thread_id(threadHandle
, kind
, tidSize
, tid
);
380 OMPD_WEAK_ATTR ompd_rc_t
ompd_get_tool_data(void *handle
, ompd_scope_t scope
,
382 ompd_address_t
*ptr
) {
383 static ompd_rc_t (*my_get_tool_data
)(void *, ompd_scope_t
, ompd_word_t
*,
384 ompd_address_t
*) = NULL
;
385 if (!my_get_tool_data
) {
386 my_get_tool_data
= dlsym(ompd_library
, "ompd_get_tool_data");
388 return ompd_rc_error
;
391 return my_get_tool_data(handle
, scope
, value
, ptr
);
394 OMPD_WEAK_ATTR ompd_rc_t
395 ompd_get_icv_string_from_scope(void *handle
, ompd_scope_t scope
,
396 ompd_icv_id_t icvId
, const char **icvString
) {
397 static ompd_rc_t (*my_get_icv_string_from_scope
)(
398 void *, ompd_scope_t
, ompd_icv_id_t
, const char **) = NULL
;
399 if (!my_get_icv_string_from_scope
) {
400 my_get_icv_string_from_scope
=
401 dlsym(ompd_library
, "ompd_get_icv_string_from_scope");
403 return ompd_rc_error
;
406 return my_get_icv_string_from_scope(handle
, scope
, icvId
, icvString
);
409 OMPD_WEAK_ATTR ompd_rc_t
410 ompd_rel_thread_handle(ompd_thread_handle_t
*threadHandle
) {
411 static ompd_rc_t (*my_release_thread_handle
)(ompd_thread_handle_t
*) = NULL
;
412 if (!my_release_thread_handle
) {
413 my_release_thread_handle
= dlsym(ompd_library
, "ompd_rel_thread_handle");
415 return ompd_rc_error
;
418 return my_release_thread_handle(threadHandle
);
421 OMPD_WEAK_ATTR ompd_rc_t
422 ompd_rel_parallel_handle(ompd_parallel_handle_t
*parallelHandle
) {
423 static ompd_rc_t (*my_release_parallel_handle
)(ompd_parallel_handle_t
*) =
425 if (!my_release_parallel_handle
) {
426 my_release_parallel_handle
=
427 dlsym(ompd_library
, "ompd_rel_parallel_handle");
429 return ompd_rc_error
;
432 return my_release_parallel_handle(parallelHandle
);
435 OMPD_WEAK_ATTR ompd_rc_t
ompd_rel_task_handle(ompd_task_handle_t
*taskHandle
) {
436 static ompd_rc_t (*my_release_task_handle
)(ompd_task_handle_t
*) = NULL
;
437 if (!my_release_task_handle
) {
438 my_release_task_handle
= dlsym(ompd_library
, "ompd_rel_task_handle");
440 return ompd_rc_error
;
443 return my_release_task_handle(taskHandle
);
446 OMPD_WEAK_ATTR ompd_rc_t
447 ompd_task_handle_compare(ompd_task_handle_t
*task_handle_1
,
448 ompd_task_handle_t
*task_handle_2
, int *cmp_value
) {
449 static ompd_rc_t (*my_task_handle_compare
)(
450 ompd_task_handle_t
*, ompd_task_handle_t
*, int *) = NULL
;
451 if (!my_task_handle_compare
) {
452 my_task_handle_compare
= dlsym(ompd_library
, "ompd_task_handle_compare");
454 return ompd_rc_error
;
457 return my_task_handle_compare(task_handle_1
, task_handle_2
, cmp_value
);
460 OMPD_WEAK_ATTR ompd_rc_t
461 ompd_get_display_control_vars(ompd_address_space_handle_t
*address_space_handle
,
462 const char *const **control_vars
) {
463 static ompd_rc_t (*my_ompd_get_display_control_vars
)(
464 ompd_address_space_handle_t
*, const char *const **) = NULL
;
465 if (!my_ompd_get_display_control_vars
) {
466 my_ompd_get_display_control_vars
=
467 dlsym(ompd_library
, "ompd_get_display_control_vars");
469 return ompd_rc_error
;
472 return my_ompd_get_display_control_vars(address_space_handle
, control_vars
);
476 * Loads the OMPD library (libompd.so). Returns an integer with the version if
477 * the OMPD library could be loaded successfully. Error codes: -1: argument
478 * could not be converted to string -2: error when calling dlopen -3: error when
479 * fetching version of OMPD API else: see ompd return codes
481 static PyObject
*ompd_open(PyObject
*self
, PyObject
*args
) {
482 const char *name
, *dlerr
;
484 if (!PyArg_ParseTuple(args
, "s", &name
)) {
485 return Py_BuildValue("i", -1);
487 ompd_library
= dlopen(name
, RTLD_LAZY
);
488 if ((dlerr
= dlerror())) {
489 return Py_BuildValue("i", -2);
492 return Py_BuildValue("i", -3);
495 ompd_rc_t rc
= ompd_get_api_version(&version
);
496 if (rc
!= ompd_rc_ok
)
497 return Py_BuildValue("l", -10 - rc
);
499 int returnValue
= version
;
500 return Py_BuildValue("i", returnValue
);
504 * Have the debugger print a string.
506 ompd_rc_t
_print(const char *str
, int category
) {
507 PyObject
*pFunc
= PyObject_GetAttrString(pModule
, "_print");
508 if (pFunc
&& PyCallable_Check(pFunc
)) {
509 PyObject
*pArgs
= PyTuple_New(1);
510 PyTuple_SetItem(pArgs
, 0, Py_BuildValue("s", str
));
511 PyObject_CallObject(pFunc
, pArgs
);
518 void _printf(const char *format
, ...) {
520 va_start(args
, format
);
522 vsnprintf(output
, 1024, format
, args
);
528 * Capsule destructors for thread, parallel and task handles.
530 static void call_ompd_rel_thread_handle_temp(PyObject
*capsule
) {
531 ompd_thread_handle_t
*threadHandle
=
532 (ompd_thread_handle_t
*)(PyCapsule_GetPointer(capsule
, "ThreadHandle"));
534 ompd_rc_t retVal
= ompd_rel_thread_handle(threadHandle
);
535 if (retVal
!= ompd_rc_ok
) {
537 "An error occurred when calling ompd_rel_thread_handle! Error code: %d",
542 static void destroyThreadCapsule(PyObject
*capsule
) {
543 call_ompd_rel_thread_handle_temp(capsule
);
545 static void (*my_thread_capsule_destructor
)(PyObject
*) = destroyThreadCapsule
;
547 static void call_ompd_rel_parallel_handle_temp(PyObject
*capsule
) {
548 ompd_parallel_handle_t
*parallelHandle
=
549 (ompd_parallel_handle_t
*)(PyCapsule_GetPointer(capsule
,
552 ompd_rc_t retVal
= ompd_rel_parallel_handle(parallelHandle
);
553 if (retVal
!= ompd_rc_ok
) {
554 _printf("An error occurred when calling ompd_rel_parallel_handle! Error "
560 static void destroyParallelCapsule(PyObject
*capsule
) {
561 call_ompd_rel_parallel_handle_temp(capsule
);
563 static void (*my_parallel_capsule_destructor
)(PyObject
*) =
564 destroyParallelCapsule
;
566 static void call_ompd_rel_task_handle_temp(PyObject
*capsule
) {
567 ompd_task_handle_t
*taskHandle
=
568 (ompd_task_handle_t
*)(PyCapsule_GetPointer(capsule
, "TaskHandle"));
570 ompd_rc_t retVal
= ompd_rel_task_handle(taskHandle
);
571 if (retVal
!= ompd_rc_ok
) {
572 _printf("An error occurred when calling ompd_rel_task_handle!\n");
576 static void destroyTaskCapsule(PyObject
*capsule
) {
577 call_ompd_rel_task_handle_temp(capsule
);
579 static void (*my_task_capsule_destructor
)(PyObject
*) = destroyTaskCapsule
;
582 * Release thread handle. Called inside destructor for Python thread_handle
585 static PyObject
*call_ompd_rel_thread_handle(PyObject
*self
, PyObject
*args
) {
586 PyObject
*threadHandlePy
= PyTuple_GetItem(args
, 0);
587 ompd_thread_handle_t
*threadHandle
=
588 (ompd_thread_handle_t
*)(PyCapsule_GetPointer(threadHandlePy
,
591 ompd_rc_t retVal
= ompd_rel_thread_handle(threadHandle
);
592 if (retVal
!= ompd_rc_ok
) {
594 "An error occurred when calling ompd_rel_thread_handle! Error code: %d",
597 return Py_BuildValue("l", retVal
);
601 * Allocate memory in the debugger's address space.
603 ompd_rc_t
_alloc(ompd_size_t bytes
, void **ptr
) {
605 return ompd_rc_bad_input
;
607 *ptr
= malloc(bytes
);
612 * Free memory in the debugger's address space.
614 ompd_rc_t
_free(void *ptr
) {
620 * Look up the sizes of primitive types in the target.
622 ompd_rc_t
_sizes(ompd_address_space_context_t
*_acontext
, /* IN */
623 ompd_device_type_sizes_t
*sizes
) /* OUT */
625 if (acontext
.id
!= _acontext
->id
)
626 return ompd_rc_stale_handle
;
627 ompd_device_type_sizes_t mysizes
= {
628 (uint8_t)sizeof(char), (uint8_t)sizeof(short),
629 (uint8_t)sizeof(int), (uint8_t)sizeof(long),
630 (uint8_t)sizeof(long long), (uint8_t)sizeof(void *)};
636 * Look up the address of a global symbol in the target.
638 ompd_rc_t
_sym_addr(ompd_address_space_context_t
*context
, /* IN */
639 ompd_thread_context_t
*tcontext
, /* IN */
640 const char *symbol_name
, /* IN */
641 ompd_address_t
*symbol_addr
, /* OUT */
642 const char *file_name
) /* IN */
645 PyObject
*symbolAddress
;
646 if (tcontext
!= NULL
) {
647 thread_id
= tcontext
->id
;
649 PyObject
*pFunc
= PyObject_GetAttrString(pModule
, "_sym_addr");
650 if (pFunc
&& PyCallable_Check(pFunc
)) {
651 PyObject
*pArgs
= PyTuple_New(2);
652 PyTuple_SetItem(pArgs
, 0, Py_BuildValue("i", thread_id
));
653 PyTuple_SetItem(pArgs
, 1, Py_BuildValue("s", symbol_name
));
654 symbolAddress
= PyObject_CallObject(pFunc
, pArgs
);
655 if (symbolAddress
== NULL
) {
658 symbol_addr
->address
= PyLong_AsLong(symbolAddress
);
660 Py_XDECREF(symbolAddress
);
667 * Read memory from the target.
669 ompd_rc_t
_read(ompd_address_space_context_t
*context
, /* IN */
670 ompd_thread_context_t
*tcontext
, /* IN */
671 const ompd_address_t
*addr
, /* IN */
672 ompd_size_t nbytes
, /* IN */
673 void *buffer
) /* OUT */
675 uint64_t readMem
= (uint64_t)addr
->address
;
676 PyObject
*pFunc
= PyObject_GetAttrString(pModule
, "_read");
677 if (pFunc
&& PyCallable_Check(pFunc
)) {
678 PyObject
*pArgs
= PyTuple_New(2);
679 PyTuple_SetItem(pArgs
, 0, Py_BuildValue("l", readMem
));
680 PyTuple_SetItem(pArgs
, 1, Py_BuildValue("l", nbytes
));
681 PyObject
*retArray
= PyObject_CallObject(pFunc
, pArgs
);
683 if (retArray
== NULL
) {
686 if (!PyByteArray_Check(retArray
)) {
687 return ompd_rc_error
;
689 Py_ssize_t retSize
= PyByteArray_Size(retArray
);
690 const char *strBuf
= PyByteArray_AsString(retArray
);
691 if ((ompd_size_t
)retSize
!= nbytes
) {
692 return ompd_rc_error
;
694 memcpy(buffer
, strBuf
, nbytes
);
695 Py_XDECREF(retArray
);
702 * Reads string from target.
704 ompd_rc_t
_read_string(ompd_address_space_context_t
*context
, /* IN */
705 ompd_thread_context_t
*tcontext
, /* IN */
706 const ompd_address_t
*addr
, /* IN */
707 ompd_size_t nbytes
, /* IN */
708 void *buffer
) /* OUT */
710 ompd_rc_t retVal
= ompd_rc_ok
;
711 uint64_t readMem
= (uint64_t)addr
->address
;
712 PyObject
*pFunc
= PyObject_GetAttrString(pModule
, "_read_string");
713 PyObject
*pArgs
= PyTuple_New(1);
714 PyTuple_SetItem(pArgs
, 0, Py_BuildValue("l", readMem
));
715 PyObject
*retString
= PyObject_CallObject(pFunc
, pArgs
);
717 if (!PyUnicode_Check(retString
)) {
718 return ompd_rc_error
;
721 const char *strbuffer
= PyUnicode_AsUTF8AndSize(retString
, &retSize
);
722 if ((ompd_size_t
)retSize
+ 1 >= nbytes
) {
723 retVal
= ompd_rc_incomplete
;
725 strncpy(buffer
, strbuffer
, nbytes
);
726 ((char *)buffer
)[nbytes
- 1] = '\0';
731 * Write memory from the target.
734 _endianess(ompd_address_space_context_t
*address_space_context
, /* IN */
735 const void *input
, /* IN */
736 ompd_size_t unit_size
, /* IN */
737 ompd_size_t count
, /* IN: number of primitive type */
739 if (acontext
.id
!= address_space_context
->id
)
740 return ompd_rc_stale_handle
;
741 memmove(output
, input
, count
* unit_size
);
746 * Returns thread context for thread id; helper function for _thread_context
749 ompd_thread_context_t
*get_thread_context(int id
) {
750 static ompd_thread_context_t
*tc
= NULL
;
757 tc
= malloc(size
* sizeof(ompd_thread_context_t
));
758 for (i
= 0; i
< size
; i
++)
761 if (id
- 1 >= size
) {
763 tc
= realloc(tc
, size
* sizeof(ompd_thread_context_t
));
764 for (i
= 0; i
< size
; i
++)
771 * Get thread specific context.
774 _thread_context(ompd_address_space_context_t
*context
, /* IN */
775 ompd_thread_id_t kind
, /* IN, 0 for pthread, 1 for lwp */
776 ompd_size_t sizeof_thread_id
, /* IN */
777 const void *thread_id
, /* IN */
778 ompd_thread_context_t
**thread_context
) /* OUT */
780 if (acontext
.id
!= context
->id
)
781 return ompd_rc_stale_handle
;
782 if (kind
!= 0 && kind
!= 1)
783 return ompd_rc_unsupported
;
785 if (sizeof(long int) >= 8 && sizeof_thread_id
== 8)
786 tid
= *(const uint64_t *)thread_id
;
787 else if (sizeof(long int) >= 4 && sizeof_thread_id
== 4)
788 tid
= *(const uint32_t *)thread_id
;
789 else if (sizeof(long int) >= 2 && sizeof_thread_id
== 2)
790 tid
= *(const uint16_t *)thread_id
;
792 return ompd_rc_bad_input
;
793 PyObject
*pFunc
= PyObject_GetAttrString(pModule
, "_thread_context");
794 if (pFunc
&& PyCallable_Check(pFunc
)) {
795 PyObject
*pArgs
= PyTuple_New(2);
796 PyTuple_SetItem(pArgs
, 0, Py_BuildValue("l", kind
));
797 PyTuple_SetItem(pArgs
, 1, Py_BuildValue("l", tid
));
798 PyObject
*res
= PyObject_CallObject(pFunc
, pArgs
);
799 int resAsInt
= (int)PyLong_AsLong(res
);
800 if (resAsInt
== -1) {
801 // NOTE: could not find match for thread_id
802 return ompd_rc_unavailable
;
804 (*thread_context
) = get_thread_context(resAsInt
);
808 if (*thread_context
== NULL
) {
809 return ompd_rc_bad_input
;
814 return ompd_rc_error
;
818 * Calls ompd_process_initialize; returns pointer to ompd_address_space_handle.
820 static PyObject
*call_ompd_initialize(PyObject
*self
, PyObject
*noargs
) {
821 pModule
= PyImport_Import(PyUnicode_FromString("ompd_callbacks"));
823 static ompd_callbacks_t table
= {
824 _alloc
, _free
, _print
, _sizes
, _sym_addr
, _read
,
825 NULL
, _read_string
, _endianess
, _endianess
, _thread_context
};
827 ompd_rc_t (*my_ompd_init
)(ompd_word_t version
, ompd_callbacks_t
*) =
828 dlsym(ompd_library
, "ompd_initialize");
829 ompd_rc_t returnInit
= my_ompd_init(201811, &table
);
830 if (returnInit
!= ompd_rc_ok
) {
831 _printf("An error occurred when calling ompd_initialize! Error code: %d",
834 ompd_address_space_handle_t
*addr_space
= NULL
;
835 ompd_rc_t (*my_proc_init
)(ompd_address_space_context_t
*,
836 ompd_address_space_handle_t
**) =
837 dlsym(ompd_library
, "ompd_process_initialize");
838 ompd_rc_t retProcInit
= my_proc_init(&acontext
, &addr_space
);
839 if (retProcInit
!= ompd_rc_ok
) {
840 _printf("An error occurred when calling ompd_process_initialize! Error "
844 return PyCapsule_New(addr_space
, "AddressSpace", NULL
);
848 * Returns a PyCapsule pointer to thread handle for thread with the given id.
850 static PyObject
*get_thread_handle(PyObject
*self
, PyObject
*args
) {
851 PyObject
*threadIdTup
= PyTuple_GetItem(args
, 0);
852 uint64_t threadId
= (uint64_t)PyLong_AsLong(threadIdTup
);
853 // NOTE: compiler does not know what thread handle looks like, so no memory
854 // is allocated automatically in the debugger's memory space
856 PyObject
*addrSpaceTup
= PyTuple_GetItem(args
, 1);
857 ompd_thread_handle_t
*threadHandle
;
858 ompd_address_space_handle_t
*addrSpace
=
859 (ompd_address_space_handle_t
*)PyCapsule_GetPointer(addrSpaceTup
,
862 ompd_size_t sizeof_tid
= (ompd_size_t
)sizeof(uint64_t);
863 ompd_rc_t retVal
= ompd_get_thread_handle(addrSpace
, 1, sizeof_tid
, &threadId
,
866 if (retVal
== ompd_rc_unavailable
) {
867 return Py_BuildValue("i", -1);
868 } else if (retVal
!= ompd_rc_ok
) {
870 "An error occured when calling ompd_get_thread_handle! Error code: %d",
872 return Py_BuildValue("l", retVal
);
874 return PyCapsule_New(threadHandle
, "ThreadHandle",
875 my_thread_capsule_destructor
);
879 * Returns a PyCapsule pointer to a thread handle for a specific thread id in
880 * the current parallel context.
882 static PyObject
*call_ompd_get_thread_in_parallel(PyObject
*self
,
884 PyObject
*parallelHandlePy
= PyTuple_GetItem(args
, 0);
885 int threadNum
= (int)PyLong_AsLong(PyTuple_GetItem(args
, 1));
886 ompd_parallel_handle_t
*parallelHandle
=
887 (ompd_parallel_handle_t
*)(PyCapsule_GetPointer(parallelHandlePy
,
889 ompd_thread_handle_t
*threadHandle
;
892 ompd_get_thread_in_parallel(parallelHandle
, threadNum
, &threadHandle
);
894 if (retVal
!= ompd_rc_ok
) {
895 _printf("An error occurred when calling ompd_get_thread_in_parallel! Error "
898 return Py_BuildValue("l", retVal
);
900 return PyCapsule_New(threadHandle
, "ThreadHandle",
901 my_thread_capsule_destructor
);
905 * Returns a PyCapsule pointer to the parallel handle of the current parallel
906 * region associated with a thread.
908 static PyObject
*call_ompd_get_curr_parallel_handle(PyObject
*self
,
910 PyObject
*threadHandlePy
= PyTuple_GetItem(args
, 0);
911 ompd_thread_handle_t
*threadHandle
=
912 (ompd_thread_handle_t
*)(PyCapsule_GetPointer(threadHandlePy
,
914 ompd_parallel_handle_t
*parallelHandle
;
917 ompd_get_curr_parallel_handle(threadHandle
, ¶llelHandle
);
919 if (retVal
!= ompd_rc_ok
) {
920 _printf("An error occurred when calling ompd_get_curr_parallel_handle! "
923 return Py_BuildValue("l", retVal
);
925 return PyCapsule_New(parallelHandle
, "ParallelHandle",
926 my_parallel_capsule_destructor
);
930 * Returns a PyCapsule pointer to the parallel handle for the parallel region
931 * enclosing the parallel region specified by parallel_handle.
933 static PyObject
*call_ompd_get_enclosing_parallel_handle(PyObject
*self
,
935 PyObject
*parallelHandlePy
= PyTuple_GetItem(args
, 0);
936 ompd_parallel_handle_t
*parallelHandle
=
937 (ompd_parallel_handle_t
*)(PyCapsule_GetPointer(parallelHandlePy
,
939 ompd_parallel_handle_t
*enclosingParallelHandle
;
941 ompd_rc_t retVal
= ompd_get_enclosing_parallel_handle(
942 parallelHandle
, &enclosingParallelHandle
);
944 if (retVal
!= ompd_rc_ok
) {
945 _printf("An error occurred when calling "
946 "ompd_get_enclosing_parallel_handle! Error code: %d",
948 return Py_BuildValue("l", retVal
);
950 return PyCapsule_New(enclosingParallelHandle
, "ParallelHandle",
951 my_parallel_capsule_destructor
);
955 * Returns a PyCapsule pointer to the parallel handle for the parallel region
956 * enclosing the task specified.
958 static PyObject
*call_ompd_get_task_parallel_handle(PyObject
*self
,
960 PyObject
*taskHandlePy
= PyTuple_GetItem(args
, 0);
961 ompd_task_handle_t
*taskHandle
=
962 PyCapsule_GetPointer(taskHandlePy
, "TaskHandle");
963 ompd_parallel_handle_t
*taskParallelHandle
;
966 ompd_get_task_parallel_handle(taskHandle
, &taskParallelHandle
);
968 if (retVal
!= ompd_rc_ok
) {
969 _printf("An error occurred when calling ompd_get_task_parallel_handle! "
971 return Py_BuildValue("l", retVal
);
973 return PyCapsule_New(taskParallelHandle
, "ParallelHandle",
974 my_parallel_capsule_destructor
);
978 * Releases a parallel handle; is called in by the destructor of a Python
979 * parallel_handle object.
981 static PyObject
*call_ompd_rel_parallel_handle(PyObject
*self
, PyObject
*args
) {
982 PyObject
*parallelHandlePy
= PyTuple_GetItem(args
, 0);
983 ompd_parallel_handle_t
*parallelHandle
=
984 (ompd_parallel_handle_t
*)(PyCapsule_GetPointer(parallelHandlePy
,
987 ompd_rc_t retVal
= ompd_rel_parallel_handle(parallelHandle
);
988 if (retVal
!= ompd_rc_ok
) {
989 _printf("An error occurred when calling ompd_rel_parallel_handle! Error "
993 return Py_BuildValue("l", retVal
);
997 * Returns a PyCapsule pointer to the task handle of the current task region
998 * associated with a thread.
1000 static PyObject
*call_ompd_get_curr_task_handle(PyObject
*self
,
1002 PyObject
*threadHandlePy
= PyTuple_GetItem(args
, 0);
1003 ompd_thread_handle_t
*threadHandle
=
1004 (ompd_thread_handle_t
*)(PyCapsule_GetPointer(threadHandlePy
,
1006 ompd_task_handle_t
*taskHandle
;
1008 ompd_rc_t retVal
= ompd_get_curr_task_handle(threadHandle
, &taskHandle
);
1010 if (retVal
!= ompd_rc_ok
) {
1011 _printf("An error occurred when calling ompd_get_curr_task_handle! Error "
1014 return Py_BuildValue("l", retVal
);
1016 return PyCapsule_New(taskHandle
, "TaskHandle", my_task_capsule_destructor
);
1020 * Returns a task handle for the task that created the task specified.
1022 static PyObject
*call_ompd_get_generating_task_handle(PyObject
*self
,
1024 PyObject
*taskHandlePy
= PyTuple_GetItem(args
, 0);
1025 ompd_task_handle_t
*taskHandle
=
1026 (ompd_task_handle_t
*)(PyCapsule_GetPointer(taskHandlePy
, "TaskHandle"));
1027 ompd_task_handle_t
*generatingTaskHandle
;
1030 ompd_get_generating_task_handle(taskHandle
, &generatingTaskHandle
);
1032 if (retVal
!= ompd_rc_ok
) {
1033 _printf("An error occurred when calling ompd_get_generating_task_handle! "
1036 return Py_BuildValue("l", retVal
);
1038 return PyCapsule_New(generatingTaskHandle
, "TaskHandle",
1039 my_task_capsule_destructor
);
1043 * Returns the task handle for the task that scheduled the task specified.
1045 static PyObject
*call_ompd_get_scheduling_task_handle(PyObject
*self
,
1047 PyObject
*taskHandlePy
= PyTuple_GetItem(args
, 0);
1048 ompd_task_handle_t
*taskHandle
=
1049 (ompd_task_handle_t
*)(PyCapsule_GetPointer(taskHandlePy
, "TaskHandle"));
1050 ompd_task_handle_t
*schedulingTaskHandle
;
1053 ompd_get_scheduling_task_handle(taskHandle
, &schedulingTaskHandle
);
1055 if (retVal
== ompd_rc_unavailable
) {
1057 } else if (retVal
!= ompd_rc_ok
) {
1058 _printf("An error occurred when calling ompd_get_scheduling_task_handle! "
1061 return Py_BuildValue("l", retVal
);
1063 return PyCapsule_New(schedulingTaskHandle
, "TaskHandle",
1064 my_task_capsule_destructor
);
1068 * Returns task handles for the implicit tasks associated with a parallel
1071 static PyObject
*call_ompd_get_task_in_parallel(PyObject
*self
,
1073 PyObject
*parallelHandlePy
= PyTuple_GetItem(args
, 0);
1074 int threadNum
= (int)PyLong_AsLong(PyTuple_GetItem(args
, 1));
1075 ompd_parallel_handle_t
*parallelHandle
=
1076 (ompd_parallel_handle_t
*)(PyCapsule_GetPointer(parallelHandlePy
,
1078 ompd_task_handle_t
*taskHandle
;
1081 ompd_get_task_in_parallel(parallelHandle
, threadNum
, &taskHandle
);
1083 if (retVal
!= ompd_rc_ok
) {
1084 _printf("An error occurred when calling ompd_get_task_in_parallel! Error "
1087 return Py_BuildValue("l", retVal
);
1089 return PyCapsule_New(taskHandle
, "TaskHandle", my_task_capsule_destructor
);
1093 * Releases a task handle; is called by the destructor of a Python task_handle
1096 static PyObject
*call_ompd_rel_task_handle(PyObject
*self
, PyObject
*args
) {
1097 PyObject
*taskHandlePy
= PyTuple_GetItem(args
, 0);
1098 ompd_task_handle_t
*taskHandle
=
1099 (ompd_task_handle_t
*)(PyCapsule_GetPointer(taskHandlePy
, "TaskHandle"));
1101 ompd_rc_t retVal
= ompd_rel_task_handle(taskHandle
);
1102 if (retVal
!= ompd_rc_ok
) {
1104 "An error occurred when calling ompd_rel_task_handle! Error code: %d",
1107 return Py_BuildValue("l", retVal
);
1111 * Calls ompd_get_task_frame and returns a PyCapsule for the enter frame of the
1114 static PyObject
*call_ompd_get_task_frame(PyObject
*self
, PyObject
*args
) {
1115 PyObject
*taskHandlePy
= PyTuple_GetItem(args
, 0);
1116 ompd_task_handle_t
*taskHandle
=
1117 (ompd_task_handle_t
*)PyCapsule_GetPointer(taskHandlePy
, "TaskHandle");
1118 ompd_frame_info_t exitFrameInfo
;
1119 ompd_frame_info_t enterFrameInfo
;
1122 ompd_get_task_frame(taskHandle
, &exitFrameInfo
, &enterFrameInfo
);
1124 if (retVal
!= ompd_rc_ok
) {
1126 "An error occurred when calling ompd_get_task_frame! Error code: %d",
1128 return Py_BuildValue("l", retVal
);
1131 PyObject
*result
= PyTuple_New(4);
1133 result
, 0, PyLong_FromUnsignedLong(enterFrameInfo
.frame_address
.address
));
1134 PyTuple_SetItem(result
, 1,
1135 PyLong_FromUnsignedLong(enterFrameInfo
.frame_flag
));
1136 PyTuple_SetItem(result
, 2,
1137 PyLong_FromUnsignedLong(exitFrameInfo
.frame_address
.address
));
1138 PyTuple_SetItem(result
, 3, PyLong_FromUnsignedLong(exitFrameInfo
.frame_flag
));
1143 * Calls ompd_get_icv_from_scope.
1145 static PyObject
*call_ompd_get_icv_from_scope(PyObject
*self
, PyObject
*args
) {
1146 PyObject
*addrSpaceHandlePy
= PyTuple_GetItem(args
, 0);
1147 PyObject
*scopePy
= PyTuple_GetItem(args
, 1);
1148 PyObject
*icvIdPy
= PyTuple_GetItem(args
, 2);
1150 ompd_scope_t scope
= (ompd_scope_t
)PyLong_AsLong(scopePy
);
1151 ompd_address_space_handle_t
*addrSpaceHandle
;
1153 case ompd_scope_thread
:
1154 addrSpaceHandle
= (ompd_address_space_handle_t
*)PyCapsule_GetPointer(
1155 addrSpaceHandlePy
, "ThreadHandle");
1157 case ompd_scope_parallel
:
1158 addrSpaceHandle
= (ompd_address_space_handle_t
*)PyCapsule_GetPointer(
1159 addrSpaceHandlePy
, "ParallelHandle");
1161 case ompd_scope_implicit_task
:
1162 addrSpaceHandle
= (ompd_address_space_handle_t
*)PyCapsule_GetPointer(
1163 addrSpaceHandlePy
, "TaskHandle");
1165 case ompd_scope_task
:
1166 addrSpaceHandle
= (ompd_address_space_handle_t
*)PyCapsule_GetPointer(
1167 addrSpaceHandlePy
, "TaskHandle");
1170 addrSpaceHandle
= (ompd_address_space_handle_t
*)PyCapsule_GetPointer(
1171 addrSpaceHandlePy
, "AddressSpace");
1175 ompd_icv_id_t icvId
= (ompd_icv_id_t
)PyLong_AsLong(icvIdPy
);
1176 ompd_word_t icvValue
;
1179 ompd_get_icv_from_scope(addrSpaceHandle
, scope
, icvId
, &icvValue
);
1181 if (retVal
!= ompd_rc_ok
) {
1182 if (retVal
!= ompd_rc_incomplete
) {
1183 _printf("An error occurred when calling ompd_get_icv_from_scope(%i, %i): "
1185 scope
, icvId
, retVal
);
1189 return PyLong_FromLong(icvValue
);
1193 * Calls ompd_enumerate_icvs.
1195 static PyObject
*call_ompd_enumerate_icvs(PyObject
*self
, PyObject
*args
) {
1196 PyObject
*addrSpaceHandlePy
= PyTuple_GetItem(args
, 0);
1197 PyObject
*currentPy
= PyTuple_GetItem(args
, 1);
1198 ompd_icv_id_t current
= (ompd_icv_id_t
)(PyLong_AsLong(currentPy
));
1199 ompd_address_space_handle_t
*addrSpaceHandle
=
1200 (ompd_address_space_handle_t
*)PyCapsule_GetPointer(addrSpaceHandlePy
,
1203 const char *nextIcv
;
1204 ompd_scope_t nextScope
;
1206 ompd_icv_id_t nextId
;
1208 ompd_rc_t retVal
= ompd_enumerate_icvs(addrSpaceHandle
, current
, &nextId
,
1209 &nextIcv
, &nextScope
, &more
);
1211 if (retVal
!= ompd_rc_ok
) {
1213 "An error occurred when calling ompd_enumerate_icvs! Error code: %d",
1217 PyObject
*retTuple
= PyTuple_New(4);
1218 PyTuple_SetItem(retTuple
, 0, PyLong_FromUnsignedLong(nextId
));
1219 PyTuple_SetItem(retTuple
, 1, PyUnicode_FromString(nextIcv
));
1220 PyTuple_SetItem(retTuple
, 2, PyLong_FromUnsignedLong(nextScope
));
1221 PyTuple_SetItem(retTuple
, 3, PyLong_FromLong(more
));
1226 * Calls ompd_enumerate_states.
1228 static PyObject
*call_ompd_enumerate_states(PyObject
*self
, PyObject
*args
) {
1229 PyObject
*addrSpaceHandlePy
= PyTuple_GetItem(args
, 0);
1230 ompd_address_space_handle_t
*addrSpaceHandle
=
1231 (ompd_address_space_handle_t
*)PyCapsule_GetPointer(addrSpaceHandlePy
,
1233 ompd_word_t currentState
=
1234 (ompd_word_t
)PyLong_AsLong(PyTuple_GetItem(args
, 1));
1236 ompd_word_t nextState
;
1237 const char *nextStateName
;
1238 ompd_word_t moreEnums
;
1240 ompd_rc_t retVal
= ompd_enumerate_states(
1241 addrSpaceHandle
, currentState
, &nextState
, &nextStateName
, &moreEnums
);
1243 if (retVal
!= ompd_rc_ok
) {
1245 "An error occurred when calling ompd_enumerate_states! Error code: %d",
1249 PyObject
*retTuple
= PyTuple_New(3);
1250 PyTuple_SetItem(retTuple
, 0, PyLong_FromLong(nextState
));
1251 PyTuple_SetItem(retTuple
, 1, PyUnicode_FromString(nextStateName
));
1252 PyTuple_SetItem(retTuple
, 2, PyLong_FromLong(moreEnums
));
1257 * Calls ompd_get_state.
1259 static PyObject
*call_ompd_get_state(PyObject
*self
, PyObject
*args
) {
1260 PyObject
*threadHandlePy
= PyTuple_GetItem(args
, 0);
1261 ompd_thread_handle_t
*threadHandle
=
1262 (ompd_thread_handle_t
*)PyCapsule_GetPointer(threadHandlePy
,
1265 ompd_wait_id_t waitId
;
1267 ompd_rc_t retVal
= ompd_get_state(threadHandle
, &state
, &waitId
);
1269 if (retVal
!= ompd_rc_ok
) {
1270 _printf("An error occurred when calling ompd_get_state! Error code: %d",
1274 PyObject
*retTuple
= PyTuple_New(2);
1275 PyTuple_SetItem(retTuple
, 0, PyLong_FromLong(state
));
1276 PyTuple_SetItem(retTuple
, 1, PyLong_FromUnsignedLong(waitId
));
1281 * Calls ompd_get_task_function and returns entry point of the code that
1282 * corresponds to the code executed by the task.
1284 static PyObject
*call_ompd_get_task_function(PyObject
*self
, PyObject
*args
) {
1285 PyObject
*taskHandlePy
= PyTuple_GetItem(args
, 0);
1286 ompd_task_handle_t
*taskHandle
=
1287 (ompd_task_handle_t
*)PyCapsule_GetPointer(taskHandlePy
, "TaskHandle");
1288 ompd_address_t entryPoint
;
1290 ompd_rc_t retVal
= ompd_get_task_function(taskHandle
, &entryPoint
);
1292 if (retVal
!= ompd_rc_ok
) {
1294 "An error occurred when calling ompd_get_task_function! Error code: %d",
1298 return PyLong_FromLong((long)entryPoint
.address
);
1302 * Prints pointer stored inside PyCapusle.
1304 static PyObject
*print_capsule(PyObject
*self
, PyObject
*args
) {
1305 PyObject
*capsule
= PyTuple_GetItem(args
, 0);
1306 PyObject
*name
= PyTuple_GetItem(args
, 1);
1308 PyCapsule_GetPointer(capsule
, PyUnicode_AsUTF8AndSize(name
, NULL
));
1309 _printf("Capsule pointer: %p", pointer
);
1314 * Calls ompd_get_thread_id for given handle and returns the thread id as a
1317 static PyObject
*call_ompd_get_thread_id(PyObject
*self
, PyObject
*args
) {
1318 PyObject
*threadHandlePy
= PyTuple_GetItem(args
, 0);
1319 ompd_thread_handle_t
*threadHandle
=
1320 (ompd_thread_handle_t
*)(PyCapsule_GetPointer(threadHandlePy
,
1322 ompd_thread_id_t kind
= 0; // OMPD_THREAD_ID_PTHREAD
1323 ompd_size_t sizeOfId
= (ompd_size_t
)sizeof(pthread_t
);
1326 ompd_rc_t retVal
= ompd_get_thread_id(threadHandle
, kind
, sizeOfId
, &thread
);
1328 if (retVal
!= ompd_rc_ok
) {
1329 kind
= 1; // OMPD_THREAD_ID_LWP
1330 retVal
= ompd_get_thread_id(threadHandle
, kind
, sizeOfId
, &thread
);
1331 if (retVal
!= ompd_rc_ok
) {
1333 "An error occurred when calling ompd_get_thread_id! Error code: %d",
1338 return PyLong_FromLong(thread
);
1342 * Calls ompd_get_tool_data and returns a tuple containing the value and pointer
1343 * of the ompt_data_t union for the selected scope.
1345 static PyObject
*call_ompd_get_tool_data(PyObject
*self
, PyObject
*args
) {
1346 PyObject
*scopePy
= PyTuple_GetItem(args
, 0);
1347 ompd_scope_t scope
= (ompd_scope_t
)(PyLong_AsLong(scopePy
));
1348 PyObject
*handlePy
= PyTuple_GetItem(args
, 1);
1349 void *handle
= NULL
;
1352 ompd_thread_handle_t
*threadHandle
=
1353 (ompd_thread_handle_t
*)(PyCapsule_GetPointer(handlePy
,
1355 handle
= threadHandle
;
1356 } else if (scope
== 4) {
1357 ompd_parallel_handle_t
*parallelHandle
=
1358 (ompd_parallel_handle_t
*)(PyCapsule_GetPointer(handlePy
,
1360 handle
= parallelHandle
;
1361 } else if (scope
== 5 || scope
== 6) {
1362 ompd_task_handle_t
*taskHandle
=
1363 (ompd_task_handle_t
*)(PyCapsule_GetPointer(handlePy
, "TaskHandle"));
1364 handle
= taskHandle
;
1366 _printf("An error occured when calling ompd_get_tool_data! Scope type not "
1374 ompd_rc_t retVal
= ompd_get_tool_data(handle
, scope
, &value
, &ptr
);
1376 if (retVal
!= ompd_rc_ok
) {
1377 _printf("An error occured when calling ompd_get_tool_data! Error code: %d",
1382 PyObject
*retTuple
= PyTuple_New(2);
1383 PyTuple_SetItem(retTuple
, 0, PyLong_FromLong(value
));
1384 PyTuple_SetItem(retTuple
, 1, PyLong_FromLong(ptr
.address
));
1388 /** Calls ompd_get_icv_string_from_scope.
1390 static PyObject
*call_ompd_get_icv_string_from_scope(PyObject
*self
,
1392 PyObject
*handlePy
= PyTuple_GetItem(args
, 0);
1393 PyObject
*scopePy
= PyTuple_GetItem(args
, 1);
1394 PyObject
*icvIdPy
= PyTuple_GetItem(args
, 2);
1396 ompd_scope_t scope
= (ompd_scope_t
)PyLong_AsLong(scopePy
);
1397 void *handle
= NULL
;
1399 case ompd_scope_thread
:
1401 (ompd_thread_handle_t
*)PyCapsule_GetPointer(handlePy
, "ThreadHandle");
1403 case ompd_scope_parallel
:
1404 handle
= (ompd_parallel_handle_t
*)PyCapsule_GetPointer(handlePy
,
1407 case ompd_scope_implicit_task
:
1408 handle
= (ompd_task_handle_t
*)PyCapsule_GetPointer(handlePy
, "TaskHandle");
1410 case ompd_scope_task
:
1411 handle
= (ompd_task_handle_t
*)PyCapsule_GetPointer(handlePy
, "TaskHandle");
1414 handle
= (ompd_address_space_handle_t
*)PyCapsule_GetPointer(
1415 handlePy
, "AddressSpace");
1419 ompd_icv_id_t icvId
= (ompd_icv_id_t
)PyLong_AsLong(icvIdPy
);
1420 const char *icvString
;
1423 ompd_get_icv_string_from_scope(handle
, scope
, icvId
, &icvString
);
1425 if (retVal
!= ompd_rc_ok
) {
1426 _printf("An error occurred when calling ompd_get_icv_string_from_scope! "
1431 return PyUnicode_FromString(icvString
);
1434 // Prototypes of API test functions.
1435 PyObject
*test_ompd_get_thread_handle(PyObject
*self
, PyObject
*args
);
1436 PyObject
*test_ompd_get_curr_parallel_handle(PyObject
*self
, PyObject
*args
);
1437 PyObject
*test_ompd_get_thread_in_parallel(PyObject
*self
, PyObject
*args
);
1438 PyObject
*test_ompd_thread_handle_compare(PyObject
*self
, PyObject
*args
);
1439 PyObject
*test_ompd_get_thread_id(PyObject
*self
, PyObject
*args
);
1440 PyObject
*test_ompd_rel_thread_handle(PyObject
*self
, PyObject
*args
);
1441 PyObject
*test_ompd_get_enclosing_parallel_handle(PyObject
*self
,
1443 PyObject
*test_ompd_parallel_handle_compare(PyObject
*self
, PyObject
*args
);
1444 PyObject
*test_ompd_rel_parallel_handle(PyObject
*self
, PyObject
*args
);
1445 PyObject
*test_ompd_initialize(PyObject
*self
, PyObject
*noargs
);
1446 PyObject
*test_ompd_get_api_version(PyObject
*self
, PyObject
*noargs
);
1447 PyObject
*test_ompd_get_version_string(PyObject
*self
, PyObject
*noargs
);
1448 PyObject
*test_ompd_finalize(PyObject
*self
, PyObject
*noargs
);
1449 PyObject
*test_ompd_process_initialize(PyObject
*self
, PyObject
*noargs
);
1450 PyObject
*test_ompd_device_initialize(PyObject
*self
, PyObject
*noargs
);
1451 PyObject
*test_ompd_rel_address_space_handle(PyObject
*self
, PyObject
*noargs
);
1452 PyObject
*test_ompd_get_omp_version(PyObject
*self
, PyObject
*args
);
1453 PyObject
*test_ompd_get_omp_version_string(PyObject
*self
, PyObject
*args
);
1454 PyObject
*test_ompd_get_curr_task_handle(PyObject
*self
, PyObject
*args
);
1455 PyObject
*test_ompd_get_task_parallel_handle(PyObject
*self
, PyObject
*args
);
1456 PyObject
*test_ompd_get_generating_task_handle(PyObject
*self
, PyObject
*args
);
1457 PyObject
*test_ompd_get_scheduling_task_handle(PyObject
*self
, PyObject
*args
);
1458 PyObject
*test_ompd_get_task_in_parallel(PyObject
*self
, PyObject
*args
);
1459 PyObject
*test_ompd_rel_task_handle(PyObject
*self
, PyObject
*noargs
);
1460 PyObject
*test_ompd_task_handle_compare(PyObject
*self
, PyObject
*args
);
1461 PyObject
*test_ompd_get_task_function(PyObject
*self
, PyObject
*args
);
1462 PyObject
*test_ompd_get_task_frame(PyObject
*self
, PyObject
*args
);
1463 PyObject
*test_ompd_get_state(PyObject
*self
, PyObject
*args
);
1464 PyObject
*test_ompd_get_display_control_vars(PyObject
*self
, PyObject
*args
);
1465 PyObject
*test_ompd_rel_display_control_vars(PyObject
*self
, PyObject
*noargs
);
1466 PyObject
*test_ompd_enumerate_icvs(PyObject
*self
, PyObject
*noargs
);
1467 PyObject
*test_ompd_get_icv_from_scope_with_addr_handle(PyObject
*self
,
1469 PyObject
*test_ompd_get_icv_from_scope_with_thread_handle(PyObject
*self
,
1471 PyObject
*test_ompd_get_icv_from_scope_with_parallel_handle(PyObject
*self
,
1473 PyObject
*test_ompd_get_icv_from_scope_with_task_handle(PyObject
*self
,
1475 PyObject
*test_ompd_get_icv_string_from_scope(PyObject
*self
, PyObject
*noargs
);
1476 PyObject
*test_ompd_get_tool_data(PyObject
*self
, PyObject
*noargs
);
1477 PyObject
*test_ompd_enumerate_states(PyObject
*self
, PyObject
*noargs
);
1479 * Binds Python function names to C functions.
1481 static PyMethodDef ompdModule_methods
[] = {
1482 {"ompd_open", ompd_open
, METH_VARARGS
,
1483 "Execute dlopen, return OMPD version."},
1484 {"call_ompd_initialize", call_ompd_initialize
, METH_NOARGS
,
1485 "Initializes OMPD environment and callbacks."},
1486 {"call_ompd_rel_thread_handle", call_ompd_rel_thread_handle
, METH_VARARGS
,
1487 "Releases a thread handle."},
1488 {"get_thread_handle", get_thread_handle
, METH_VARARGS
,
1489 "Collects information on threads."},
1490 {"call_ompd_get_thread_in_parallel", call_ompd_get_thread_in_parallel
,
1492 "Obtains handle for a certain thread within parallel region."},
1493 {"call_ompd_get_curr_parallel_handle", call_ompd_get_curr_parallel_handle
,
1495 "Obtains a pointer to the parallel handle for the current parallel "
1497 {"call_ompd_get_enclosing_parallel_handle",
1498 call_ompd_get_enclosing_parallel_handle
, METH_VARARGS
,
1499 "Obtains a pointer to the parallel handle for the parallel region "
1500 "enclosing the parallel region specified."},
1501 {"call_ompd_get_task_parallel_handle", call_ompd_get_task_parallel_handle
,
1503 "Obtains a pointer to the parallel handle for the parallel region "
1504 "enclosing the task region specified."},
1505 {"call_ompd_rel_parallel_handle", call_ompd_rel_parallel_handle
,
1506 METH_VARARGS
, "Releases a parallel region handle."},
1507 {"call_ompd_get_curr_task_handle", call_ompd_get_curr_task_handle
,
1509 "Obtains a pointer to the task handle for the current task region "
1510 "associated with an OpenMP thread."},
1511 {"call_ompd_get_generating_task_handle",
1512 call_ompd_get_generating_task_handle
, METH_VARARGS
,
1513 "Obtains a pointer to the task handle for the task that was created when "
1514 "the task handle specified was encountered."},
1515 {"call_ompd_get_scheduling_task_handle",
1516 call_ompd_get_scheduling_task_handle
, METH_VARARGS
,
1517 "Obtains a pointer to the task handle for the task that scheduled the "
1519 {"call_ompd_get_task_in_parallel", call_ompd_get_task_in_parallel
,
1521 "Obtains the handle for implicit tasks associated with a parallel "
1523 {"call_ompd_rel_task_handle", call_ompd_rel_task_handle
, METH_VARARGS
,
1524 "Releases a task handle."},
1525 {"call_ompd_get_task_frame", call_ompd_get_task_frame
, METH_VARARGS
,
1526 "Returns a pointer to the enter and exit frame address and flag of the "
1528 {"call_ompd_enumerate_icvs", call_ompd_enumerate_icvs
, METH_VARARGS
,
1529 "Saves ICVs in map."},
1530 {"call_ompd_get_icv_from_scope", call_ompd_get_icv_from_scope
, METH_VARARGS
,
1531 "Gets ICVs from scope."},
1532 {"call_ompd_enumerate_states", call_ompd_enumerate_states
, METH_VARARGS
,
1533 "Enumerates OMP states."},
1534 {"call_ompd_get_state", call_ompd_get_state
, METH_VARARGS
,
1535 "Returns state for given thread handle."},
1536 {"call_ompd_get_task_function", call_ompd_get_task_function
, METH_VARARGS
,
1537 "Returns point of code where task starts executing."},
1538 {"print_capsule", print_capsule
, METH_VARARGS
, "Print capsule content"},
1539 {"call_ompd_get_thread_id", call_ompd_get_thread_id
, METH_VARARGS
,
1540 "Maps an OMPD thread handle to a native thread."},
1541 {"call_ompd_get_tool_data", call_ompd_get_tool_data
, METH_VARARGS
,
1542 "Returns value and pointer of ompd_data_t for given scope and handle."},
1543 {"call_ompd_get_icv_string_from_scope", call_ompd_get_icv_string_from_scope
,
1544 METH_VARARGS
, "Gets ICV string representation from scope."},
1546 {"test_ompd_get_thread_handle", test_ompd_get_thread_handle
, METH_VARARGS
,
1547 "Test API ompd_get_thread_handle."},
1548 {"test_ompd_get_curr_parallel_handle", test_ompd_get_curr_parallel_handle
,
1549 METH_VARARGS
, "Test API test_ompd_get_curr_parallel_handle."},
1550 {"test_ompd_get_thread_in_parallel", test_ompd_get_thread_in_parallel
,
1551 METH_VARARGS
, "Test API ompd_get_thread_in_parallel."},
1552 {"test_ompd_thread_handle_compare", test_ompd_thread_handle_compare
,
1553 METH_VARARGS
, "Test API ompd_thread_handle_compare."},
1554 {"test_ompd_get_thread_id", test_ompd_get_thread_id
, METH_VARARGS
,
1555 "Test API ompd_get_thread_id."},
1556 {"test_ompd_rel_thread_handle", test_ompd_rel_thread_handle
, METH_VARARGS
,
1557 "Test API ompd_rel_thread_handle."},
1558 {"test_ompd_get_enclosing_parallel_handle",
1559 test_ompd_get_enclosing_parallel_handle
, METH_VARARGS
,
1560 "Test API ompd_get_enclosing_parallel_handle."},
1561 {"test_ompd_parallel_handle_compare", test_ompd_parallel_handle_compare
,
1562 METH_VARARGS
, "Test API test_ompd_parallel_handle_compare."},
1563 {"test_ompd_rel_parallel_handle", test_ompd_rel_parallel_handle
,
1564 METH_VARARGS
, "Test API ompd_rel_parallel_handle."},
1566 {"test_ompd_initialize", test_ompd_initialize
, METH_VARARGS
,
1567 "Test API ompd_initialize."},
1568 {"test_ompd_get_api_version", test_ompd_get_api_version
, METH_VARARGS
,
1569 "Test API ompd_get_api_version."},
1570 {"test_ompd_get_version_string", test_ompd_get_version_string
, METH_VARARGS
,
1571 "Test API ompd_get_version_string."},
1572 {"test_ompd_finalize", test_ompd_finalize
, METH_VARARGS
,
1573 "Test API ompd_finalize."},
1574 {"test_ompd_process_initialize", test_ompd_process_initialize
, METH_VARARGS
,
1575 "Test API ompd_process_initialize. "},
1576 {"test_ompd_device_initialize", test_ompd_device_initialize
, METH_VARARGS
,
1577 "Test API ompd_device_initialize."},
1578 {"test_ompd_rel_address_space_handle", test_ompd_rel_address_space_handle
,
1579 METH_VARARGS
, "Test API ompd_rel_address_space_handle."},
1580 {"test_ompd_get_omp_version", test_ompd_get_omp_version
, METH_VARARGS
,
1581 "Test API ompd_get_omp_version."},
1582 {"test_ompd_get_omp_version_string", test_ompd_get_omp_version_string
,
1583 METH_VARARGS
, "Test API ompd_get_omp_version_string."},
1585 {"test_ompd_get_curr_task_handle", test_ompd_get_curr_task_handle
,
1586 METH_VARARGS
, "Test API ompd_get_curr_task_handle."},
1587 {"test_ompd_get_task_parallel_handle", test_ompd_get_task_parallel_handle
,
1588 METH_VARARGS
, "Test API ompd_get_task_parallel_handle."},
1589 {"test_ompd_get_generating_task_handle",
1590 test_ompd_get_generating_task_handle
, METH_VARARGS
,
1591 "Test API ompd_get_generating_task_handle."},
1592 {"test_ompd_get_scheduling_task_handle",
1593 test_ompd_get_scheduling_task_handle
, METH_VARARGS
,
1594 "Test API ompd_get_scheduling_task_handle."},
1595 {"test_ompd_get_task_in_parallel", test_ompd_get_task_in_parallel
,
1596 METH_VARARGS
, "Test API ompd_get_task_in_parallel."},
1597 {"test_ompd_rel_task_handle", test_ompd_rel_task_handle
, METH_VARARGS
,
1598 "Test API ompd_rel_task_handle."},
1599 {"test_ompd_task_handle_compare", test_ompd_task_handle_compare
,
1600 METH_VARARGS
, "Test API ompd_task_handle_compare."},
1601 {"test_ompd_get_task_function", test_ompd_get_task_function
, METH_VARARGS
,
1602 "Test API ompd_get_task_function."},
1603 {"test_ompd_get_task_frame", test_ompd_get_task_frame
, METH_VARARGS
,
1604 "Test API ompd_get_task_frame."},
1605 {"test_ompd_get_state", test_ompd_get_state
, METH_VARARGS
,
1606 "Test API ompd_get_state."},
1607 {"test_ompd_get_display_control_vars", test_ompd_get_display_control_vars
,
1608 METH_VARARGS
, "Test API ompd_get_display_control_vars."},
1609 {"test_ompd_rel_display_control_vars", test_ompd_rel_display_control_vars
,
1610 METH_VARARGS
, "Test API ompd_rel_display_control_vars."},
1611 {"test_ompd_enumerate_icvs", test_ompd_enumerate_icvs
, METH_VARARGS
,
1612 "Test API ompd_enumerate_icvs."},
1613 {"test_ompd_get_icv_from_scope_with_addr_handle",
1614 test_ompd_get_icv_from_scope_with_addr_handle
, METH_VARARGS
,
1615 "Test API ompd_get_icv_from_scope with addr_handle."},
1616 {"test_ompd_get_icv_from_scope_with_thread_handle",
1617 test_ompd_get_icv_from_scope_with_thread_handle
, METH_VARARGS
,
1618 "Test API ompd_get_icv_from_scope with thread_handle."},
1619 {"test_ompd_get_icv_from_scope_with_parallel_handle",
1620 test_ompd_get_icv_from_scope_with_parallel_handle
, METH_VARARGS
,
1621 "Test API ompd_get_icv_from_scope with parallel_handle."},
1622 {"test_ompd_get_icv_from_scope_with_task_handle",
1623 test_ompd_get_icv_from_scope_with_task_handle
, METH_VARARGS
,
1624 "Test API ompd_get_icv_from_scope with task_handle."},
1625 {"test_ompd_get_icv_string_from_scope", test_ompd_get_icv_string_from_scope
,
1626 METH_VARARGS
, "Test API ompd_get_icv_string_from_scope."},
1627 {"test_ompd_get_tool_data", test_ompd_get_tool_data
, METH_VARARGS
,
1628 "Test API ompd_get_tool_data."},
1629 {"test_ompd_enumerate_states", test_ompd_enumerate_states
, METH_VARARGS
,
1630 "Test API ompd_enumerate_states."},
1631 {NULL
, NULL
, 0, NULL
}};
1634 * Lets Python initialize module.
1636 #if PY_MAJOR_VERSION >= 3
1637 static struct PyModuleDef moduledef
= {
1638 PyModuleDef_HEAD_INIT
,
1639 "ompdModule", /* m_name */
1640 "This is a module", /* m_doc */
1642 ompdModule_methods
, /* m_methods */
1643 NULL
, /* m_reload */
1644 NULL
, /* m_traverse */
1649 void PyInit_ompdModule(void) {
1650 // (void) Py_InitModule("ompdModule", ompdModule_methods);
1651 PyModule_Create(&moduledef
);