brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.9 KiB · 0532ca3 Raw
1094 lines · cpp
1/*2 * omp-debug.cpp3 *4 *  Created on: Jan 14, 20155 *      Author: Ignacio Laguna6 *              Joachim Protze7 *     Contact: ilaguna@llnl.gov8 *              protze@llnl.gov9 */10/*******************************************************************************11 * This implements an OMPD DLL for the LLVM OpenMP runtime library.12 */13 14//===----------------------------------------------------------------------===//15//16// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.17// See https://llvm.org/LICENSE.txt for license information.18// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception19//20//===----------------------------------------------------------------------===//21 22#define NDEBUG 123 24#include "omp-debug.h"25#include "TargetValue.h"26#include "omp.h"27#include "ompd-private.h"28#include <assert.h>29#include <cstdio>30#include <inttypes.h>31#include <pthread.h>32#include <stdint.h>33 34ompd_device_type_sizes_t type_sizes;35uint64_t ompd_state;36ompd_rc_t ompd_get_num_threads(37    ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */38    ompd_word_t *val /* OUT: number of threads */);39 40/* --- OMPD functions ------------------------------------------------------- */41 42/* --- Initialization ------------------------------------------------------- */43 44ompd_rc_t ompd_initialize(ompd_word_t version, const ompd_callbacks_t *table) {45  ompd_rc_t ret = ompd_rc_ok;46  ompd_word_t ompd_version;47 48  if (!table)49    return ompd_rc_bad_input;50 51  ompd_get_api_version(&ompd_version);52  if (version != ompd_version)53    return ompd_rc_unsupported;54  callbacks = table;55  TValue::callbacks = table;56  __ompd_init_icvs(table);57  __ompd_init_states(table);58 59  return ret;60}61 62ompd_rc_t ompd_finalize(void) { return ompd_rc_ok; }63 64ompd_rc_t ompd_process_initialize(65    ompd_address_space_context_t66        *context, /* IN: debugger handle for the target */67    ompd_address_space_handle_t **handle /* OUT: ompd handle for the target */68) {69  if (!context)70    return ompd_rc_bad_input;71  if (!handle)72    return ompd_rc_bad_input;73 74  ompd_rc_t ret = initTypeSizes(context);75  if (ret != ompd_rc_ok)76    return ret;77 78  ret = TValue(context, "ompd_state")79            .castBase(ompd_type_long_long)80            .getValue(ompd_state);81  if (ret != ompd_rc_ok)82    return ret;83  ret = callbacks->alloc_memory(sizeof(ompd_address_space_handle_t),84                                (void **)(handle));85  if (ret != ompd_rc_ok)86    return ret;87  if (!*handle)88    return ompd_rc_error;89 90  (*handle)->context = context;91  (*handle)->kind = OMPD_DEVICE_KIND_HOST;92 93  return ompd_rc_ok;94}95 96ompd_rc_t97ompd_get_omp_version(ompd_address_space_handle_t98                         *address_space, /* IN: handle for the address space */99                     ompd_word_t *version) {100  if (!address_space)101    return ompd_rc_stale_handle;102  if (!version)103    return ompd_rc_bad_input;104 105  ompd_address_space_context_t *context = address_space->context;106  ompd_rc_t ret;107 108  if (!context)109    return ompd_rc_stale_handle;110 111  if (!callbacks) {112    return ompd_rc_callback_error;113  }114 115  ret = TValue(context, "__kmp_openmp_version")116            .castBase(ompd_type_int)117            .getValue(*version);118  return ret;119}120 121ompd_rc_t ompd_get_omp_version_string(122    ompd_address_space_handle_t123        *address_space, /* IN: handle for the address space */124    const char **string) {125  if (!address_space)126    return ompd_rc_stale_handle;127  if (!string)128    return ompd_rc_bad_input;129  ompd_address_space_context_t *context = address_space->context;130  ompd_word_t ver;131  ompd_rc_t ret;132  char *omp_version;133  ret = callbacks->alloc_memory(10, /* max digit can be store on int*/134                                (void **)&omp_version);135 136  if (ret != ompd_rc_ok)137    return ret;138 139  ret = TValue(context, "__kmp_openmp_version")140            .castBase(ompd_type_int)141            .getValue(ver);142  if (ret != ompd_rc_ok)143    return ret;144 145  sprintf(omp_version, "%ld", ver);146  *string = omp_version;147  return ret;148}149 150ompd_rc_t ompd_rel_address_space_handle(151    ompd_address_space_handle_t152        *addr_handle /* IN: handle for the address space */153) {154  if (!addr_handle)155    return ompd_rc_stale_handle;156 157  ompd_rc_t ret = callbacks->free_memory((void *)(addr_handle));158  //  delete addr_handle;159  return ret;160}161 162ompd_rc_t ompd_device_initialize(ompd_address_space_handle_t *process_handle,163                                 ompd_address_space_context_t *device_context,164                                 ompd_device_t kind, ompd_size_t sizeof_id,165                                 void *id,166                                 ompd_address_space_handle_t **device_handle) {167  if (!device_context)168    return ompd_rc_bad_input;169 170  return ompd_rc_unavailable;171}172 173/* --- Thread Handles ------------------------------------------------------- */174 175/* thread_handle is of type (kmp_base_info_t) */176 177ompd_rc_t ompd_get_thread_in_parallel(178    ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */179    int thread_num, /* IN: Thread num, handle of which is to be returned */180    ompd_thread_handle_t **thread_handle /* OUT: handle */181) {182  if (!parallel_handle)183    return ompd_rc_stale_handle;184  if (!parallel_handle->ah)185    return ompd_rc_stale_handle;186  ompd_address_space_context_t *context = parallel_handle->ah->context;187  ompd_rc_t ret;188 189  if (!context)190    return ompd_rc_stale_handle;191 192  if (!callbacks) {193    return ompd_rc_callback_error;194  }195 196  ompd_word_t team_size_var;197  ret = ompd_get_num_threads(parallel_handle, &team_size_var);198  if (ret != ompd_rc_ok)199    return ret;200  if (thread_num < 0 || thread_num >= team_size_var)201    return ompd_rc_bad_input;202 203  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};204 205  ret = TValue(context, parallel_handle->th) /* t */206            .cast("kmp_base_team_t", 0)207            .access("t_threads") /*t.t_threads*/208            .cast("kmp_info_t", 2)209            .getArrayElement(thread_num) /*t.t_threads[nth_handle]*/210            .access("th")                /*t.t_threads[i]->th*/211            .getAddress(&taddr);212 213  if (ret != ompd_rc_ok)214    return ret;215 216  ret = callbacks->alloc_memory(sizeof(ompd_thread_handle_t),217                                (void **)(thread_handle));218  if (ret != ompd_rc_ok)219    return ret;220 221  (*thread_handle)->th = taddr;222  (*thread_handle)->ah = parallel_handle->ah;223  return ret;224}225 226ompd_rc_t ompd_rel_thread_handle(227    ompd_thread_handle_t228        *thread_handle /* IN: OpenMP thread handle to be released */229) {230  if (!thread_handle)231    return ompd_rc_stale_handle;232  ompd_rc_t ret = callbacks->free_memory((void *)(thread_handle));233  if (ret != ompd_rc_ok)234    return ret;235  return ompd_rc_ok;236}237 238ompd_rc_t ompd_thread_handle_compare(ompd_thread_handle_t *thread_handle_1,239                                     ompd_thread_handle_t *thread_handle_2,240                                     int *cmp_value) {241  if (!thread_handle_1)242    return ompd_rc_stale_handle;243  if (!thread_handle_2)244    return ompd_rc_stale_handle;245  if (!cmp_value)246    return ompd_rc_bad_input;247  if (thread_handle_1->ah->kind != thread_handle_2->ah->kind)248    return ompd_rc_bad_input;249  *cmp_value = thread_handle_1->th.address - thread_handle_2->th.address;250 251  return ompd_rc_ok;252}253 254/* --- Parallel Region Handles----------------------------------------------- */255 256/* parallel_handle is of type (kmp_base_team_t)*/257 258ompd_rc_t ompd_get_curr_parallel_handle(259    ompd_thread_handle_t *thread_handle,     /* IN: OpenMP thread handle*/260    ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */261) {262  if (!thread_handle)263    return ompd_rc_stale_handle;264  if (!thread_handle->ah)265    return ompd_rc_stale_handle;266  ompd_address_space_context_t *context = thread_handle->ah->context;267  ompd_thread_context_t *thread_context = thread_handle->thread_context;268  if (!context || !thread_context)269    return ompd_rc_stale_handle;270 271  if (!callbacks) {272    return ompd_rc_callback_error;273  }274 275  ompd_rc_t ret;276 277  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0},278                 lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};279 280  TValue teamdata = TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/281                        .cast("kmp_base_info_t")282                        .access("th_team") /*__kmp_threads[t]->th.th_team*/283                        .cast("kmp_team_p", 1)284                        .access("t"); /*__kmp_threads[t]->th.th_team->t*/285 286  ret = teamdata.getAddress(&taddr);287  if (ret != ompd_rc_ok)288    return ret;289 290  lwt.segment = OMPD_SEGMENT_UNSPECIFIED;291  ret = teamdata.cast("kmp_base_team_t", 0)292            .access("ompt_serialized_team_info")293            .castBase()294            .getValue(lwt.address);295  if (ret != ompd_rc_ok)296    return ret;297 298  ret = callbacks->alloc_memory(sizeof(ompd_parallel_handle_t),299                                (void **)(parallel_handle));300  if (ret != ompd_rc_ok)301    return ret;302 303  (*parallel_handle)->ah = thread_handle->ah;304  (*parallel_handle)->th = taddr;305  (*parallel_handle)->lwt = lwt;306  return ompd_rc_ok;307}308 309ompd_rc_t ompd_get_enclosing_parallel_handle(310    ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */311    ompd_parallel_handle_t *312        *enclosing_parallel_handle /* OUT: OpenMP parallel handle */313) {314  if (!parallel_handle)315    return ompd_rc_stale_handle;316  if (!parallel_handle->ah)317    return ompd_rc_stale_handle;318  ompd_address_space_context_t *context = parallel_handle->ah->context;319 320  if (!context)321    return ompd_rc_stale_handle;322 323  if (!callbacks) {324    return ompd_rc_callback_error;325  }326 327  ompd_address_t taddr = parallel_handle->th,328                 lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};329  ompd_rc_t ret;330 331  ret = ompd_rc_stale_handle;332  TValue lwtValue = TValue(context, parallel_handle->lwt);333  if (lwtValue.getError() == ompd_rc_ok) // lwt == 0x0334  {                                      // if we are in lwt, get parent335    ret = lwtValue.cast("ompt_lw_taskteam_t", 0)336              .access("parent")337              .cast("ompt_lw_taskteam_t", 1)338              .dereference()339              .getAddress(&lwt);340  }341  if (ret != ompd_rc_ok) { // no lwt or parent==0x0342 343    TValue teamdata =344        TValue(context, parallel_handle->th) /*__kmp_threads[t]->th*/345            .cast("kmp_base_team_t", 0)      /*t*/346            .access("t_parent")              /*t.t_parent*/347            .cast("kmp_team_p", 1)348            .access("t"); /*t.t_parent->t*/349 350    ret = teamdata.getAddress(&taddr);351    if (ret != ompd_rc_ok)352      return ret;353 354    lwt.segment = OMPD_SEGMENT_UNSPECIFIED;355    ret = teamdata.cast("kmp_base_team_t", 0)356              .access("ompt_serialized_team_info")357              .castBase()358              .getValue(lwt.address);359    if (ret != ompd_rc_ok)360      return ret;361  }362 363  ret = callbacks->alloc_memory(sizeof(ompd_parallel_handle_t),364                                (void **)(enclosing_parallel_handle));365  if (ret != ompd_rc_ok)366    return ret;367  (*enclosing_parallel_handle)->th = taddr;368  (*enclosing_parallel_handle)->lwt = lwt;369  (*enclosing_parallel_handle)->ah = parallel_handle->ah;370  return ompd_rc_ok;371}372 373ompd_rc_t ompd_get_task_parallel_handle(374    ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */375    ompd_parallel_handle_t *376        *task_parallel_handle /* OUT: OpenMP parallel handle */377) {378  if (!task_handle)379    return ompd_rc_stale_handle;380  if (!task_handle->ah)381    return ompd_rc_stale_handle;382  ompd_address_space_context_t *context = task_handle->ah->context;383 384  if (!context)385    return ompd_rc_stale_handle;386 387  if (!callbacks) {388    return ompd_rc_callback_error;389  }390 391  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};392 393  ompd_rc_t ret;394 395  ret = TValue(context, task_handle->th)396            .cast("kmp_taskdata_t") /*td*/397            .access("td_team")      /*td.td_team*/398            .cast("kmp_team_p", 1)399            .access("t") /*td.td_team->t*/400            .getAddress(&taddr);401 402  if (ret != ompd_rc_ok)403    return ret;404 405  ret = callbacks->alloc_memory(sizeof(ompd_parallel_handle_t),406                                (void **)(task_parallel_handle));407  if (ret != ompd_rc_ok)408    return ret;409 410  (*task_parallel_handle)->ah = task_handle->ah;411  (*task_parallel_handle)->lwt = task_handle->lwt;412  (*task_parallel_handle)->th = taddr;413  return ompd_rc_ok;414}415 416ompd_rc_t ompd_rel_parallel_handle(417    ompd_parallel_handle_t *parallel_handle /* IN: OpenMP parallel handle */418) {419  if (!parallel_handle)420    return ompd_rc_stale_handle;421  ompd_rc_t ret = callbacks->free_memory((void *)(parallel_handle));422  if (ret != ompd_rc_ok)423    return ret;424  return ompd_rc_ok;425}426 427ompd_rc_t428ompd_parallel_handle_compare(ompd_parallel_handle_t *parallel_handle_1,429                             ompd_parallel_handle_t *parallel_handle_2,430                             int *cmp_value) {431  if (!parallel_handle_1)432    return ompd_rc_stale_handle;433  if (!parallel_handle_2)434    return ompd_rc_stale_handle;435  if (!cmp_value)436    return ompd_rc_bad_input;437  if (parallel_handle_1->ah->kind != parallel_handle_2->ah->kind)438    return ompd_rc_bad_input;439  if (parallel_handle_1->ah->kind == OMPD_DEVICE_KIND_HOST) {440    if (parallel_handle_1->th.address - parallel_handle_2->th.address)441      *cmp_value =442          parallel_handle_1->th.address - parallel_handle_2->th.address;443    else444      *cmp_value =445          parallel_handle_1->lwt.address - parallel_handle_2->lwt.address;446  } else {447    *cmp_value = parallel_handle_1->th.address - parallel_handle_2->th.address;448  }449  return ompd_rc_ok;450}451 452/* ------- Task Handles ----------------------------------------------------- */453 454/* task_handle is of type (kmp_taskdata_t) */455 456ompd_rc_t ompd_get_curr_task_handle(457    ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/458    ompd_task_handle_t **task_handle     /* OUT: OpenMP task handle */459) {460  if (!thread_handle)461    return ompd_rc_stale_handle;462  if (!thread_handle->ah)463    return ompd_rc_stale_handle;464  ompd_address_space_context_t *context = thread_handle->ah->context;465  if (!context)466    return ompd_rc_stale_handle;467 468  if (!callbacks) {469    return ompd_rc_callback_error;470  }471 472  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0},473                 lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};474  ompd_rc_t ret = ompd_rc_ok;475 476  lwt.segment = OMPD_SEGMENT_UNSPECIFIED;477 478  TValue taskdata =479      TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/480          .cast("kmp_base_info_t")481          .access("th_current_task") /*__kmp_threads[t]->th.th_current_task*/482          .cast("kmp_taskdata_t", 1);483 484  ret = taskdata.dereference().getAddress(&taddr);485  if (ret != ompd_rc_ok)486    return ret;487 488  ret = taskdata489            .access("td_team") /*td.td_team*/490            .cast("kmp_team_p", 1)491            .access("t") /*td.td_team->t*/492            .cast("kmp_base_team_t", 0)493            .access("ompt_serialized_team_info")494            .castBase()495            .getValue(lwt.address);496 497  if (ret != ompd_rc_ok)498    return ret;499 500  ret = callbacks->alloc_memory(sizeof(ompd_task_handle_t),501                                (void **)(task_handle));502  if (ret != ompd_rc_ok)503    return ret;504 505  (*task_handle)->th = taddr;506  (*task_handle)->lwt = lwt;507  (*task_handle)->ah = thread_handle->ah;508  return ompd_rc_ok;509}510 511ompd_rc_t ompd_get_generating_task_handle(512    ompd_task_handle_t *task_handle,        /* IN: OpenMP task handle */513    ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */514) {515  if (!task_handle)516    return ompd_rc_stale_handle;517  if (!task_handle->ah)518    return ompd_rc_stale_handle;519 520  ompd_address_space_context_t *context = task_handle->ah->context;521  if (!context)522    return ompd_rc_stale_handle;523  if (!callbacks) {524    return ompd_rc_callback_error;525  }526 527  ompd_address_t taddr = task_handle->th, lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};528 529  ompd_rc_t ret = ompd_rc_stale_handle;530  TValue lwtValue = TValue(context, task_handle->lwt);531  if (lwtValue.getError() == ompd_rc_ok) // lwt == 0x0532  {                                      // if we are in lwt, get parent533    ret = lwtValue.cast("ompt_lw_taskteam_t", 0)534              .access("parent")535              .cast("ompt_lw_taskteam_t", 1)536              .dereference()537              .getAddress(&lwt);538  }539  if (ret != ompd_rc_ok) { // no lwt or parent==0x0540 541    TValue taskdata = TValue(context, task_handle->th) /*__kmp_threads[t]->th*/542                          .cast("kmp_taskdata_t")      /*td*/543                          .access("td_parent")         /*td->td_parent*/544                          .cast("kmp_taskdata_t", 1);545 546    ret = taskdata.dereference().getAddress(&taddr);547    if (ret != ompd_rc_ok)548      return ret;549 550    lwt.segment = OMPD_SEGMENT_UNSPECIFIED;551    ret = taskdata552              .access("td_team") /*td.td_team*/553              .cast("kmp_team_p", 1)554              .access("t") /*td.td_team->t*/555              .cast("kmp_base_team_t", 0)556              .access("ompt_serialized_team_info")557              .castBase()558              .getValue(lwt.address);559    if (ret != ompd_rc_ok)560      return ret;561  }562 563  ret = callbacks->alloc_memory(sizeof(ompd_task_handle_t),564                                (void **)(parent_task_handle));565  if (ret != ompd_rc_ok)566    return ret;567 568  (*parent_task_handle)->th = taddr;569  (*parent_task_handle)->lwt = lwt;570  (*parent_task_handle)->ah = task_handle->ah;571  return ret;572}573 574ompd_rc_t ompd_get_scheduling_task_handle(575    ompd_task_handle_t *task_handle,        /* IN: OpenMP task handle */576    ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */577) {578  if (!task_handle)579    return ompd_rc_stale_handle;580  if (!task_handle->ah)581    return ompd_rc_stale_handle;582  ompd_address_space_context_t *context = task_handle->ah->context;583  if (!context)584    return ompd_rc_stale_handle;585 586  if (!callbacks) {587    return ompd_rc_callback_error;588  }589 590  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};591  ompd_rc_t ret;592 593  ret = TValue(context, task_handle->th)594            .cast("kmp_taskdata_t")   /*td*/595            .access("ompt_task_info") // td->ompt_task_info596            .cast("ompt_task_info_t")597            .access("scheduling_parent") // td->ompd_task_info.scheduling_parent598            .cast("kmp_taskdata_t", 1)599            .castBase()600            .getValue(taddr.address);601  if (taddr.address == 0) {602    return ompd_rc_unavailable;603  }604 605  if (ret != ompd_rc_ok)606    return ret;607  ret = callbacks->alloc_memory(sizeof(ompd_task_handle_t),608                                (void **)(parent_task_handle));609  if (ret != ompd_rc_ok)610    return ret;611 612  (*parent_task_handle)->th = taddr;613  (*parent_task_handle)->lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};614  (*parent_task_handle)->ah = task_handle->ah;615  return ret;616}617 618ompd_rc_t ompd_get_task_in_parallel(619    ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */620    int thread_num, /* IN: thread num of implicit task of team */621    ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */622) {623  if (!parallel_handle)624    return ompd_rc_stale_handle;625  if (!parallel_handle->ah)626    return ompd_rc_stale_handle;627  ompd_address_space_context_t *context = parallel_handle->ah->context;628  if (!context)629    return ompd_rc_stale_handle;630 631  if (!callbacks) {632    return ompd_rc_callback_error;633  }634 635  ompd_rc_t ret;636  ompd_word_t team_size_var;637  ret = ompd_get_num_threads(parallel_handle, &team_size_var);638  if (ret != ompd_rc_ok)639    return ret;640  if (thread_num < 0 || thread_num >= team_size_var)641    return ompd_rc_bad_input;642 643  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};644 645  ret = TValue(context, parallel_handle->th) /* t */646            .cast("kmp_base_team_t", 0)647            .access("t_implicit_task_taskdata") /*t.t_implicit_task_taskdata*/648            .cast("kmp_taskdata_t", 1)649            .getArrayElement(650                thread_num) /*t.t_implicit_task_taskdata[nth_handle]*/651            .getAddress(&taddr);652 653  if (ret != ompd_rc_ok)654    return ret;655  ret = callbacks->alloc_memory(sizeof(ompd_task_handle_t),656                                (void **)(task_handle));657  if (ret != ompd_rc_ok)658    return ret;659 660  (*task_handle)->th = taddr;661  (*task_handle)->ah = parallel_handle->ah;662  (*task_handle)->lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};663  return ret;664}665 666ompd_rc_t ompd_rel_task_handle(667    ompd_task_handle_t *task_handle /* IN: OpenMP task handle */668) {669  if (!task_handle)670    return ompd_rc_stale_handle;671  ompd_rc_t ret = callbacks->free_memory((void *)(task_handle));672  if (ret != ompd_rc_ok)673    return ret;674  return ompd_rc_ok;675}676 677ompd_rc_t ompd_task_handle_compare(ompd_task_handle_t *task_handle_1,678                                   ompd_task_handle_t *task_handle_2,679                                   int *cmp_value) {680  if (!task_handle_1)681    return ompd_rc_stale_handle;682  if (!task_handle_2)683    return ompd_rc_stale_handle;684  if (!cmp_value)685    return ompd_rc_bad_input;686  if (task_handle_1->ah->kind != task_handle_2->ah->kind)687    return ompd_rc_bad_input;688  if (task_handle_1->th.address - task_handle_2->th.address)689    *cmp_value = task_handle_1->th.address - task_handle_2->th.address;690  else691    *cmp_value = task_handle_1->lwt.address - task_handle_2->lwt.address;692  return ompd_rc_ok;693}694 695ompd_rc_t ompd_get_thread_handle(696    ompd_address_space_handle_t *handle, /* IN: handle for the address space */697    ompd_thread_id_t kind, ompd_size_t sizeof_thread_id, const void *thread_id,698    ompd_thread_handle_t **thread_handle) {699  if (!handle)700    return ompd_rc_stale_handle;701  ompd_address_space_context_t *context = handle->context;702  ompd_rc_t ret;703 704  if (!context)705    return ompd_rc_stale_handle;706 707  if (!callbacks) {708    return ompd_rc_callback_error;709  }710  ompd_thread_context_t *tcontext;711  ret = callbacks->get_thread_context_for_thread_id(712      context, kind, sizeof_thread_id, thread_id, &tcontext);713  if (ret != ompd_rc_ok)714    return ret;715 716  int tId;717 718  ret = TValue(context, tcontext, "__kmp_gtid")719            .castBase("__kmp_gtid")720            .getValue(tId);721  if (ret != ompd_rc_ok)722    return ret;723 724  if (tId < 0) // thread is no omp worker725    return ompd_rc_unavailable;726 727  TValue th = TValue(context, "__kmp_threads") // __kmp_threads728                  .cast("kmp_info_t", 2)729                  .getArrayElement(tId) /*__kmp_threads[t]*/730                  .access("th");        /*__kmp_threads[t]->th*/731 732  ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};733  ret = th.getAddress(&taddr);734  if (ret != ompd_rc_ok)735    return ret;736  ret = callbacks->alloc_memory(sizeof(ompd_thread_handle_t),737                                (void **)(thread_handle));738  if (ret != ompd_rc_ok)739    return ret;740  (*thread_handle)->ah = handle;741  (*thread_handle)->th = taddr;742 743#ifndef NDEBUG744  if (ret != ompd_rc_ok)745    return ret;746 747  pthread_t oshandle;748  TBaseValue ds_handle =749      th.cast("kmp_base_info_t")750          .access("th_info") /*__kmp_threads[t]->th.th_info*/751          .cast("kmp_desc_t")752          .access("ds") /*__kmp_threads[t]->th.th_info.ds*/753          .cast("kmp_desc_base_t")754          .access("ds_thread") /*__kmp_threads[t]->th.th_info.ds.ds_thread*/755          .castBase();756 757  assert(ompd_rc_ok == ds_handle.getValue(oshandle) &&758         oshandle == *(pthread_t *)(thread_id) &&759         "Callback table not initialized!");760#endif761 762  (*thread_handle)->thread_context = tcontext;763  return ret;764}765 766ompd_rc_t ompd_get_thread_id(767    ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/768    ompd_thread_id_t kind, ompd_size_t sizeof_thread_id, void *thread_id) {769  if (kind != OMPD_THREAD_ID_PTHREAD)770    return ompd_rc_unsupported;771  if (!thread_id)772    return ompd_rc_bad_input;773  if (!thread_handle)774    return ompd_rc_stale_handle;775  if (!thread_handle->ah)776    return ompd_rc_stale_handle;777  ompd_address_space_context_t *context = thread_handle->ah->context;778  if (!context)779    return ompd_rc_stale_handle;780  ompd_rc_t ret;781 782  ompd_size_t size;783  ret = tf.getType(context, "kmp_thread_t").getSize(&size);784  if (ret != ompd_rc_ok)785    return ret;786  if (sizeof_thread_id != size)787    return ompd_rc_bad_input;788 789  if (!callbacks) {790    return ompd_rc_callback_error;791  }792 793  ret = TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/794            .cast("kmp_base_info_t")795            .access("th_info") /*__kmp_threads[t]->th.th_info*/796            .cast("kmp_desc_t")797            .access("ds") /*__kmp_threads[t]->th.th_info.ds*/798            .cast("kmp_desc_base_t")799            .access("ds_thread") /*__kmp_threads[t]->th.th_info.ds.ds_thread*/800            .cast("kmp_thread_t")801            .getRawValue(thread_id, 1);802 803  return ret;804}805 806/* --- OMPT Thread State Inquiry Analogue ----------------------------------- */807 808ompd_rc_t ompd_get_state(809    ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/810    ompd_word_t *state,                  /* OUT: State of this thread */811    ompd_wait_id_t *wait_id              /* OUT: Wait ID */812) {813  if (!thread_handle)814    return ompd_rc_stale_handle;815  if (!thread_handle->ah)816    return ompd_rc_stale_handle;817  if (!state)818    return ompd_rc_bad_input;819  ompd_address_space_context_t *context = thread_handle->ah->context;820  if (!context)821    return ompd_rc_stale_handle;822  if (!ompd_state)823    return ompd_rc_needs_state_tracking;824 825  if (!callbacks) {826    return ompd_rc_callback_error;827  }828  ompd_rc_t ret;829 830  TValue ompt_thread_info =831      TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/832          .cast("kmp_base_info_t")833          .access("ompt_thread_info") /*__kmp_threads[t]->th.ompt_thread_info*/834          .cast("ompt_thread_info_t");835  if (ompt_thread_info.gotError())836    return ompt_thread_info.getError();837  ret = ompt_thread_info838            .access("state") /*__kmp_threads[t]->th.ompt_thread_info.state*/839            .castBase()840            .getValue(*state);841  if (ret != ompd_rc_ok)842    return ret;843  if (wait_id)844    ret = ompt_thread_info845              .access("wait_id") /*__kmp_threads[t]->th.ompt_thread_info.state*/846              .castBase()847              .getValue(*wait_id);848 849  return ret;850}851 852/* ---  Task Inquiry -------------------------------------------------------- */853 854/* ---  Task Settings ------------------------------------------------------- */855 856/* ---  OMPT Task Inquiry Analogues ----------------------------------------- */857 858ompd_rc_t859ompd_get_task_frame(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/860                    ompd_frame_info_t *exit_frame,861                    ompd_frame_info_t *enter_frame) {862  if (!task_handle)863    return ompd_rc_stale_handle;864  if (!task_handle->ah)865    return ompd_rc_stale_handle;866  if (!exit_frame || !enter_frame)867    return ompd_rc_bad_input;868  ompd_address_space_context_t *context = task_handle->ah->context;869  if (!context)870    return ompd_rc_stale_handle;871  if (!ompd_state)872    return ompd_rc_needs_state_tracking;873 874  if (!callbacks) {875    return ompd_rc_callback_error;876  }877 878  ompd_rc_t ret;879 880  TValue taskInfo;881  if (task_handle->lwt.address != 0)882    taskInfo =883        TValue(context, task_handle->lwt).cast("ompt_lw_taskteam_t", 0); /*lwt*/884  else885    taskInfo = TValue(context, task_handle->th).cast("kmp_taskdata_t", 0); /*t*/886  TValue frame = taskInfo887                     .access("ompt_task_info") // td->ompt_task_info888                     .cast("ompt_task_info_t")889                     .access("frame") // td->ompd_task_info.frame890                     .cast("ompt_frame_t", 0);891  enter_frame->frame_address.segment = OMPD_SEGMENT_UNSPECIFIED;892  ret = frame893            .access("enter_frame") // td->ompt_task_info.frame.enter_frame894            .castBase()895            .getValue(enter_frame->frame_address.address);896 897  if (ret != ompd_rc_ok)898    return ret;899 900  exit_frame->frame_address.segment = OMPD_SEGMENT_UNSPECIFIED;901  ret = frame902            .access("exit_frame") // td->ompt_task_info.frame.exit_frame903            .castBase()904            .getValue(exit_frame->frame_address.address);905 906  return ret;907}908 909ompd_rc_t ompd_get_task_function(910    ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */911    ompd_address_t *task_addr /* OUT: first instruction in the task region */912) {913  if (!task_handle)914    return ompd_rc_stale_handle;915  if (!task_handle->ah)916    return ompd_rc_stale_handle;917  if (!task_addr)918    return ompd_rc_bad_input;919  ompd_address_space_context_t *context = task_handle->ah->context;920  if (!context)921    return ompd_rc_stale_handle;922  if (!ompd_state)923    return ompd_rc_needs_state_tracking;924  if (!callbacks) {925    return ompd_rc_callback_error;926  }927 928  ompd_rc_t ret;929 930  task_addr->segment = OMPD_SEGMENT_UNSPECIFIED;931  TValue taskInfo;932  if (task_handle->lwt.address != 0)933    return ompd_rc_bad_input; // We need to decide what we do here.934  else {935    ompd_word_t val;936    ret = TValue(context, task_handle->th)937              .cast("kmp_taskdata_t") // td938              .access("td_flags")     // td->td_flags939              .cast("kmp_tasking_flags_t")940              .check("tasktype", &val); // td->td_flags.tasktype941 942    if (ret != ompd_rc_ok)943      return ret;944 945    if (val == 1) { // tasktype: explicit = 1, implicit = 0946 947      ret = TValue(context, task_handle->th)948                .cast("kmp_taskdata_t", 0) /*t*/949                .getArrayElement(950                    1) /* see kmp.h: #define KMP_TASKDATA_TO_TASK(taskdata)951                          (kmp_task_t *)(taskdata + 1) */952                .cast("kmp_task_t", 0) /* (kmp_task_t *) */953                .access("routine")     /*td->ompt_task_info*/954                .castBase()955                .getValue(task_addr->address);956 957    } else {958 959      ret = TValue(context, task_handle->th)960                .cast("kmp_taskdata_t") /*td*/961                .access("td_team")      /*td.td_team*/962                .cast("kmp_team_p", 1)963                .access("t") /*td.td_team->t*/964                .cast("kmp_base_team_t", 0)965                .access("t_pkfn") /*td.td_team->t.t_pkfn*/966                .castBase()967                .getValue(task_addr->address);968    }969  }970 971  return ret;972}973 974/* ------- OMPD Version and Compatibility Information ----------------------- */975 976ompd_rc_t ompd_get_api_version(ompd_word_t *version) {977  if (!version)978    return ompd_rc_bad_input;979 980  *version = OMPD_VERSION;981  return ompd_rc_ok;982}983 984ompd_rc_t985ompd_get_version_string(const char **string /* OUT: OMPD version string */986) {987  if (!string)988    return ompd_rc_bad_input;989 990  static const char version_string[] =991      "LLVM OpenMP " STR(OMPD_IMPLEMENTS_OPENMP) "." STR(992          OMPD_IMPLEMENTS_OPENMP_SUBVERSION) " Debugging Library implmenting "993                                             "TR " STR(OMPD_TR_VERSION) "" STR(994                                                 OMPD_TR_SUBVERSION);995  *string = version_string;996  return ompd_rc_ok;997}998 999/* ------ Display Control Variables ----------------------------------------- */1000 1001ompd_rc_t ompd_get_display_control_vars(ompd_address_space_handle_t *handle,1002                                        const char *const **control_vars) {1003  if (!handle)1004    return ompd_rc_stale_handle;1005  if (!control_vars)1006    return ompd_rc_bad_input;1007 1008  ompd_address_space_context_t *context = handle->context;1009  if (!context)1010    return ompd_rc_stale_handle;1011 1012  // runtime keeps a full dump of OMP/KMP definitions in this format1013  // <var1 name>=<var1 value>\n<var2 name>=<var2 value>\n...1014  ompd_address_t block_addr = {ompd_segment_none, 0};1015  OMPD_GET_VALUE(context, NULL, "ompd_env_block", type_sizes.sizeof_pointer,1016                 &block_addr.address);1017 1018  // query size of the block1019  ompd_size_t block_size;1020  OMPD_GET_VALUE(context, NULL, "ompd_env_block_size", sizeof(ompd_size_t),1021                 &block_size);1022 1023  // copy raw data from the address space1024  char *block;1025  OMPD_CALLBACK(alloc_memory, block_size, (void **)&block);1026  OMPD_CALLBACK(read_memory, context, NULL, &block_addr, block_size, block);1027 1028  // count number of items, replace new line to zero.1029  int block_items = 1; // also count the last "NULL" item1030  for (ompd_size_t i = 0; i < block_size; i++) {1031    if (block[i] == '\n') {1032      block_items++;1033      block[i] = '\0';1034    }1035  }1036 1037  // create vector of char*1038  const char **ctl_vars;1039  OMPD_CALLBACK(alloc_memory, block_items * sizeof(char *),1040                (void **)(&ctl_vars));1041  char *pos = block;1042  ctl_vars[0] = block;1043 1044  // ctl_vars[0] points to the entire block, ctl_vars[1]... points to the1045  // smaller subsets of the block, and ctl_vars[block_items-2] points to the1046  // last string in the block.1047  for (int i = 1; i < block_items - 1; i++) {1048    while (*pos++ != '\0')1049      ;1050    if (pos > block + block_size)1051      return ompd_rc_error;1052    ctl_vars[i] = pos;1053  }1054  // last item must be NULL1055  ctl_vars[block_items - 1] = NULL;1056 1057  *control_vars = ctl_vars;1058 1059  return ompd_rc_ok;1060}1061 1062ompd_rc_t ompd_rel_display_control_vars(const char *const **control_vars) {1063  if (!control_vars)1064    return ompd_rc_bad_input;1065 1066  char **ctl_vars = const_cast<char **>(*control_vars);1067 1068  // remove the raw block first1069  OMPD_CALLBACK(free_memory, (void *)ctl_vars[0]);1070  // remove the vector1071  OMPD_CALLBACK(free_memory, (void *)ctl_vars);1072 1073  return ompd_rc_ok;1074}1075 1076/* --- Helper functions ----------------------------------------------------- */1077 1078ompd_rc_t initTypeSizes(ompd_address_space_context_t *context) {1079  static int inited = 0;1080  static ompd_rc_t ret;1081  if (inited)1082    return ret;1083  ret = callbacks->sizeof_type(context, &type_sizes);1084  if (ret != ompd_rc_ok)1085    return ret;1086  if (!(type_sizes.sizeof_pointer > 0))1087    return ompd_rc_error;1088  ret = callbacks->sizeof_type(context, &TValue::type_sizes);1089  if (ret != ompd_rc_ok)1090    return ret;1091  inited = 1;1092  return ret;1093}1094