1655 lines · c
1/*2 * ompdModule.c3 */4 5//===----------------------------------------------------------------------===//6//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-exception10//11//===----------------------------------------------------------------------===//12 13#include <Python.h>14#include <omp-tools.h>15// #include <ompd.h>16#include <dlfcn.h>17#include <errno.h>18#include <pthread.h>19#include <stdio.h>20#include <stdlib.h>21#include <string.h>22 23void *ompd_library;24 25#define OMPD_WEAK_ATTR __attribute__((weak))26 27struct _ompd_aspace_cont {28 int id;29};30struct _ompd_thread_cont {31 int id;32};33ompd_address_space_context_t acontext = {42};34 35PyObject *pModule;36 37ompd_rc_t _print(const char *str, int category);38 39// NOTE: implement functions to check parameters of OMPD API functions for40// correctness41OMPD_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");45 if (dlerror()) {46 return ompd_rc_error;47 }48 }49 return my_get_api_version(addr);50}51 52OMPD_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");56 if (dlerror()) {57 return ompd_rc_error;58 }59 }60 return my_get_version_string(string);61}62 63OMPD_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");67 if (dlerror()) {68 return ompd_rc_error;69 }70 }71 return my_ompd_finalize();72}73 74OMPD_WEAK_ATTR ompd_rc_t75ompd_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");81 if (dlerror()) {82 return ompd_rc_error;83 }84 }85 return my_ompd_process_initialize(context, handle);86}87 88OMPD_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");94 if (dlerror()) {95 return ompd_rc_error;96 }97 }98 return my_ompd_get_omp_version(address_space, omp_version);99}100 101OMPD_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");108 if (dlerror()) {109 return ompd_rc_error;110 }111 }112 return my_ompd_get_omp_version_string(address_space, string);113}114 115OMPD_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");123 if (dlerror()) {124 return ompd_rc_error;125 }126 }127 return my_get_thread_handle(handle, kind, tidSize, tid, threadHandle);128}129 130OMPD_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");138 if (dlerror()) {139 return ompd_rc_error;140 }141 }142 return my_get_thread_in_parallel(parallelHandle, threadNum, threadHandle);143}144 145OMPD_WEAK_ATTR ompd_rc_t ompd_thread_handle_compare(146 ompd_thread_handle_t *thread_handle1, ompd_thread_handle_t *thread_handle2,147 int *cmp_value) {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");153 if (dlerror()) {154 return ompd_rc_error;155 }156 }157 return my_thread_handle_compare(thread_handle1, thread_handle2, cmp_value);158}159 160OMPD_WEAK_ATTR ompd_rc_t161ompd_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");168 if (dlerror()) {169 return ompd_rc_error;170 }171 }172 return my_get_current_parallel_handle(threadHandle, parallelHandle);173}174 175OMPD_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");183 if (dlerror()) {184 return ompd_rc_error;185 }186 }187 return my_parallel_handle_compare(parallel_handle_1, parallel_handle_2,188 cmp_value);189}190 191OMPD_WEAK_ATTR ompd_rc_t192ompd_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");199 if (dlerror()) {200 return ompd_rc_error;201 }202 }203 return my_get_enclosing_parallel_handle(parallelHandle, enclosing);204}205 206OMPD_WEAK_ATTR ompd_rc_t207ompd_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");214 if (dlerror()) {215 return ompd_rc_error;216 }217 }218 return my_get_task_parallel_handle(taskHandle, taskParallelHandle);219}220 221OMPD_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");228 if (dlerror()) {229 return ompd_rc_error;230 }231 }232 return my_get_current_task_handle(threadHandle, taskHandle);233}234 235OMPD_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");242 if (dlerror()) {243 return ompd_rc_error;244 }245 }246 return my_get_generating_task_handle(taskHandle, generating);247}248 249OMPD_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");256 if (dlerror()) {257 return ompd_rc_error;258 }259 }260 return my_get_scheduling_task_handle(taskHandle, scheduling);261}262 263OMPD_WEAK_ATTR ompd_rc_t264ompd_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");270 if (dlerror()) {271 return ompd_rc_error;272 }273 }274 return my_get_task_in_parallel(parallelHandle, threadNum, taskHandle);275}276 277OMPD_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");284 if (dlerror()) {285 return ompd_rc_error;286 }287 }288 return my_get_task_frame(taskHandle, exitFrame, enterFrame);289}290 291OMPD_WEAK_ATTR ompd_rc_t ompd_get_icv_from_scope(void *handle,292 ompd_scope_t scope,293 ompd_icv_id_t icvId,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");299 if (dlerror()) {300 return ompd_rc_error;301 }302 }303 return my_get_icv_from_scope(handle, scope, icvId, icvValue);304}305 306OMPD_WEAK_ATTR ompd_rc_t307ompd_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");315 if (dlerror()) {316 return ompd_rc_error;317 }318 }319 return my_enumerate_icvs(handle, current, next, nextIcvName, nextScope, more);320}321 322OMPD_WEAK_ATTR ompd_rc_t323ompd_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");331 if (dlerror()) {332 return ompd_rc_error;333 }334 }335 return my_enumerate_states(addrSpaceHandle, currentState, nextState,336 nextStateName, moreEnums);337}338 339OMPD_WEAK_ATTR ompd_rc_t ompd_get_state(ompd_thread_handle_t *threadHandle,340 ompd_word_t *state,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;344 if (!my_get_state) {345 my_get_state = dlsym(ompd_library, "ompd_get_state");346 if (dlerror()) {347 return ompd_rc_error;348 }349 }350 return my_get_state(threadHandle, state, waitId);351}352 353OMPD_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");359 if (dlerror()) {360 return ompd_rc_error;361 }362 }363 return my_get_task_function(taskHandle, entryPoint);364}365 366OMPD_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");373 if (dlerror()) {374 return ompd_rc_error;375 }376 }377 return my_get_thread_id(threadHandle, kind, tidSize, tid);378}379 380OMPD_WEAK_ATTR ompd_rc_t ompd_get_tool_data(void *handle, ompd_scope_t scope,381 ompd_word_t *value,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");387 if (dlerror()) {388 return ompd_rc_error;389 }390 }391 return my_get_tool_data(handle, scope, value, ptr);392}393 394OMPD_WEAK_ATTR ompd_rc_t395ompd_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");402 if (dlerror()) {403 return ompd_rc_error;404 }405 }406 return my_get_icv_string_from_scope(handle, scope, icvId, icvString);407}408 409OMPD_WEAK_ATTR ompd_rc_t410ompd_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");414 if (dlerror()) {415 return ompd_rc_error;416 }417 }418 return my_release_thread_handle(threadHandle);419}420 421OMPD_WEAK_ATTR ompd_rc_t422ompd_rel_parallel_handle(ompd_parallel_handle_t *parallelHandle) {423 static ompd_rc_t (*my_release_parallel_handle)(ompd_parallel_handle_t *) =424 NULL;425 if (!my_release_parallel_handle) {426 my_release_parallel_handle =427 dlsym(ompd_library, "ompd_rel_parallel_handle");428 if (dlerror()) {429 return ompd_rc_error;430 }431 }432 return my_release_parallel_handle(parallelHandle);433}434 435OMPD_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");439 if (dlerror()) {440 return ompd_rc_error;441 }442 }443 return my_release_task_handle(taskHandle);444}445 446OMPD_WEAK_ATTR ompd_rc_t447ompd_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");453 if (dlerror()) {454 return ompd_rc_error;455 }456 }457 return my_task_handle_compare(task_handle_1, task_handle_2, cmp_value);458}459 460OMPD_WEAK_ATTR ompd_rc_t461ompd_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");468 if (dlerror()) {469 return ompd_rc_error;470 }471 }472 return my_ompd_get_display_control_vars(address_space_handle, control_vars);473}474 475/**476 * Loads the OMPD library (libompd.so). Returns an integer with the version if477 * the OMPD library could be loaded successfully. Error codes: -1: argument478 * could not be converted to string -2: error when calling dlopen -3: error when479 * fetching version of OMPD API else: see ompd return codes480 */481static PyObject *ompd_open(PyObject *self, PyObject *args) {482 const char *name, *dlerr;483 dlerror();484 if (!PyArg_ParseTuple(args, "s", &name)) {485 return Py_BuildValue("i", -1);486 }487 ompd_library = dlopen(name, RTLD_LAZY);488 if ((dlerr = dlerror())) {489 return Py_BuildValue("i", -2);490 }491 if (dlerror()) {492 return Py_BuildValue("i", -3);493 }494 ompd_word_t version;495 ompd_rc_t rc = ompd_get_api_version(&version);496 if (rc != ompd_rc_ok)497 return Py_BuildValue("l", -10 - rc);498 499 int returnValue = version;500 return Py_BuildValue("i", returnValue);501}502 503/**504 * Have the debugger print a string.505 */506ompd_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);512 Py_XDECREF(pArgs);513 }514 Py_XDECREF(pFunc);515 return ompd_rc_ok;516}517 518void _printf(const char *format, ...) {519 va_list args;520 va_start(args, format);521 char output[1024];522 vsnprintf(output, 1024, format, args);523 va_end(args);524 _print(output, 0);525}526 527/**528 * Capsule destructors for thread, parallel and task handles.529 */530static void call_ompd_rel_thread_handle_temp(PyObject *capsule) {531 ompd_thread_handle_t *threadHandle =532 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule, "ThreadHandle"));533 534 ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle);535 if (retVal != ompd_rc_ok) {536 _printf(537 "An error occurred when calling ompd_rel_thread_handle! Error code: %d",538 retVal);539 }540}541 542static void destroyThreadCapsule(PyObject *capsule) {543 call_ompd_rel_thread_handle_temp(capsule);544}545static void (*my_thread_capsule_destructor)(PyObject *) = destroyThreadCapsule;546 547static void call_ompd_rel_parallel_handle_temp(PyObject *capsule) {548 ompd_parallel_handle_t *parallelHandle =549 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule,550 "ParallelHandle"));551 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 "555 "code: %d",556 retVal);557 }558}559 560static void destroyParallelCapsule(PyObject *capsule) {561 call_ompd_rel_parallel_handle_temp(capsule);562}563static void (*my_parallel_capsule_destructor)(PyObject *) =564 destroyParallelCapsule;565 566static void call_ompd_rel_task_handle_temp(PyObject *capsule) {567 ompd_task_handle_t *taskHandle =568 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule, "TaskHandle"));569 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");573 }574}575 576static void destroyTaskCapsule(PyObject *capsule) {577 call_ompd_rel_task_handle_temp(capsule);578}579static void (*my_task_capsule_destructor)(PyObject *) = destroyTaskCapsule;580 581/**582 * Release thread handle. Called inside destructor for Python thread_handle583 * object.584 */585static 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,589 "ThreadHandle"));590 591 ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle);592 if (retVal != ompd_rc_ok) {593 _printf(594 "An error occurred when calling ompd_rel_thread_handle! Error code: %d",595 retVal);596 }597 return Py_BuildValue("l", retVal);598}599 600/**601 * Allocate memory in the debugger's address space.602 */603ompd_rc_t _alloc(ompd_size_t bytes, void **ptr) {604 if (ptr == NULL) {605 return ompd_rc_bad_input;606 }607 *ptr = malloc(bytes);608 return ompd_rc_ok;609}610 611/**612 * Free memory in the debugger's address space.613 */614ompd_rc_t _free(void *ptr) {615 free(ptr);616 return ompd_rc_ok;617}618 619/**620 * Look up the sizes of primitive types in the target.621 */622ompd_rc_t _sizes(ompd_address_space_context_t *_acontext, /* IN */623 ompd_device_type_sizes_t *sizes) /* OUT */624{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 *)};631 *sizes = mysizes;632 return ompd_rc_ok;633}634 635/**636 * Look up the address of a global symbol in the target.637 */638ompd_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 */643{644 int thread_id = -1;645 PyObject *symbolAddress;646 if (tcontext != NULL) {647 thread_id = tcontext->id;648 }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) {656 PyErr_Print();657 }658 symbol_addr->address = PyLong_AsLong(symbolAddress);659 Py_XDECREF(pArgs);660 Py_XDECREF(symbolAddress);661 }662 Py_XDECREF(pFunc);663 return ompd_rc_ok;664}665 666/**667 * Read memory from the target.668 */669ompd_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 */674{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);682 Py_XDECREF(pArgs);683 if (retArray == NULL) {684 PyErr_Print();685 }686 if (!PyByteArray_Check(retArray)) {687 return ompd_rc_error;688 }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;693 }694 memcpy(buffer, strBuf, nbytes);695 Py_XDECREF(retArray);696 }697 Py_XDECREF(pFunc);698 return ompd_rc_ok;699}700 701/**702 * Reads string from target.703 */704ompd_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 */709{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);716 Py_XDECREF(pArgs);717 if (!PyUnicode_Check(retString)) {718 return ompd_rc_error;719 }720 Py_ssize_t retSize;721 const char *strbuffer = PyUnicode_AsUTF8AndSize(retString, &retSize);722 if ((ompd_size_t)retSize + 1 >= nbytes) {723 retVal = ompd_rc_incomplete;724 }725 strncpy(buffer, strbuffer, nbytes);726 ((char *)buffer)[nbytes - 1] = '\0';727 return retVal;728}729 730/**731 * Write memory from the target.732 */733ompd_rc_t734_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 */738 void *output) {739 if (acontext.id != address_space_context->id)740 return ompd_rc_stale_handle;741 memmove(output, input, count * unit_size);742 return ompd_rc_ok;743}744 745/**746 * Returns thread context for thread id; helper function for _thread_context747 * callback.748 */749ompd_thread_context_t *get_thread_context(int id) {750 static ompd_thread_context_t *tc = NULL;751 static int size = 0;752 int i;753 if (id < 1)754 return NULL;755 if (tc == NULL) {756 size = 16;757 tc = malloc(size * sizeof(ompd_thread_context_t));758 for (i = 0; i < size; i++)759 tc[i].id = i + 1;760 }761 if (id - 1 >= size) {762 size += 16;763 tc = realloc(tc, size * sizeof(ompd_thread_context_t));764 for (i = 0; i < size; i++)765 tc[i].id = i + 1;766 }767 return tc + id - 1;768}769 770/**771 * Get thread specific context.772 */773ompd_rc_t774_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 */779{780 if (acontext.id != context->id)781 return ompd_rc_stale_handle;782 if (kind != 0 && kind != 1)783 return ompd_rc_unsupported;784 long int tid;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;791 else792 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_id802 return ompd_rc_unavailable;803 }804 (*thread_context) = get_thread_context(resAsInt);805 Py_XDECREF(pArgs);806 Py_XDECREF(res);807 Py_XDECREF(pFunc);808 if (*thread_context == NULL) {809 return ompd_rc_bad_input;810 }811 return ompd_rc_ok;812 }813 Py_XDECREF(pFunc);814 return ompd_rc_error;815}816 817/**818 * Calls ompd_process_initialize; returns pointer to ompd_address_space_handle.819 */820static PyObject *call_ompd_initialize(PyObject *self, PyObject *noargs) {821 pModule = PyImport_Import(PyUnicode_FromString("ompd_callbacks"));822 823 static ompd_callbacks_t table = {824 _alloc, _free, _print, _sizes, _sym_addr, _read,825 NULL, _read_string, _endianess, _endianess, _thread_context};826 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",832 returnInit);833 }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 "841 "code: %d",842 retProcInit);843 }844 return PyCapsule_New(addr_space, "AddressSpace", NULL);845}846 847/**848 * Returns a PyCapsule pointer to thread handle for thread with the given id.849 */850static 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 memory854 // is allocated automatically in the debugger's memory space855 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,860 "AddressSpace");861 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,864 &threadHandle);865 866 if (retVal == ompd_rc_unavailable) {867 return Py_BuildValue("i", -1);868 } else if (retVal != ompd_rc_ok) {869 _printf(870 "An error occured when calling ompd_get_thread_handle! Error code: %d",871 retVal);872 return Py_BuildValue("l", retVal);873 }874 return PyCapsule_New(threadHandle, "ThreadHandle",875 my_thread_capsule_destructor);876}877 878/**879 * Returns a PyCapsule pointer to a thread handle for a specific thread id in880 * the current parallel context.881 */882static PyObject *call_ompd_get_thread_in_parallel(PyObject *self,883 PyObject *args) {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,888 "ParallelHandle"));889 ompd_thread_handle_t *threadHandle;890 891 ompd_rc_t retVal =892 ompd_get_thread_in_parallel(parallelHandle, threadNum, &threadHandle);893 894 if (retVal != ompd_rc_ok) {895 _printf("An error occurred when calling ompd_get_thread_in_parallel! Error "896 "code: %d",897 retVal);898 return Py_BuildValue("l", retVal);899 }900 return PyCapsule_New(threadHandle, "ThreadHandle",901 my_thread_capsule_destructor);902}903 904/**905 * Returns a PyCapsule pointer to the parallel handle of the current parallel906 * region associated with a thread.907 */908static PyObject *call_ompd_get_curr_parallel_handle(PyObject *self,909 PyObject *args) {910 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);911 ompd_thread_handle_t *threadHandle =912 (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,913 "ThreadHandle"));914 ompd_parallel_handle_t *parallelHandle;915 916 ompd_rc_t retVal =917 ompd_get_curr_parallel_handle(threadHandle, ¶llelHandle);918 919 if (retVal != ompd_rc_ok) {920 _printf("An error occurred when calling ompd_get_curr_parallel_handle! "921 "Error code: %d",922 retVal);923 return Py_BuildValue("l", retVal);924 }925 return PyCapsule_New(parallelHandle, "ParallelHandle",926 my_parallel_capsule_destructor);927}928 929/**930 * Returns a PyCapsule pointer to the parallel handle for the parallel region931 * enclosing the parallel region specified by parallel_handle.932 */933static PyObject *call_ompd_get_enclosing_parallel_handle(PyObject *self,934 PyObject *args) {935 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);936 ompd_parallel_handle_t *parallelHandle =937 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,938 "ParallelHandle"));939 ompd_parallel_handle_t *enclosingParallelHandle;940 941 ompd_rc_t retVal = ompd_get_enclosing_parallel_handle(942 parallelHandle, &enclosingParallelHandle);943 944 if (retVal != ompd_rc_ok) {945 _printf("An error occurred when calling "946 "ompd_get_enclosing_parallel_handle!"947 "Error code: %d",948 retVal);949 return Py_BuildValue("l", retVal);950 }951 return PyCapsule_New(enclosingParallelHandle, "ParallelHandle",952 my_parallel_capsule_destructor);953}954 955/**956 * Returns a PyCapsule pointer to the parallel handle for the parallel region957 * enclosing the task specified.958 */959static PyObject *call_ompd_get_task_parallel_handle(PyObject *self,960 PyObject *args) {961 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);962 ompd_task_handle_t *taskHandle =963 PyCapsule_GetPointer(taskHandlePy, "TaskHandle");964 ompd_parallel_handle_t *taskParallelHandle;965 966 ompd_rc_t retVal =967 ompd_get_task_parallel_handle(taskHandle, &taskParallelHandle);968 969 if (retVal != ompd_rc_ok) {970 _printf("An error occurred when calling ompd_get_task_parallel_handle! "971 "Error code: %d", retVal);972 return Py_BuildValue("l", retVal);973 }974 return PyCapsule_New(taskParallelHandle, "ParallelHandle",975 my_parallel_capsule_destructor);976}977 978/**979 * Releases a parallel handle; is called in by the destructor of a Python980 * parallel_handle object.981 */982static PyObject *call_ompd_rel_parallel_handle(PyObject *self, PyObject *args) {983 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);984 ompd_parallel_handle_t *parallelHandle =985 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,986 "ParallelHandle"));987 988 ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle);989 if (retVal != ompd_rc_ok) {990 _printf("An error occurred when calling ompd_rel_parallel_handle! Error "991 "code: %d",992 retVal);993 }994 return Py_BuildValue("l", retVal);995}996 997/**998 * Returns a PyCapsule pointer to the task handle of the current task region999 * associated with a thread.1000 */1001static PyObject *call_ompd_get_curr_task_handle(PyObject *self,1002 PyObject *args) {1003 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);1004 ompd_thread_handle_t *threadHandle =1005 (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,1006 "ThreadHandle"));1007 ompd_task_handle_t *taskHandle;1008 1009 ompd_rc_t retVal = ompd_get_curr_task_handle(threadHandle, &taskHandle);1010 1011 if (retVal != ompd_rc_ok) {1012 _printf("An error occurred when calling ompd_get_curr_task_handle! Error "1013 "code: %d",1014 retVal);1015 return Py_BuildValue("l", retVal);1016 }1017 return PyCapsule_New(taskHandle, "TaskHandle", my_task_capsule_destructor);1018}1019 1020/**1021 * Returns a task handle for the task that created the task specified.1022 */1023static PyObject *call_ompd_get_generating_task_handle(PyObject *self,1024 PyObject *args) {1025 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);1026 ompd_task_handle_t *taskHandle =1027 (ompd_task_handle_t *)(PyCapsule_GetPointer(taskHandlePy, "TaskHandle"));1028 ompd_task_handle_t *generatingTaskHandle;1029 1030 ompd_rc_t retVal =1031 ompd_get_generating_task_handle(taskHandle, &generatingTaskHandle);1032 1033 if (retVal != ompd_rc_ok) {1034 _printf("An error occurred when calling ompd_get_generating_task_handle! "1035 "Error code: %d",1036 retVal);1037 return Py_BuildValue("l", retVal);1038 }1039 return PyCapsule_New(generatingTaskHandle, "TaskHandle",1040 my_task_capsule_destructor);1041}1042 1043/**1044 * Returns the task handle for the task that scheduled the task specified.1045 */1046static PyObject *call_ompd_get_scheduling_task_handle(PyObject *self,1047 PyObject *args) {1048 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);1049 ompd_task_handle_t *taskHandle =1050 (ompd_task_handle_t *)(PyCapsule_GetPointer(taskHandlePy, "TaskHandle"));1051 ompd_task_handle_t *schedulingTaskHandle;1052 1053 ompd_rc_t retVal =1054 ompd_get_scheduling_task_handle(taskHandle, &schedulingTaskHandle);1055 1056 if (retVal == ompd_rc_unavailable) {1057 return Py_None;1058 } else if (retVal != ompd_rc_ok) {1059 _printf("An error occurred when calling ompd_get_scheduling_task_handle! "1060 "Error code: %d",1061 retVal);1062 return Py_BuildValue("l", retVal);1063 }1064 return PyCapsule_New(schedulingTaskHandle, "TaskHandle",1065 my_task_capsule_destructor);1066}1067 1068/**1069 * Returns task handles for the implicit tasks associated with a parallel1070 * region.1071 */1072static PyObject *call_ompd_get_task_in_parallel(PyObject *self,1073 PyObject *args) {1074 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);1075 int threadNum = (int)PyLong_AsLong(PyTuple_GetItem(args, 1));1076 ompd_parallel_handle_t *parallelHandle =1077 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(parallelHandlePy,1078 "ParallelHandle"));1079 ompd_task_handle_t *taskHandle;1080 1081 ompd_rc_t retVal =1082 ompd_get_task_in_parallel(parallelHandle, threadNum, &taskHandle);1083 1084 if (retVal != ompd_rc_ok) {1085 _printf("An error occurred when calling ompd_get_task_in_parallel! Error "1086 "code: %d",1087 retVal);1088 return Py_BuildValue("l", retVal);1089 }1090 return PyCapsule_New(taskHandle, "TaskHandle", my_task_capsule_destructor);1091}1092 1093/**1094 * Releases a task handle; is called by the destructor of a Python task_handle1095 * object.1096 */1097static PyObject *call_ompd_rel_task_handle(PyObject *self, PyObject *args) {1098 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);1099 ompd_task_handle_t *taskHandle =1100 (ompd_task_handle_t *)(PyCapsule_GetPointer(taskHandlePy, "TaskHandle"));1101 1102 ompd_rc_t retVal = ompd_rel_task_handle(taskHandle);1103 if (retVal != ompd_rc_ok) {1104 _printf(1105 "An error occurred when calling ompd_rel_task_handle! Error code: %d",1106 retVal);1107 }1108 return Py_BuildValue("l", retVal);1109}1110 1111/**1112 * Calls ompd_get_task_frame and returns a PyCapsule for the enter frame of the1113 * given task.1114 */1115static PyObject *call_ompd_get_task_frame(PyObject *self, PyObject *args) {1116 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);1117 ompd_task_handle_t *taskHandle =1118 (ompd_task_handle_t *)PyCapsule_GetPointer(taskHandlePy, "TaskHandle");1119 ompd_frame_info_t exitFrameInfo;1120 ompd_frame_info_t enterFrameInfo;1121 1122 ompd_rc_t retVal =1123 ompd_get_task_frame(taskHandle, &exitFrameInfo, &enterFrameInfo);1124 1125 if (retVal != ompd_rc_ok) {1126 _printf(1127 "An error occurred when calling ompd_get_task_frame! Error code: %d",1128 retVal);1129 return Py_BuildValue("l", retVal);1130 }1131 1132 PyObject *result = PyTuple_New(4);1133 PyTuple_SetItem(1134 result, 0, PyLong_FromUnsignedLong(enterFrameInfo.frame_address.address));1135 PyTuple_SetItem(result, 1,1136 PyLong_FromUnsignedLong(enterFrameInfo.frame_flag));1137 PyTuple_SetItem(result, 2,1138 PyLong_FromUnsignedLong(exitFrameInfo.frame_address.address));1139 PyTuple_SetItem(result, 3, PyLong_FromUnsignedLong(exitFrameInfo.frame_flag));1140 return result;1141}1142 1143/**1144 * Calls ompd_get_icv_from_scope.1145 */1146static PyObject *call_ompd_get_icv_from_scope(PyObject *self, PyObject *args) {1147 PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);1148 PyObject *scopePy = PyTuple_GetItem(args, 1);1149 PyObject *icvIdPy = PyTuple_GetItem(args, 2);1150 1151 ompd_scope_t scope = (ompd_scope_t)PyLong_AsLong(scopePy);1152 ompd_address_space_handle_t *addrSpaceHandle;1153 switch (scope) {1154 case ompd_scope_thread:1155 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(1156 addrSpaceHandlePy, "ThreadHandle");1157 break;1158 case ompd_scope_parallel:1159 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(1160 addrSpaceHandlePy, "ParallelHandle");1161 break;1162 case ompd_scope_implicit_task:1163 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(1164 addrSpaceHandlePy, "TaskHandle");1165 break;1166 case ompd_scope_task:1167 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(1168 addrSpaceHandlePy, "TaskHandle");1169 break;1170 default:1171 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(1172 addrSpaceHandlePy, "AddressSpace");1173 break;1174 }1175 1176 ompd_icv_id_t icvId = (ompd_icv_id_t)PyLong_AsLong(icvIdPy);1177 ompd_word_t icvValue;1178 1179 ompd_rc_t retVal =1180 ompd_get_icv_from_scope(addrSpaceHandle, scope, icvId, &icvValue);1181 1182 if (retVal != ompd_rc_ok) {1183 if (retVal != ompd_rc_incomplete) {1184 _printf(1185 "An error occurred when calling ompd_get_icv_from_scope(%i, %" PRIu641186 "): Error code: %d",1187 scope, icvId, retVal);1188 }1189 return Py_None;1190 }1191 return PyLong_FromLong(icvValue);1192}1193 1194/**1195 * Calls ompd_enumerate_icvs.1196 */1197static PyObject *call_ompd_enumerate_icvs(PyObject *self, PyObject *args) {1198 PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);1199 PyObject *currentPy = PyTuple_GetItem(args, 1);1200 ompd_icv_id_t current = (ompd_icv_id_t)(PyLong_AsLong(currentPy));1201 ompd_address_space_handle_t *addrSpaceHandle =1202 (ompd_address_space_handle_t *)PyCapsule_GetPointer(addrSpaceHandlePy,1203 "AddressSpace");1204 1205 const char *nextIcv;1206 ompd_scope_t nextScope;1207 int more;1208 ompd_icv_id_t nextId;1209 1210 ompd_rc_t retVal = ompd_enumerate_icvs(addrSpaceHandle, current, &nextId,1211 &nextIcv, &nextScope, &more);1212 1213 if (retVal != ompd_rc_ok) {1214 _printf(1215 "An error occurred when calling ompd_enumerate_icvs! Error code: %d",1216 retVal);1217 return Py_None;1218 }1219 PyObject *retTuple = PyTuple_New(4);1220 PyTuple_SetItem(retTuple, 0, PyLong_FromUnsignedLong(nextId));1221 PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(nextIcv));1222 PyTuple_SetItem(retTuple, 2, PyLong_FromUnsignedLong(nextScope));1223 PyTuple_SetItem(retTuple, 3, PyLong_FromLong(more));1224 return retTuple;1225}1226 1227/**1228 * Calls ompd_enumerate_states.1229 */1230static PyObject *call_ompd_enumerate_states(PyObject *self, PyObject *args) {1231 PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);1232 ompd_address_space_handle_t *addrSpaceHandle =1233 (ompd_address_space_handle_t *)PyCapsule_GetPointer(addrSpaceHandlePy,1234 "AddressSpace");1235 ompd_word_t currentState =1236 (ompd_word_t)PyLong_AsLong(PyTuple_GetItem(args, 1));1237 1238 ompd_word_t nextState;1239 const char *nextStateName;1240 ompd_word_t moreEnums;1241 1242 ompd_rc_t retVal = ompd_enumerate_states(1243 addrSpaceHandle, currentState, &nextState, &nextStateName, &moreEnums);1244 1245 if (retVal != ompd_rc_ok) {1246 _printf(1247 "An error occurred when calling ompd_enumerate_states! Error code: %d",1248 retVal);1249 return Py_None;1250 }1251 PyObject *retTuple = PyTuple_New(3);1252 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(nextState));1253 PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(nextStateName));1254 PyTuple_SetItem(retTuple, 2, PyLong_FromLong(moreEnums));1255 return retTuple;1256}1257 1258/**1259 * Calls ompd_get_state.1260 */1261static PyObject *call_ompd_get_state(PyObject *self, PyObject *args) {1262 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);1263 ompd_thread_handle_t *threadHandle =1264 (ompd_thread_handle_t *)PyCapsule_GetPointer(threadHandlePy,1265 "ThreadHandle");1266 ompd_word_t state;1267 ompd_wait_id_t waitId;1268 1269 ompd_rc_t retVal = ompd_get_state(threadHandle, &state, &waitId);1270 1271 if (retVal != ompd_rc_ok) {1272 _printf("An error occurred when calling ompd_get_state! Error code: %d",1273 retVal);1274 return Py_None;1275 }1276 PyObject *retTuple = PyTuple_New(2);1277 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(state));1278 PyTuple_SetItem(retTuple, 1, PyLong_FromUnsignedLong(waitId));1279 return retTuple;1280}1281 1282/**1283 * Calls ompd_get_task_function and returns entry point of the code that1284 * corresponds to the code executed by the task.1285 */1286static PyObject *call_ompd_get_task_function(PyObject *self, PyObject *args) {1287 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);1288 ompd_task_handle_t *taskHandle =1289 (ompd_task_handle_t *)PyCapsule_GetPointer(taskHandlePy, "TaskHandle");1290 ompd_address_t entryPoint;1291 1292 ompd_rc_t retVal = ompd_get_task_function(taskHandle, &entryPoint);1293 1294 if (retVal != ompd_rc_ok) {1295 _printf(1296 "An error occurred when calling ompd_get_task_function! Error code: %d",1297 retVal);1298 return Py_None;1299 }1300 return PyLong_FromLong((long)entryPoint.address);1301}1302 1303/**1304 * Prints pointer stored inside PyCapusle.1305 */1306static PyObject *print_capsule(PyObject *self, PyObject *args) {1307 PyObject *capsule = PyTuple_GetItem(args, 0);1308 PyObject *name = PyTuple_GetItem(args, 1);1309 void *pointer =1310 PyCapsule_GetPointer(capsule, PyUnicode_AsUTF8AndSize(name, NULL));1311 _printf("Capsule pointer: %p", pointer);1312 return Py_None;1313}1314 1315/**1316 * Calls ompd_get_thread_id for given handle and returns the thread id as a1317 * long.1318 */1319static PyObject *call_ompd_get_thread_id(PyObject *self, PyObject *args) {1320 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);1321 ompd_thread_handle_t *threadHandle =1322 (ompd_thread_handle_t *)(PyCapsule_GetPointer(threadHandlePy,1323 "ThreadHandle"));1324 ompd_thread_id_t kind = 0; // OMPD_THREAD_ID_PTHREAD1325 ompd_size_t sizeOfId = (ompd_size_t)sizeof(pthread_t);1326 1327 uint64_t thread;1328 ompd_rc_t retVal = ompd_get_thread_id(threadHandle, kind, sizeOfId, &thread);1329 1330 if (retVal != ompd_rc_ok) {1331 kind = 1; // OMPD_THREAD_ID_LWP1332 retVal = ompd_get_thread_id(threadHandle, kind, sizeOfId, &thread);1333 if (retVal != ompd_rc_ok) {1334 _printf(1335 "An error occurred when calling ompd_get_thread_id! Error code: %d",1336 retVal);1337 return Py_None;1338 }1339 }1340 return PyLong_FromLong(thread);1341}1342 1343/**1344 * Calls ompd_get_tool_data and returns a tuple containing the value and pointer1345 * of the ompt_data_t union for the selected scope.1346 */1347static PyObject *call_ompd_get_tool_data(PyObject *self, PyObject *args) {1348 PyObject *scopePy = PyTuple_GetItem(args, 0);1349 ompd_scope_t scope = (ompd_scope_t)(PyLong_AsLong(scopePy));1350 PyObject *handlePy = PyTuple_GetItem(args, 1);1351 void *handle = NULL;1352 1353 if (scope == 3) {1354 ompd_thread_handle_t *threadHandle =1355 (ompd_thread_handle_t *)(PyCapsule_GetPointer(handlePy,1356 "ThreadHandle"));1357 handle = threadHandle;1358 } else if (scope == 4) {1359 ompd_parallel_handle_t *parallelHandle =1360 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(handlePy,1361 "ParallelHandle"));1362 handle = parallelHandle;1363 } else if (scope == 5 || scope == 6) {1364 ompd_task_handle_t *taskHandle =1365 (ompd_task_handle_t *)(PyCapsule_GetPointer(handlePy, "TaskHandle"));1366 handle = taskHandle;1367 } else {1368 _printf("An error occured when calling ompd_get_tool_data! Scope type not "1369 "supported.");1370 return Py_None;1371 }1372 1373 ompd_word_t value;1374 ompd_address_t ptr;1375 1376 ompd_rc_t retVal = ompd_get_tool_data(handle, scope, &value, &ptr);1377 1378 if (retVal != ompd_rc_ok) {1379 _printf("An error occured when calling ompd_get_tool_data! Error code: %d",1380 retVal);1381 return Py_None;1382 }1383 1384 PyObject *retTuple = PyTuple_New(2);1385 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(value));1386 PyTuple_SetItem(retTuple, 1, PyLong_FromLong(ptr.address));1387 return retTuple;1388}1389 1390/** Calls ompd_get_icv_string_from_scope.1391 */1392static PyObject *call_ompd_get_icv_string_from_scope(PyObject *self,1393 PyObject *args) {1394 PyObject *handlePy = PyTuple_GetItem(args, 0);1395 PyObject *scopePy = PyTuple_GetItem(args, 1);1396 PyObject *icvIdPy = PyTuple_GetItem(args, 2);1397 1398 ompd_scope_t scope = (ompd_scope_t)PyLong_AsLong(scopePy);1399 void *handle = NULL;1400 switch (scope) {1401 case ompd_scope_thread:1402 handle =1403 (ompd_thread_handle_t *)PyCapsule_GetPointer(handlePy, "ThreadHandle");1404 break;1405 case ompd_scope_parallel:1406 handle = (ompd_parallel_handle_t *)PyCapsule_GetPointer(handlePy,1407 "ParallelHandle");1408 break;1409 case ompd_scope_implicit_task:1410 handle = (ompd_task_handle_t *)PyCapsule_GetPointer(handlePy, "TaskHandle");1411 break;1412 case ompd_scope_task:1413 handle = (ompd_task_handle_t *)PyCapsule_GetPointer(handlePy, "TaskHandle");1414 break;1415 default:1416 handle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(1417 handlePy, "AddressSpace");1418 break;1419 }1420 1421 ompd_icv_id_t icvId = (ompd_icv_id_t)PyLong_AsLong(icvIdPy);1422 const char *icvString;1423 1424 ompd_rc_t retVal =1425 ompd_get_icv_string_from_scope(handle, scope, icvId, &icvString);1426 1427 if (retVal != ompd_rc_ok) {1428 _printf("An error occurred when calling ompd_get_icv_string_from_scope! "1429 "Error code: %d",1430 retVal);1431 return Py_None;1432 }1433 return PyUnicode_FromString(icvString);1434}1435 1436// Prototypes of API test functions.1437PyObject *test_ompd_get_thread_handle(PyObject *self, PyObject *args);1438PyObject *test_ompd_get_curr_parallel_handle(PyObject *self, PyObject *args);1439PyObject *test_ompd_get_thread_in_parallel(PyObject *self, PyObject *args);1440PyObject *test_ompd_thread_handle_compare(PyObject *self, PyObject *args);1441PyObject *test_ompd_get_thread_id(PyObject *self, PyObject *args);1442PyObject *test_ompd_rel_thread_handle(PyObject *self, PyObject *args);1443PyObject *test_ompd_get_enclosing_parallel_handle(PyObject *self,1444 PyObject *args);1445PyObject *test_ompd_parallel_handle_compare(PyObject *self, PyObject *args);1446PyObject *test_ompd_rel_parallel_handle(PyObject *self, PyObject *args);1447PyObject *test_ompd_initialize(PyObject *self, PyObject *noargs);1448PyObject *test_ompd_get_api_version(PyObject *self, PyObject *noargs);1449PyObject *test_ompd_get_version_string(PyObject *self, PyObject *noargs);1450PyObject *test_ompd_finalize(PyObject *self, PyObject *noargs);1451PyObject *test_ompd_process_initialize(PyObject *self, PyObject *noargs);1452PyObject *test_ompd_device_initialize(PyObject *self, PyObject *noargs);1453PyObject *test_ompd_rel_address_space_handle(PyObject *self, PyObject *noargs);1454PyObject *test_ompd_get_omp_version(PyObject *self, PyObject *args);1455PyObject *test_ompd_get_omp_version_string(PyObject *self, PyObject *args);1456PyObject *test_ompd_get_curr_task_handle(PyObject *self, PyObject *args);1457PyObject *test_ompd_get_task_parallel_handle(PyObject *self, PyObject *args);1458PyObject *test_ompd_get_generating_task_handle(PyObject *self, PyObject *args);1459PyObject *test_ompd_get_scheduling_task_handle(PyObject *self, PyObject *args);1460PyObject *test_ompd_get_task_in_parallel(PyObject *self, PyObject *args);1461PyObject *test_ompd_rel_task_handle(PyObject *self, PyObject *noargs);1462PyObject *test_ompd_task_handle_compare(PyObject *self, PyObject *args);1463PyObject *test_ompd_get_task_function(PyObject *self, PyObject *args);1464PyObject *test_ompd_get_task_frame(PyObject *self, PyObject *args);1465PyObject *test_ompd_get_state(PyObject *self, PyObject *args);1466PyObject *test_ompd_get_display_control_vars(PyObject *self, PyObject *args);1467PyObject *test_ompd_rel_display_control_vars(PyObject *self, PyObject *noargs);1468PyObject *test_ompd_enumerate_icvs(PyObject *self, PyObject *noargs);1469PyObject *test_ompd_get_icv_from_scope_with_addr_handle(PyObject *self,1470 PyObject *noargs);1471PyObject *test_ompd_get_icv_from_scope_with_thread_handle(PyObject *self,1472 PyObject *noargs);1473PyObject *test_ompd_get_icv_from_scope_with_parallel_handle(PyObject *self,1474 PyObject *noargs);1475PyObject *test_ompd_get_icv_from_scope_with_task_handle(PyObject *self,1476 PyObject *noargs);1477PyObject *test_ompd_get_icv_string_from_scope(PyObject *self, PyObject *noargs);1478PyObject *test_ompd_get_tool_data(PyObject *self, PyObject *noargs);1479PyObject *test_ompd_enumerate_states(PyObject *self, PyObject *noargs);1480/**1481 * Binds Python function names to C functions.1482 */1483static PyMethodDef ompdModule_methods[] = {1484 {"ompd_open", ompd_open, METH_VARARGS,1485 "Execute dlopen, return OMPD version."},1486 {"call_ompd_initialize", call_ompd_initialize, METH_NOARGS,1487 "Initializes OMPD environment and callbacks."},1488 {"call_ompd_rel_thread_handle", call_ompd_rel_thread_handle, METH_VARARGS,1489 "Releases a thread handle."},1490 {"get_thread_handle", get_thread_handle, METH_VARARGS,1491 "Collects information on threads."},1492 {"call_ompd_get_thread_in_parallel", call_ompd_get_thread_in_parallel,1493 METH_VARARGS,1494 "Obtains handle for a certain thread within parallel region."},1495 {"call_ompd_get_curr_parallel_handle", call_ompd_get_curr_parallel_handle,1496 METH_VARARGS,1497 "Obtains a pointer to the parallel handle for the current parallel "1498 "region."},1499 {"call_ompd_get_enclosing_parallel_handle",1500 call_ompd_get_enclosing_parallel_handle, METH_VARARGS,1501 "Obtains a pointer to the parallel handle for the parallel region "1502 "enclosing the parallel region specified."},1503 {"call_ompd_get_task_parallel_handle", call_ompd_get_task_parallel_handle,1504 METH_VARARGS,1505 "Obtains a pointer to the parallel handle for the parallel region "1506 "enclosing the task region specified."},1507 {"call_ompd_rel_parallel_handle", call_ompd_rel_parallel_handle,1508 METH_VARARGS, "Releases a parallel region handle."},1509 {"call_ompd_get_curr_task_handle", call_ompd_get_curr_task_handle,1510 METH_VARARGS,1511 "Obtains a pointer to the task handle for the current task region "1512 "associated with an OpenMP thread."},1513 {"call_ompd_get_generating_task_handle",1514 call_ompd_get_generating_task_handle, METH_VARARGS,1515 "Obtains a pointer to the task handle for the task that was created when "1516 "the task handle specified was encountered."},1517 {"call_ompd_get_scheduling_task_handle",1518 call_ompd_get_scheduling_task_handle, METH_VARARGS,1519 "Obtains a pointer to the task handle for the task that scheduled the "1520 "task specified."},1521 {"call_ompd_get_task_in_parallel", call_ompd_get_task_in_parallel,1522 METH_VARARGS,1523 "Obtains the handle for implicit tasks associated with a parallel "1524 "region."},1525 {"call_ompd_rel_task_handle", call_ompd_rel_task_handle, METH_VARARGS,1526 "Releases a task handle."},1527 {"call_ompd_get_task_frame", call_ompd_get_task_frame, METH_VARARGS,1528 "Returns a pointer to the enter and exit frame address and flag of the "1529 "given task."},1530 {"call_ompd_enumerate_icvs", call_ompd_enumerate_icvs, METH_VARARGS,1531 "Saves ICVs in map."},1532 {"call_ompd_get_icv_from_scope", call_ompd_get_icv_from_scope, METH_VARARGS,1533 "Gets ICVs from scope."},1534 {"call_ompd_enumerate_states", call_ompd_enumerate_states, METH_VARARGS,1535 "Enumerates OMP states."},1536 {"call_ompd_get_state", call_ompd_get_state, METH_VARARGS,1537 "Returns state for given thread handle."},1538 {"call_ompd_get_task_function", call_ompd_get_task_function, METH_VARARGS,1539 "Returns point of code where task starts executing."},1540 {"print_capsule", print_capsule, METH_VARARGS, "Print capsule content"},1541 {"call_ompd_get_thread_id", call_ompd_get_thread_id, METH_VARARGS,1542 "Maps an OMPD thread handle to a native thread."},1543 {"call_ompd_get_tool_data", call_ompd_get_tool_data, METH_VARARGS,1544 "Returns value and pointer of ompd_data_t for given scope and handle."},1545 {"call_ompd_get_icv_string_from_scope", call_ompd_get_icv_string_from_scope,1546 METH_VARARGS, "Gets ICV string representation from scope."},1547 1548 {"test_ompd_get_thread_handle", test_ompd_get_thread_handle, METH_VARARGS,1549 "Test API ompd_get_thread_handle."},1550 {"test_ompd_get_curr_parallel_handle", test_ompd_get_curr_parallel_handle,1551 METH_VARARGS, "Test API test_ompd_get_curr_parallel_handle."},1552 {"test_ompd_get_thread_in_parallel", test_ompd_get_thread_in_parallel,1553 METH_VARARGS, "Test API ompd_get_thread_in_parallel."},1554 {"test_ompd_thread_handle_compare", test_ompd_thread_handle_compare,1555 METH_VARARGS, "Test API ompd_thread_handle_compare."},1556 {"test_ompd_get_thread_id", test_ompd_get_thread_id, METH_VARARGS,1557 "Test API ompd_get_thread_id."},1558 {"test_ompd_rel_thread_handle", test_ompd_rel_thread_handle, METH_VARARGS,1559 "Test API ompd_rel_thread_handle."},1560 {"test_ompd_get_enclosing_parallel_handle",1561 test_ompd_get_enclosing_parallel_handle, METH_VARARGS,1562 "Test API ompd_get_enclosing_parallel_handle."},1563 {"test_ompd_parallel_handle_compare", test_ompd_parallel_handle_compare,1564 METH_VARARGS, "Test API test_ompd_parallel_handle_compare."},1565 {"test_ompd_rel_parallel_handle", test_ompd_rel_parallel_handle,1566 METH_VARARGS, "Test API ompd_rel_parallel_handle."},1567 1568 {"test_ompd_initialize", test_ompd_initialize, METH_VARARGS,1569 "Test API ompd_initialize."},1570 {"test_ompd_get_api_version", test_ompd_get_api_version, METH_VARARGS,1571 "Test API ompd_get_api_version."},1572 {"test_ompd_get_version_string", test_ompd_get_version_string, METH_VARARGS,1573 "Test API ompd_get_version_string."},1574 {"test_ompd_finalize", test_ompd_finalize, METH_VARARGS,1575 "Test API ompd_finalize."},1576 {"test_ompd_process_initialize", test_ompd_process_initialize, METH_VARARGS,1577 "Test API ompd_process_initialize. "},1578 {"test_ompd_device_initialize", test_ompd_device_initialize, METH_VARARGS,1579 "Test API ompd_device_initialize."},1580 {"test_ompd_rel_address_space_handle", test_ompd_rel_address_space_handle,1581 METH_VARARGS, "Test API ompd_rel_address_space_handle."},1582 {"test_ompd_get_omp_version", test_ompd_get_omp_version, METH_VARARGS,1583 "Test API ompd_get_omp_version."},1584 {"test_ompd_get_omp_version_string", test_ompd_get_omp_version_string,1585 METH_VARARGS, "Test API ompd_get_omp_version_string."},1586 1587 {"test_ompd_get_curr_task_handle", test_ompd_get_curr_task_handle,1588 METH_VARARGS, "Test API ompd_get_curr_task_handle."},1589 {"test_ompd_get_task_parallel_handle", test_ompd_get_task_parallel_handle,1590 METH_VARARGS, "Test API ompd_get_task_parallel_handle."},1591 {"test_ompd_get_generating_task_handle",1592 test_ompd_get_generating_task_handle, METH_VARARGS,1593 "Test API ompd_get_generating_task_handle."},1594 {"test_ompd_get_scheduling_task_handle",1595 test_ompd_get_scheduling_task_handle, METH_VARARGS,1596 "Test API ompd_get_scheduling_task_handle."},1597 {"test_ompd_get_task_in_parallel", test_ompd_get_task_in_parallel,1598 METH_VARARGS, "Test API ompd_get_task_in_parallel."},1599 {"test_ompd_rel_task_handle", test_ompd_rel_task_handle, METH_VARARGS,1600 "Test API ompd_rel_task_handle."},1601 {"test_ompd_task_handle_compare", test_ompd_task_handle_compare,1602 METH_VARARGS, "Test API ompd_task_handle_compare."},1603 {"test_ompd_get_task_function", test_ompd_get_task_function, METH_VARARGS,1604 "Test API ompd_get_task_function."},1605 {"test_ompd_get_task_frame", test_ompd_get_task_frame, METH_VARARGS,1606 "Test API ompd_get_task_frame."},1607 {"test_ompd_get_state", test_ompd_get_state, METH_VARARGS,1608 "Test API ompd_get_state."},1609 {"test_ompd_get_display_control_vars", test_ompd_get_display_control_vars,1610 METH_VARARGS, "Test API ompd_get_display_control_vars."},1611 {"test_ompd_rel_display_control_vars", test_ompd_rel_display_control_vars,1612 METH_VARARGS, "Test API ompd_rel_display_control_vars."},1613 {"test_ompd_enumerate_icvs", test_ompd_enumerate_icvs, METH_VARARGS,1614 "Test API ompd_enumerate_icvs."},1615 {"test_ompd_get_icv_from_scope_with_addr_handle",1616 test_ompd_get_icv_from_scope_with_addr_handle, METH_VARARGS,1617 "Test API ompd_get_icv_from_scope with addr_handle."},1618 {"test_ompd_get_icv_from_scope_with_thread_handle",1619 test_ompd_get_icv_from_scope_with_thread_handle, METH_VARARGS,1620 "Test API ompd_get_icv_from_scope with thread_handle."},1621 {"test_ompd_get_icv_from_scope_with_parallel_handle",1622 test_ompd_get_icv_from_scope_with_parallel_handle, METH_VARARGS,1623 "Test API ompd_get_icv_from_scope with parallel_handle."},1624 {"test_ompd_get_icv_from_scope_with_task_handle",1625 test_ompd_get_icv_from_scope_with_task_handle, METH_VARARGS,1626 "Test API ompd_get_icv_from_scope with task_handle."},1627 {"test_ompd_get_icv_string_from_scope", test_ompd_get_icv_string_from_scope,1628 METH_VARARGS, "Test API ompd_get_icv_string_from_scope."},1629 {"test_ompd_get_tool_data", test_ompd_get_tool_data, METH_VARARGS,1630 "Test API ompd_get_tool_data."},1631 {"test_ompd_enumerate_states", test_ompd_enumerate_states, METH_VARARGS,1632 "Test API ompd_enumerate_states."},1633 {NULL, NULL, 0, NULL}};1634 1635/**1636 * Lets Python initialize module.1637 */1638#if PY_MAJOR_VERSION >= 31639static struct PyModuleDef moduledef = {1640 PyModuleDef_HEAD_INIT,1641 "ompdModule", /* m_name */1642 "This is a module", /* m_doc */1643 -1, /* m_size */1644 ompdModule_methods, /* m_methods */1645 NULL, /* m_reload */1646 NULL, /* m_traverse */1647 NULL, /* m_clear */1648 NULL, /* m_free */1649};1650#endif1651void PyInit_ompdModule(void) {1652 // (void) Py_InitModule("ompdModule", ompdModule_methods);1653 PyModule_Create(&moduledef);1654}1655