4 * Created on: Jan 14, 2015
5 * Author: Ignacio Laguna
7 * Contact: ilaguna@llnl.gov
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 //===----------------------------------------------------------------------===//
24 #include "omp-debug.h"
25 #include "TargetValue.h"
27 #include "ompd-private.h"
34 ompd_device_type_sizes_t type_sizes
;
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
;
49 return ompd_rc_bad_input
;
51 ompd_get_api_version(&ompd_version
);
52 if (version
!= ompd_version
)
53 return ompd_rc_unsupported
;
55 TValue::callbacks
= table
;
56 __ompd_init_icvs(table
);
57 __ompd_init_states(table
);
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 */
70 return ompd_rc_bad_input
;
72 return ompd_rc_bad_input
;
74 ompd_rc_t ret
= initTypeSizes(context
);
75 if (ret
!= ompd_rc_ok
)
78 ret
= TValue(context
, "ompd_state")
79 .castBase(ompd_type_long_long
)
80 .getValue(ompd_state
);
81 if (ret
!= ompd_rc_ok
)
83 ret
= callbacks
->alloc_memory(sizeof(ompd_address_space_handle_t
),
85 if (ret
!= ompd_rc_ok
)
90 (*handle
)->context
= context
;
91 (*handle
)->kind
= OMPD_DEVICE_KIND_HOST
;
97 ompd_get_omp_version(ompd_address_space_handle_t
98 *address_space
, /* IN: handle for the address space */
99 ompd_word_t
*version
) {
101 return ompd_rc_stale_handle
;
103 return ompd_rc_bad_input
;
105 ompd_address_space_context_t
*context
= address_space
->context
;
109 return ompd_rc_stale_handle
;
112 return ompd_rc_callback_error
;
115 ret
= TValue(context
, "__kmp_openmp_version")
116 .castBase(ompd_type_int
)
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
) {
126 return ompd_rc_stale_handle
;
128 return ompd_rc_bad_input
;
129 ompd_address_space_context_t
*context
= address_space
->context
;
133 ret
= callbacks
->alloc_memory(10, /* max digit can be store on int*/
134 (void **)&omp_version
);
136 if (ret
!= ompd_rc_ok
)
139 ret
= TValue(context
, "__kmp_openmp_version")
140 .castBase(ompd_type_int
)
142 if (ret
!= ompd_rc_ok
)
145 sprintf(omp_version
, "%ld", ver
);
146 *string
= omp_version
;
150 ompd_rc_t
ompd_rel_address_space_handle(
151 ompd_address_space_handle_t
152 *addr_handle
/* IN: handle for the address space */
155 return ompd_rc_stale_handle
;
157 ompd_rc_t ret
= callbacks
->free_memory((void *)(addr_handle
));
158 // delete addr_handle;
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
,
166 ompd_address_space_handle_t
**device_handle
) {
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
;
190 return ompd_rc_stale_handle
;
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
)
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*/
213 if (ret
!= ompd_rc_ok
)
216 ret
= callbacks
->alloc_memory(sizeof(ompd_thread_handle_t
),
217 (void **)(thread_handle
));
218 if (ret
!= ompd_rc_ok
)
221 (*thread_handle
)->th
= taddr
;
222 (*thread_handle
)->ah
= parallel_handle
->ah
;
226 ompd_rc_t
ompd_rel_thread_handle(
228 *thread_handle
/* IN: OpenMP thread handle to be released */
231 return ompd_rc_stale_handle
;
232 ompd_rc_t ret
= callbacks
->free_memory((void *)(thread_handle
));
233 if (ret
!= 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
,
241 if (!thread_handle_1
)
242 return ompd_rc_stale_handle
;
243 if (!thread_handle_2
)
244 return ompd_rc_stale_handle
;
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
;
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 */
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
;
272 return ompd_rc_callback_error
;
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
)
290 lwt
.segment
= OMPD_SEGMENT_UNSPECIFIED
;
291 ret
= teamdata
.cast("kmp_base_team_t", 0)
292 .access("ompt_serialized_team_info")
294 .getValue(lwt
.address
);
295 if (ret
!= ompd_rc_ok
)
298 ret
= callbacks
->alloc_memory(sizeof(ompd_parallel_handle_t
),
299 (void **)(parallel_handle
));
300 if (ret
!= ompd_rc_ok
)
303 (*parallel_handle
)->ah
= thread_handle
->ah
;
304 (*parallel_handle
)->th
= taddr
;
305 (*parallel_handle
)->lwt
= lwt
;
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
;
321 return ompd_rc_stale_handle
;
324 return ompd_rc_callback_error
;
327 ompd_address_t taddr
= parallel_handle
->th
,
328 lwt
= {OMPD_SEGMENT_UNSPECIFIED
, 0};
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)
337 .cast("ompt_lw_taskteam_t", 1)
341 if (ret
!= ompd_rc_ok
) { // no lwt or parent==0x0
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
)
354 lwt
.segment
= OMPD_SEGMENT_UNSPECIFIED
;
355 ret
= teamdata
.cast("kmp_base_team_t", 0)
356 .access("ompt_serialized_team_info")
358 .getValue(lwt
.address
);
359 if (ret
!= ompd_rc_ok
)
363 ret
= callbacks
->alloc_memory(sizeof(ompd_parallel_handle_t
),
364 (void **)(enclosing_parallel_handle
));
365 if (ret
!= ompd_rc_ok
)
367 (*enclosing_parallel_handle
)->th
= taddr
;
368 (*enclosing_parallel_handle
)->lwt
= lwt
;
369 (*enclosing_parallel_handle
)->ah
= parallel_handle
->ah
;
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 */
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
;
385 return ompd_rc_stale_handle
;
388 return ompd_rc_callback_error
;
391 ompd_address_t taddr
= {OMPD_SEGMENT_UNSPECIFIED
, 0};
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*/
402 if (ret
!= ompd_rc_ok
)
405 ret
= callbacks
->alloc_memory(sizeof(ompd_parallel_handle_t
),
406 (void **)(task_parallel_handle
));
407 if (ret
!= ompd_rc_ok
)
410 (*task_parallel_handle
)->ah
= task_handle
->ah
;
411 (*task_parallel_handle
)->lwt
= task_handle
->lwt
;
412 (*task_parallel_handle
)->th
= taddr
;
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
)
428 ompd_parallel_handle_compare(ompd_parallel_handle_t
*parallel_handle_1
,
429 ompd_parallel_handle_t
*parallel_handle_2
,
431 if (!parallel_handle_1
)
432 return ompd_rc_stale_handle
;
433 if (!parallel_handle_2
)
434 return ompd_rc_stale_handle
;
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
)
442 parallel_handle_1
->th
.address
- parallel_handle_2
->th
.address
;
445 parallel_handle_1
->lwt
.address
- parallel_handle_2
->lwt
.address
;
447 *cmp_value
= parallel_handle_1
->th
.address
- parallel_handle_2
->th
.address
;
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 */
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
;
466 return ompd_rc_stale_handle
;
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
;
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
)
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")
495 .getValue(lwt
.address
);
497 if (ret
!= ompd_rc_ok
)
500 ret
= callbacks
->alloc_memory(sizeof(ompd_task_handle_t
),
501 (void **)(task_handle
));
502 if (ret
!= ompd_rc_ok
)
505 (*task_handle
)->th
= taddr
;
506 (*task_handle
)->lwt
= lwt
;
507 (*task_handle
)->ah
= thread_handle
->ah
;
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 */
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
;
522 return ompd_rc_stale_handle
;
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)
535 .cast("ompt_lw_taskteam_t", 1)
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
)
550 lwt
.segment
= OMPD_SEGMENT_UNSPECIFIED
;
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")
558 .getValue(lwt
.address
);
559 if (ret
!= ompd_rc_ok
)
563 ret
= callbacks
->alloc_memory(sizeof(ompd_task_handle_t
),
564 (void **)(parent_task_handle
));
565 if (ret
!= ompd_rc_ok
)
568 (*parent_task_handle
)->th
= taddr
;
569 (*parent_task_handle
)->lwt
= lwt
;
570 (*parent_task_handle
)->ah
= task_handle
->ah
;
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 */
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
;
584 return ompd_rc_stale_handle
;
587 return ompd_rc_callback_error
;
590 ompd_address_t taddr
= {OMPD_SEGMENT_UNSPECIFIED
, 0};
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)
600 .getValue(taddr
.address
);
601 if (taddr
.address
== 0) {
602 return ompd_rc_unavailable
;
605 if (ret
!= ompd_rc_ok
)
607 ret
= callbacks
->alloc_memory(sizeof(ompd_task_handle_t
),
608 (void **)(parent_task_handle
));
609 if (ret
!= ompd_rc_ok
)
612 (*parent_task_handle
)->th
= taddr
;
613 (*parent_task_handle
)->lwt
= {OMPD_SEGMENT_UNSPECIFIED
, 0};
614 (*parent_task_handle
)->ah
= task_handle
->ah
;
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
;
629 return ompd_rc_stale_handle
;
632 return ompd_rc_callback_error
;
636 ompd_word_t team_size_var
;
637 ret
= ompd_get_num_threads(parallel_handle
, &team_size_var
);
638 if (ret
!= ompd_rc_ok
)
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)
650 thread_num
) /*t.t_implicit_task_taskdata[nth_handle]*/
653 if (ret
!= ompd_rc_ok
)
655 ret
= callbacks
->alloc_memory(sizeof(ompd_task_handle_t
),
656 (void **)(task_handle
));
657 if (ret
!= ompd_rc_ok
)
660 (*task_handle
)->th
= taddr
;
661 (*task_handle
)->ah
= parallel_handle
->ah
;
662 (*task_handle
)->lwt
= {OMPD_SEGMENT_UNSPECIFIED
, 0};
666 ompd_rc_t
ompd_rel_task_handle(
667 ompd_task_handle_t
*task_handle
/* IN: OpenMP 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
)
677 ompd_rc_t
ompd_task_handle_compare(ompd_task_handle_t
*task_handle_1
,
678 ompd_task_handle_t
*task_handle_2
,
681 return ompd_rc_stale_handle
;
683 return ompd_rc_stale_handle
;
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
;
691 *cmp_value
= task_handle_1
->lwt
.address
- task_handle_2
->lwt
.address
;
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
) {
700 return ompd_rc_stale_handle
;
701 ompd_address_space_context_t
*context
= handle
->context
;
705 return ompd_rc_stale_handle
;
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
)
718 ret
= TValue(context
, tcontext
, "__kmp_gtid")
719 .castBase("__kmp_gtid")
721 if (ret
!= ompd_rc_ok
)
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
)
736 ret
= callbacks
->alloc_memory(sizeof(ompd_thread_handle_t
),
737 (void **)(thread_handle
));
738 if (ret
!= ompd_rc_ok
)
740 (*thread_handle
)->ah
= handle
;
741 (*thread_handle
)->th
= taddr
;
744 if (ret
!= ompd_rc_ok
)
748 TBaseValue ds_handle
=
749 th
.cast("kmp_base_info_t")
750 .access("th_info") /*__kmp_threads[t]->th.th_info*/
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*/
757 assert(ompd_rc_ok
== ds_handle
.getValue(oshandle
) &&
758 oshandle
== *(pthread_t
*)(thread_id
) &&
759 "Callback table not initialized!");
762 (*thread_handle
)->thread_context
= tcontext
;
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
;
772 return ompd_rc_bad_input
;
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
;
779 return ompd_rc_stale_handle
;
783 ret
= tf
.getType(context
, "kmp_thread_t").getSize(&size
);
784 if (ret
!= ompd_rc_ok
)
786 if (sizeof_thread_id
!= size
)
787 return ompd_rc_bad_input
;
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*/
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);
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 */
814 return ompd_rc_stale_handle
;
815 if (!thread_handle
->ah
)
816 return ompd_rc_stale_handle
;
818 return ompd_rc_bad_input
;
819 ompd_address_space_context_t
*context
= thread_handle
->ah
->context
;
821 return ompd_rc_stale_handle
;
823 return ompd_rc_needs_state_tracking
;
826 return ompd_rc_callback_error
;
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*/
841 if (ret
!= ompd_rc_ok
)
844 ret
= ompt_thread_info
845 .access("wait_id") /*__kmp_threads[t]->th.ompt_thread_info.state*/
852 /* --- Task Inquiry -------------------------------------------------------- */
854 /* --- Task Settings ------------------------------------------------------- */
856 /* --- OMPT Task Inquiry Analogues ----------------------------------------- */
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
) {
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
;
870 return ompd_rc_stale_handle
;
872 return ompd_rc_needs_state_tracking
;
875 return ompd_rc_callback_error
;
881 if (task_handle
->lwt
.address
!= 0)
883 TValue(context
, task_handle
->lwt
).cast("ompt_lw_taskteam_t", 0); /*lwt*/
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
;
893 .access("enter_frame") // td->ompt_task_info.frame.enter_frame
895 .getValue(enter_frame
->frame_address
.address
);
897 if (ret
!= ompd_rc_ok
)
900 exit_frame
->frame_address
.segment
= OMPD_SEGMENT_UNSPECIFIED
;
902 .access("exit_frame") // td->ompt_task_info.frame.exit_frame
904 .getValue(exit_frame
->frame_address
.address
);
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 */
914 return ompd_rc_stale_handle
;
915 if (!task_handle
->ah
)
916 return ompd_rc_stale_handle
;
918 return ompd_rc_bad_input
;
919 ompd_address_space_context_t
*context
= task_handle
->ah
->context
;
921 return ompd_rc_stale_handle
;
923 return ompd_rc_needs_state_tracking
;
925 return ompd_rc_callback_error
;
930 task_addr
->segment
= OMPD_SEGMENT_UNSPECIFIED
;
932 if (task_handle
->lwt
.address
!= 0)
933 return ompd_rc_bad_input
; // We need to decide what we do here.
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
)
945 if (val
== 1) { // tasktype: explicit = 1, implicit = 0
947 ret
= TValue(context
, task_handle
->th
)
948 .cast("kmp_taskdata_t", 0) /*t*/
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*/
955 .getValue(task_addr
->address
);
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*/
967 .getValue(task_addr
->address
);
974 /* ------- OMPD Version and Compatibility Information ----------------------- */
976 ompd_rc_t
ompd_get_api_version(ompd_word_t
*version
) {
978 return ompd_rc_bad_input
;
980 *version
= OMPD_VERSION
;
985 ompd_get_version_string(const char **string
/* OUT: OMPD version 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(
995 *string
= version_string
;
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
) {
1004 return ompd_rc_stale_handle
;
1006 return ompd_rc_bad_input
;
1008 ompd_address_space_context_t
*context
= handle
->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
),
1023 // copy raw data from the address space
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') {
1037 // create vector of char*
1038 const char **ctl_vars
;
1039 OMPD_CALLBACK(alloc_memory
, block_items
* sizeof(char *),
1040 (void **)(&ctl_vars
));
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
;
1054 // last item must be NULL
1055 ctl_vars
[block_items
- 1] = NULL
;
1057 *control_vars
= ctl_vars
;
1062 ompd_rc_t
ompd_rel_display_control_vars(const char *const **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
);
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
;
1083 ret
= callbacks
->sizeof_type(context
, &type_sizes
);
1084 if (ret
!= ompd_rc_ok
)
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
)