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