1 /* 2 * omp-debug.cpp 3 * 4 * Created on: Jan 14, 2015 5 * Author: Ignacio Laguna 6 * Joachim Protze 7 * Contact: [email protected] 8 * [email protected] 9 */ 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-exception 19 // 20 //===----------------------------------------------------------------------===// 21 22 #define NDEBUG 1 23 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 34 ompd_device_type_sizes_t type_sizes; 35 uint64_t ompd_state; 36 ompd_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 44 ompd_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 62 ompd_rc_t ompd_finalize(void) { return ompd_rc_ok; } 63 64 ompd_rc_t ompd_process_initialize( 65 ompd_address_space_context_t 66 *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 96 ompd_rc_t 97 ompd_get_omp_version(ompd_address_space_handle_t 98 *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 121 ompd_rc_t ompd_get_omp_version_string( 122 ompd_address_space_handle_t 123 *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 150 ompd_rc_t ompd_rel_address_space_handle( 151 ompd_address_space_handle_t 152 *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 162 ompd_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 177 ompd_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 226 ompd_rc_t ompd_rel_thread_handle( 227 ompd_thread_handle_t 228 *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 238 ompd_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 258 ompd_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 309 ompd_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 == 0x0 334 { // if we are in lwt, get parent 335 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==0x0 342 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 373 ompd_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 416 ompd_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 427 ompd_rc_t 428 ompd_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 else 444 *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 456 ompd_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 = taskdata 489 .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 511 ompd_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 == 0x0 532 { // if we are in lwt, get parent 533 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==0x0 540 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 = taskdata 552 .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 574 ompd_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_info 596 .cast("ompt_task_info_t") 597 .access("scheduling_parent") // td->ompd_task_info.scheduling_parent 598 .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 618 ompd_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 666 ompd_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 677 ompd_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 else 691 *cmp_value = task_handle_1->lwt.address - task_handle_2->lwt.address; 692 return ompd_rc_ok; 693 } 694 695 ompd_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 worker 725 return ompd_rc_unavailable; 726 727 TValue th = TValue(context, "__kmp_threads") // __kmp_threads 728 .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 NDEBUG 744 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 #endif 761 762 (*thread_handle)->thread_context = tcontext; 763 return ret; 764 } 765 766 ompd_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 808 ompd_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_info 838 .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_info 845 .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 858 ompd_rc_t 859 ompd_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 else 885 taskInfo = TValue(context, task_handle->th).cast("kmp_taskdata_t", 0); /*t*/ 886 TValue frame = taskInfo 887 .access("ompt_task_info") // td->ompt_task_info 888 .cast("ompt_task_info_t") 889 .access("frame") // td->ompd_task_info.frame 890 .cast("ompt_frame_t", 0); 891 enter_frame->frame_address.segment = OMPD_SEGMENT_UNSPECIFIED; 892 ret = frame 893 .access("enter_frame") // td->ompt_task_info.frame.enter_frame 894 .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 = frame 902 .access("exit_frame") // td->ompt_task_info.frame.exit_frame 903 .castBase() 904 .getValue(exit_frame->frame_address.address); 905 906 return ret; 907 } 908 909 ompd_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") // td 938 .access("td_flags") // td->td_flags 939 .cast("kmp_tasking_flags_t") 940 .check("tasktype", &val); // td->td_flags.tasktype 941 942 if (ret != ompd_rc_ok) 943 return ret; 944 945 if (val == 1) { // tasktype: explicit = 1, implicit = 0 946 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 976 ompd_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 984 ompd_rc_t 985 ompd_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 1001 ompd_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 format 1013 // <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 block 1019 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 space 1024 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" item 1030 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 the 1045 // smaller subsets of the block, and ctl_vars[block_items-2] points to the 1046 // 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 NULL 1055 ctl_vars[block_items - 1] = NULL; 1056 1057 *control_vars = ctl_vars; 1058 1059 return ompd_rc_ok; 1060 } 1061 1062 ompd_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 first 1069 OMPD_CALLBACK(free_memory, (void *)ctl_vars[0]); 1070 // remove the vector 1071 OMPD_CALLBACK(free_memory, (void *)ctl_vars); 1072 1073 return ompd_rc_ok; 1074 } 1075 1076 /* --- Helper functions ----------------------------------------------------- */ 1077 1078 ompd_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