[memprof] Use a new constructor of IndexedAllocationInfo (NFC) (#116920)
[llvm-project.git] / openmp / libompd / src / omp-debug.cpp
blob0532ca30e249ca5883ff3d5d14bb9a48ac0c132d
1 /*
2 * omp-debug.cpp
4 * Created on: Jan 14, 2015
5 * Author: Ignacio Laguna
6 * Joachim Protze
7 * Contact: ilaguna@llnl.gov
8 * protze@llnl.gov
9 */
10 /*******************************************************************************
11 * This implements an OMPD DLL for the LLVM OpenMP runtime library.
14 //===----------------------------------------------------------------------===//
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
20 //===----------------------------------------------------------------------===//
22 #define NDEBUG 1
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>
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 */);
40 /* --- OMPD functions ------------------------------------------------------- */
42 /* --- Initialization ------------------------------------------------------- */
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;
48 if (!table)
49 return ompd_rc_bad_input;
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);
59 return ret;
62 ompd_rc_t ompd_finalize(void) { return ompd_rc_ok; }
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;
74 ompd_rc_t ret = initTypeSizes(context);
75 if (ret != ompd_rc_ok)
76 return ret;
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;
90 (*handle)->context = context;
91 (*handle)->kind = OMPD_DEVICE_KIND_HOST;
93 return ompd_rc_ok;
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;
105 ompd_address_space_context_t *context = address_space->context;
106 ompd_rc_t ret;
108 if (!context)
109 return ompd_rc_stale_handle;
111 if (!callbacks) {
112 return ompd_rc_callback_error;
115 ret = TValue(context, "__kmp_openmp_version")
116 .castBase(ompd_type_int)
117 .getValue(*version);
118 return ret;
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);
136 if (ret != ompd_rc_ok)
137 return ret;
139 ret = TValue(context, "__kmp_openmp_version")
140 .castBase(ompd_type_int)
141 .getValue(ver);
142 if (ret != ompd_rc_ok)
143 return ret;
145 sprintf(omp_version, "%ld", ver);
146 *string = omp_version;
147 return ret;
150 ompd_rc_t ompd_rel_address_space_handle(
151 ompd_address_space_handle_t
152 *addr_handle /* IN: handle for the address space */
154 if (!addr_handle)
155 return ompd_rc_stale_handle;
157 ompd_rc_t ret = callbacks->free_memory((void *)(addr_handle));
158 // delete addr_handle;
159 return ret;
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;
170 return ompd_rc_unavailable;
173 /* --- Thread Handles ------------------------------------------------------- */
175 /* thread_handle is of type (kmp_base_info_t) */
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 */
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;
189 if (!context)
190 return ompd_rc_stale_handle;
192 if (!callbacks) {
193 return ompd_rc_callback_error;
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;
203 ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};
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);
213 if (ret != ompd_rc_ok)
214 return ret;
216 ret = callbacks->alloc_memory(sizeof(ompd_thread_handle_t),
217 (void **)(thread_handle));
218 if (ret != ompd_rc_ok)
219 return ret;
221 (*thread_handle)->th = taddr;
222 (*thread_handle)->ah = parallel_handle->ah;
223 return ret;
226 ompd_rc_t ompd_rel_thread_handle(
227 ompd_thread_handle_t
228 *thread_handle /* IN: OpenMP thread handle to be released */
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;
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;
251 return ompd_rc_ok;
254 /* --- Parallel Region Handles----------------------------------------------- */
256 /* parallel_handle is of type (kmp_base_team_t)*/
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 */
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;
271 if (!callbacks) {
272 return ompd_rc_callback_error;
275 ompd_rc_t ret;
277 ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0},
278 lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};
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*/
286 ret = teamdata.getAddress(&taddr);
287 if (ret != ompd_rc_ok)
288 return ret;
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;
298 ret = callbacks->alloc_memory(sizeof(ompd_parallel_handle_t),
299 (void **)(parallel_handle));
300 if (ret != ompd_rc_ok)
301 return ret;
303 (*parallel_handle)->ah = thread_handle->ah;
304 (*parallel_handle)->th = taddr;
305 (*parallel_handle)->lwt = lwt;
306 return ompd_rc_ok;
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 */
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;
320 if (!context)
321 return ompd_rc_stale_handle;
323 if (!callbacks) {
324 return ompd_rc_callback_error;
327 ompd_address_t taddr = parallel_handle->th,
328 lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};
329 ompd_rc_t ret;
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);
341 if (ret != ompd_rc_ok) { // no lwt or parent==0x0
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*/
350 ret = teamdata.getAddress(&taddr);
351 if (ret != ompd_rc_ok)
352 return ret;
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;
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;
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 */
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;
384 if (!context)
385 return ompd_rc_stale_handle;
387 if (!callbacks) {
388 return ompd_rc_callback_error;
391 ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};
393 ompd_rc_t ret;
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);
402 if (ret != ompd_rc_ok)
403 return ret;
405 ret = callbacks->alloc_memory(sizeof(ompd_parallel_handle_t),
406 (void **)(task_parallel_handle));
407 if (ret != ompd_rc_ok)
408 return ret;
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;
416 ompd_rc_t ompd_rel_parallel_handle(
417 ompd_parallel_handle_t *parallel_handle /* IN: OpenMP parallel handle */
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;
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;
449 return ompd_rc_ok;
452 /* ------- Task Handles ----------------------------------------------------- */
454 /* task_handle is of type (kmp_taskdata_t) */
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 */
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;
468 if (!callbacks) {
469 return ompd_rc_callback_error;
472 ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0},
473 lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};
474 ompd_rc_t ret = ompd_rc_ok;
476 lwt.segment = OMPD_SEGMENT_UNSPECIFIED;
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);
484 ret = taskdata.dereference().getAddress(&taddr);
485 if (ret != ompd_rc_ok)
486 return ret;
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);
497 if (ret != ompd_rc_ok)
498 return ret;
500 ret = callbacks->alloc_memory(sizeof(ompd_task_handle_t),
501 (void **)(task_handle));
502 if (ret != ompd_rc_ok)
503 return ret;
505 (*task_handle)->th = taddr;
506 (*task_handle)->lwt = lwt;
507 (*task_handle)->ah = thread_handle->ah;
508 return ompd_rc_ok;
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 */
515 if (!task_handle)
516 return ompd_rc_stale_handle;
517 if (!task_handle->ah)
518 return ompd_rc_stale_handle;
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;
527 ompd_address_t taddr = task_handle->th, lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};
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);
539 if (ret != ompd_rc_ok) { // no lwt or parent==0x0
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);
546 ret = taskdata.dereference().getAddress(&taddr);
547 if (ret != ompd_rc_ok)
548 return ret;
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;
563 ret = callbacks->alloc_memory(sizeof(ompd_task_handle_t),
564 (void **)(parent_task_handle));
565 if (ret != ompd_rc_ok)
566 return ret;
568 (*parent_task_handle)->th = taddr;
569 (*parent_task_handle)->lwt = lwt;
570 (*parent_task_handle)->ah = task_handle->ah;
571 return ret;
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 */
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;
586 if (!callbacks) {
587 return ompd_rc_callback_error;
590 ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};
591 ompd_rc_t ret;
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;
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;
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;
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 */
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;
631 if (!callbacks) {
632 return ompd_rc_callback_error;
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;
643 ompd_address_t taddr = {OMPD_SEGMENT_UNSPECIFIED, 0};
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);
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;
660 (*task_handle)->th = taddr;
661 (*task_handle)->ah = parallel_handle->ah;
662 (*task_handle)->lwt = {OMPD_SEGMENT_UNSPECIFIED, 0};
663 return ret;
666 ompd_rc_t ompd_rel_task_handle(
667 ompd_task_handle_t *task_handle /* IN: OpenMP task handle */
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;
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;
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;
704 if (!context)
705 return ompd_rc_stale_handle;
707 if (!callbacks) {
708 return ompd_rc_callback_error;
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;
716 int tId;
718 ret = TValue(context, tcontext, "__kmp_gtid")
719 .castBase("__kmp_gtid")
720 .getValue(tId);
721 if (ret != ompd_rc_ok)
722 return ret;
724 if (tId < 0) // thread is no omp worker
725 return ompd_rc_unavailable;
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*/
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;
743 #ifndef NDEBUG
744 if (ret != ompd_rc_ok)
745 return ret;
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();
757 assert(ompd_rc_ok == ds_handle.getValue(oshandle) &&
758 oshandle == *(pthread_t *)(thread_id) &&
759 "Callback table not initialized!");
760 #endif
762 (*thread_handle)->thread_context = tcontext;
763 return ret;
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;
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;
789 if (!callbacks) {
790 return ompd_rc_callback_error;
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);
803 return ret;
806 /* --- OMPT Thread State Inquiry Analogue ----------------------------------- */
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 */
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;
825 if (!callbacks) {
826 return ompd_rc_callback_error;
828 ompd_rc_t ret;
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);
849 return ret;
852 /* --- Task Inquiry -------------------------------------------------------- */
854 /* --- Task Settings ------------------------------------------------------- */
856 /* --- OMPT Task Inquiry Analogues ----------------------------------------- */
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;
874 if (!callbacks) {
875 return ompd_rc_callback_error;
878 ompd_rc_t ret;
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);
897 if (ret != ompd_rc_ok)
898 return ret;
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);
906 return ret;
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 */
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;
928 ompd_rc_t ret;
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
942 if (ret != ompd_rc_ok)
943 return ret;
945 if (val == 1) { // tasktype: explicit = 1, implicit = 0
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);
957 } else {
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);
971 return ret;
974 /* ------- OMPD Version and Compatibility Information ----------------------- */
976 ompd_rc_t ompd_get_api_version(ompd_word_t *version) {
977 if (!version)
978 return ompd_rc_bad_input;
980 *version = OMPD_VERSION;
981 return ompd_rc_ok;
984 ompd_rc_t
985 ompd_get_version_string(const char **string /* OUT: OMPD version string */
987 if (!string)
988 return ompd_rc_bad_input;
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;
999 /* ------ Display Control Variables ----------------------------------------- */
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;
1008 ompd_address_space_context_t *context = handle->context;
1009 if (!context)
1010 return ompd_rc_stale_handle;
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);
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);
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);
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';
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;
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')
1050 if (pos > block + block_size)
1051 return ompd_rc_error;
1052 ctl_vars[i] = pos;
1054 // last item must be NULL
1055 ctl_vars[block_items - 1] = NULL;
1057 *control_vars = ctl_vars;
1059 return ompd_rc_ok;
1062 ompd_rc_t ompd_rel_display_control_vars(const char *const **control_vars) {
1063 if (!control_vars)
1064 return ompd_rc_bad_input;
1066 char **ctl_vars = const_cast<char **>(*control_vars);
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);
1073 return ompd_rc_ok;
1076 /* --- Helper functions ----------------------------------------------------- */
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;