brintos

brintos / llvm-project-archived public Read only

0
0
Text · 61.2 KiB · c6020de Raw
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, &parallelHandle);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