10b57cec5SDimitry Andric /* 20b57cec5SDimitry Andric * ompt-specific.cpp -- OMPT internal functions 30b57cec5SDimitry Andric */ 40b57cec5SDimitry Andric 50b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 80b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 90b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric //****************************************************************************** 140b57cec5SDimitry Andric // include files 150b57cec5SDimitry Andric //****************************************************************************** 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "kmp.h" 180b57cec5SDimitry Andric #include "ompt-specific.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric #if KMP_OS_UNIX 210b57cec5SDimitry Andric #include <dlfcn.h> 220b57cec5SDimitry Andric #endif 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric #if KMP_OS_WINDOWS 250b57cec5SDimitry Andric #define THREAD_LOCAL __declspec(thread) 260b57cec5SDimitry Andric #else 270b57cec5SDimitry Andric #define THREAD_LOCAL __thread 280b57cec5SDimitry Andric #endif 290b57cec5SDimitry Andric 30979e22ffSDimitry Andric #define OMPT_WEAK_ATTRIBUTE KMP_WEAK_ATTRIBUTE_INTERNAL 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric //****************************************************************************** 330b57cec5SDimitry Andric // macros 340b57cec5SDimitry Andric //****************************************************************************** 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric #define LWT_FROM_TEAM(team) (team)->t.ompt_serialized_team_info 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric #define OMPT_THREAD_ID_BITS 16 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric //****************************************************************************** 410b57cec5SDimitry Andric // private operations 420b57cec5SDimitry Andric //****************************************************************************** 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric //---------------------------------------------------------- 450b57cec5SDimitry Andric // traverse the team and task hierarchy 460b57cec5SDimitry Andric // note: __ompt_get_teaminfo and __ompt_get_task_info_object 470b57cec5SDimitry Andric // traverse the hierarchy similarly and need to be 480b57cec5SDimitry Andric // kept consistent 490b57cec5SDimitry Andric //---------------------------------------------------------- 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric ompt_team_info_t *__ompt_get_teaminfo(int depth, int *size) { 520b57cec5SDimitry Andric kmp_info_t *thr = ompt_get_thread(); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric if (thr) { 550b57cec5SDimitry Andric kmp_team *team = thr->th.th_team; 560b57cec5SDimitry Andric if (team == NULL) 570b57cec5SDimitry Andric return NULL; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric ompt_lw_taskteam_t *next_lwt = LWT_FROM_TEAM(team), *lwt = NULL; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric while (depth > 0) { 620b57cec5SDimitry Andric // next lightweight team (if any) 630b57cec5SDimitry Andric if (lwt) 640b57cec5SDimitry Andric lwt = lwt->parent; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric // next heavyweight team (if any) after 670b57cec5SDimitry Andric // lightweight teams are exhausted 680b57cec5SDimitry Andric if (!lwt && team) { 690b57cec5SDimitry Andric if (next_lwt) { 700b57cec5SDimitry Andric lwt = next_lwt; 710b57cec5SDimitry Andric next_lwt = NULL; 720b57cec5SDimitry Andric } else { 730b57cec5SDimitry Andric team = team->t.t_parent; 740b57cec5SDimitry Andric if (team) { 750b57cec5SDimitry Andric next_lwt = LWT_FROM_TEAM(team); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric depth--; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric if (lwt) { 840b57cec5SDimitry Andric // lightweight teams have one task 850b57cec5SDimitry Andric if (size) 860b57cec5SDimitry Andric *size = 1; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric // return team info for lightweight team 890b57cec5SDimitry Andric return &lwt->ompt_team_info; 900b57cec5SDimitry Andric } else if (team) { 910b57cec5SDimitry Andric // extract size from heavyweight team 920b57cec5SDimitry Andric if (size) 930b57cec5SDimitry Andric *size = team->t.t_nproc; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // return team info for heavyweight team 960b57cec5SDimitry Andric return &team->t.ompt_team_info; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric return NULL; 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric ompt_task_info_t *__ompt_get_task_info_object(int depth) { 1040b57cec5SDimitry Andric ompt_task_info_t *info = NULL; 1050b57cec5SDimitry Andric kmp_info_t *thr = ompt_get_thread(); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric if (thr) { 1080b57cec5SDimitry Andric kmp_taskdata_t *taskdata = thr->th.th_current_task; 1090b57cec5SDimitry Andric ompt_lw_taskteam_t *lwt = NULL, 1100b57cec5SDimitry Andric *next_lwt = LWT_FROM_TEAM(taskdata->td_team); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric while (depth > 0) { 1130b57cec5SDimitry Andric // next lightweight team (if any) 1140b57cec5SDimitry Andric if (lwt) 1150b57cec5SDimitry Andric lwt = lwt->parent; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // next heavyweight team (if any) after 1180b57cec5SDimitry Andric // lightweight teams are exhausted 1190b57cec5SDimitry Andric if (!lwt && taskdata) { 1200b57cec5SDimitry Andric if (next_lwt) { 1210b57cec5SDimitry Andric lwt = next_lwt; 1220b57cec5SDimitry Andric next_lwt = NULL; 1230b57cec5SDimitry Andric } else { 1240b57cec5SDimitry Andric taskdata = taskdata->td_parent; 1250b57cec5SDimitry Andric if (taskdata) { 1260b57cec5SDimitry Andric next_lwt = LWT_FROM_TEAM(taskdata->td_team); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric depth--; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric if (lwt) { 1340b57cec5SDimitry Andric info = &lwt->ompt_task_info; 1350b57cec5SDimitry Andric } else if (taskdata) { 1360b57cec5SDimitry Andric info = &taskdata->ompt_task_info; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric return info; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric ompt_task_info_t *__ompt_get_scheduling_taskinfo(int depth) { 1440b57cec5SDimitry Andric ompt_task_info_t *info = NULL; 1450b57cec5SDimitry Andric kmp_info_t *thr = ompt_get_thread(); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric if (thr) { 1480b57cec5SDimitry Andric kmp_taskdata_t *taskdata = thr->th.th_current_task; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric ompt_lw_taskteam_t *lwt = NULL, 1510b57cec5SDimitry Andric *next_lwt = LWT_FROM_TEAM(taskdata->td_team); 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric while (depth > 0) { 1540b57cec5SDimitry Andric // next lightweight team (if any) 1550b57cec5SDimitry Andric if (lwt) 1560b57cec5SDimitry Andric lwt = lwt->parent; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric // next heavyweight team (if any) after 1590b57cec5SDimitry Andric // lightweight teams are exhausted 1600b57cec5SDimitry Andric if (!lwt && taskdata) { 1610b57cec5SDimitry Andric // first try scheduling parent (for explicit task scheduling) 1620b57cec5SDimitry Andric if (taskdata->ompt_task_info.scheduling_parent) { 1630b57cec5SDimitry Andric taskdata = taskdata->ompt_task_info.scheduling_parent; 1640b57cec5SDimitry Andric } else if (next_lwt) { 1650b57cec5SDimitry Andric lwt = next_lwt; 1660b57cec5SDimitry Andric next_lwt = NULL; 1670b57cec5SDimitry Andric } else { 1680b57cec5SDimitry Andric // then go for implicit tasks 1690b57cec5SDimitry Andric taskdata = taskdata->td_parent; 1700b57cec5SDimitry Andric if (taskdata) { 1710b57cec5SDimitry Andric next_lwt = LWT_FROM_TEAM(taskdata->td_team); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric depth--; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric if (lwt) { 1790b57cec5SDimitry Andric info = &lwt->ompt_task_info; 1800b57cec5SDimitry Andric } else if (taskdata) { 1810b57cec5SDimitry Andric info = &taskdata->ompt_task_info; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric return info; 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric //****************************************************************************** 1890b57cec5SDimitry Andric // interface operations 1900b57cec5SDimitry Andric //****************************************************************************** 191bdd1243dSDimitry Andric //---------------------------------------------------------- 192bdd1243dSDimitry Andric // initialization support 193bdd1243dSDimitry Andric //---------------------------------------------------------- 194bdd1243dSDimitry Andric 195bdd1243dSDimitry Andric void __ompt_force_initialization() { __kmp_serial_initialize(); } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric //---------------------------------------------------------- 1980b57cec5SDimitry Andric // thread support 1990b57cec5SDimitry Andric //---------------------------------------------------------- 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric ompt_data_t *__ompt_get_thread_data_internal() { 2020b57cec5SDimitry Andric if (__kmp_get_gtid() >= 0) { 2030b57cec5SDimitry Andric kmp_info_t *thread = ompt_get_thread(); 2040b57cec5SDimitry Andric if (thread == NULL) 2050b57cec5SDimitry Andric return NULL; 2060b57cec5SDimitry Andric return &(thread->th.ompt_thread_info.thread_data); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric return NULL; 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric //---------------------------------------------------------- 2120b57cec5SDimitry Andric // state support 2130b57cec5SDimitry Andric //---------------------------------------------------------- 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric void __ompt_thread_assign_wait_id(void *variable) { 2160b57cec5SDimitry Andric kmp_info_t *ti = ompt_get_thread(); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric if (ti) 2190b57cec5SDimitry Andric ti->th.ompt_thread_info.wait_id = (ompt_wait_id_t)(uintptr_t)variable; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric int __ompt_get_state_internal(ompt_wait_id_t *omp_wait_id) { 2230b57cec5SDimitry Andric kmp_info_t *ti = ompt_get_thread(); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric if (ti) { 2260b57cec5SDimitry Andric if (omp_wait_id) 2270b57cec5SDimitry Andric *omp_wait_id = ti->th.ompt_thread_info.wait_id; 2280b57cec5SDimitry Andric return ti->th.ompt_thread_info.state; 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric return ompt_state_undefined; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric //---------------------------------------------------------- 2340b57cec5SDimitry Andric // parallel region support 2350b57cec5SDimitry Andric //---------------------------------------------------------- 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric int __ompt_get_parallel_info_internal(int ancestor_level, 2380b57cec5SDimitry Andric ompt_data_t **parallel_data, 2390b57cec5SDimitry Andric int *team_size) { 2400b57cec5SDimitry Andric if (__kmp_get_gtid() >= 0) { 2410b57cec5SDimitry Andric ompt_team_info_t *info; 2420b57cec5SDimitry Andric if (team_size) { 2430b57cec5SDimitry Andric info = __ompt_get_teaminfo(ancestor_level, team_size); 2440b57cec5SDimitry Andric } else { 2450b57cec5SDimitry Andric info = __ompt_get_teaminfo(ancestor_level, NULL); 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric if (parallel_data) { 2480b57cec5SDimitry Andric *parallel_data = info ? &(info->parallel_data) : NULL; 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric return info ? 2 : 0; 2510b57cec5SDimitry Andric } else { 2520b57cec5SDimitry Andric return 0; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric //---------------------------------------------------------- 2570b57cec5SDimitry Andric // lightweight task team support 2580b57cec5SDimitry Andric //---------------------------------------------------------- 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid, 2610b57cec5SDimitry Andric ompt_data_t *ompt_pid, void *codeptr) { 2620b57cec5SDimitry Andric // initialize parallel_data with input, return address to parallel_data on 2630b57cec5SDimitry Andric // exit 2640b57cec5SDimitry Andric lwt->ompt_team_info.parallel_data = *ompt_pid; 2650b57cec5SDimitry Andric lwt->ompt_team_info.master_return_address = codeptr; 2660b57cec5SDimitry Andric lwt->ompt_task_info.task_data.value = 0; 2670b57cec5SDimitry Andric lwt->ompt_task_info.frame.enter_frame = ompt_data_none; 2680b57cec5SDimitry Andric lwt->ompt_task_info.frame.exit_frame = ompt_data_none; 2690b57cec5SDimitry Andric lwt->ompt_task_info.scheduling_parent = NULL; 2700b57cec5SDimitry Andric lwt->heap = 0; 2710b57cec5SDimitry Andric lwt->parent = 0; 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, 275489b1cf2SDimitry Andric int on_heap, bool always) { 2760b57cec5SDimitry Andric ompt_lw_taskteam_t *link_lwt = lwt; 277489b1cf2SDimitry Andric if (always || 278489b1cf2SDimitry Andric thr->th.th_team->t.t_serialized > 2790b57cec5SDimitry Andric 1) { // we already have a team, so link the new team and swap values 2800b57cec5SDimitry Andric if (on_heap) { // the lw_taskteam cannot stay on stack, allocate it on heap 2810b57cec5SDimitry Andric link_lwt = 2820b57cec5SDimitry Andric (ompt_lw_taskteam_t *)__kmp_allocate(sizeof(ompt_lw_taskteam_t)); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric link_lwt->heap = on_heap; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric // would be swap in the (on_stack) case. 2870b57cec5SDimitry Andric ompt_team_info_t tmp_team = lwt->ompt_team_info; 2880b57cec5SDimitry Andric link_lwt->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr); 2890b57cec5SDimitry Andric *OMPT_CUR_TEAM_INFO(thr) = tmp_team; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // link the taskteam into the list of taskteams: 2920b57cec5SDimitry Andric ompt_lw_taskteam_t *my_parent = 2930b57cec5SDimitry Andric thr->th.th_team->t.ompt_serialized_team_info; 2940b57cec5SDimitry Andric link_lwt->parent = my_parent; 2950b57cec5SDimitry Andric thr->th.th_team->t.ompt_serialized_team_info = link_lwt; 296fe6060f1SDimitry Andric #if OMPD_SUPPORT 297fe6060f1SDimitry Andric if (ompd_state & OMPD_ENABLE_BP) { 298fe6060f1SDimitry Andric ompd_bp_parallel_begin(); 299fe6060f1SDimitry Andric } 300fe6060f1SDimitry Andric #endif 301349cc55cSDimitry Andric 302349cc55cSDimitry Andric ompt_task_info_t tmp_task = lwt->ompt_task_info; 303349cc55cSDimitry Andric link_lwt->ompt_task_info = *OMPT_CUR_TASK_INFO(thr); 304349cc55cSDimitry Andric *OMPT_CUR_TASK_INFO(thr) = tmp_task; 3050b57cec5SDimitry Andric } else { 3060b57cec5SDimitry Andric // this is the first serialized team, so we just store the values in the 3070b57cec5SDimitry Andric // team and drop the taskteam-object 3080b57cec5SDimitry Andric *OMPT_CUR_TEAM_INFO(thr) = lwt->ompt_team_info; 309fe6060f1SDimitry Andric #if OMPD_SUPPORT 310fe6060f1SDimitry Andric if (ompd_state & OMPD_ENABLE_BP) { 311fe6060f1SDimitry Andric ompd_bp_parallel_begin(); 312fe6060f1SDimitry Andric } 313fe6060f1SDimitry Andric #endif 3140b57cec5SDimitry Andric *OMPT_CUR_TASK_INFO(thr) = lwt->ompt_task_info; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric void __ompt_lw_taskteam_unlink(kmp_info_t *thr) { 3190b57cec5SDimitry Andric ompt_lw_taskteam_t *lwtask = thr->th.th_team->t.ompt_serialized_team_info; 3200b57cec5SDimitry Andric if (lwtask) { 321349cc55cSDimitry Andric ompt_task_info_t tmp_task = lwtask->ompt_task_info; 322349cc55cSDimitry Andric lwtask->ompt_task_info = *OMPT_CUR_TASK_INFO(thr); 323349cc55cSDimitry Andric *OMPT_CUR_TASK_INFO(thr) = tmp_task; 324fe6060f1SDimitry Andric #if OMPD_SUPPORT 325fe6060f1SDimitry Andric if (ompd_state & OMPD_ENABLE_BP) { 326fe6060f1SDimitry Andric ompd_bp_parallel_end(); 327fe6060f1SDimitry Andric } 328fe6060f1SDimitry Andric #endif 3290b57cec5SDimitry Andric thr->th.th_team->t.ompt_serialized_team_info = lwtask->parent; 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric ompt_team_info_t tmp_team = lwtask->ompt_team_info; 3320b57cec5SDimitry Andric lwtask->ompt_team_info = *OMPT_CUR_TEAM_INFO(thr); 3330b57cec5SDimitry Andric *OMPT_CUR_TEAM_INFO(thr) = tmp_team; 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric if (lwtask->heap) { 3360b57cec5SDimitry Andric __kmp_free(lwtask); 3370b57cec5SDimitry Andric lwtask = NULL; 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric // return lwtask; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric //---------------------------------------------------------- 3440b57cec5SDimitry Andric // task support 3450b57cec5SDimitry Andric //---------------------------------------------------------- 3460b57cec5SDimitry Andric 34706c3fb27SDimitry Andric ompt_data_t *__ompt_get_task_data() { 34806c3fb27SDimitry Andric kmp_info_t *thr = ompt_get_thread(); 34906c3fb27SDimitry Andric ompt_data_t *task_data = thr ? OMPT_CUR_TASK_DATA(thr) : NULL; 35006c3fb27SDimitry Andric return task_data; 35106c3fb27SDimitry Andric } 35206c3fb27SDimitry Andric 35306c3fb27SDimitry Andric ompt_data_t *__ompt_get_target_task_data() { 35406c3fb27SDimitry Andric return &__kmp_threads[__kmp_get_gtid()]->th.ompt_thread_info.target_task_data; 35506c3fb27SDimitry Andric } 35606c3fb27SDimitry Andric 3570b57cec5SDimitry Andric int __ompt_get_task_info_internal(int ancestor_level, int *type, 3580b57cec5SDimitry Andric ompt_data_t **task_data, 3590b57cec5SDimitry Andric ompt_frame_t **task_frame, 3600b57cec5SDimitry Andric ompt_data_t **parallel_data, 3610b57cec5SDimitry Andric int *thread_num) { 3620b57cec5SDimitry Andric if (__kmp_get_gtid() < 0) 3630b57cec5SDimitry Andric return 0; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric if (ancestor_level < 0) 3660b57cec5SDimitry Andric return 0; 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric // copied from __ompt_get_scheduling_taskinfo 3690b57cec5SDimitry Andric ompt_task_info_t *info = NULL; 3700b57cec5SDimitry Andric ompt_team_info_t *team_info = NULL; 3710b57cec5SDimitry Andric kmp_info_t *thr = ompt_get_thread(); 3720b57cec5SDimitry Andric int level = ancestor_level; 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric if (thr) { 3750b57cec5SDimitry Andric kmp_taskdata_t *taskdata = thr->th.th_current_task; 3760b57cec5SDimitry Andric if (taskdata == NULL) 3770b57cec5SDimitry Andric return 0; 3780b57cec5SDimitry Andric kmp_team *team = thr->th.th_team, *prev_team = NULL; 3790b57cec5SDimitry Andric if (team == NULL) 3800b57cec5SDimitry Andric return 0; 3810b57cec5SDimitry Andric ompt_lw_taskteam_t *lwt = NULL, 382349cc55cSDimitry Andric *next_lwt = LWT_FROM_TEAM(taskdata->td_team); 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric while (ancestor_level > 0) { 3850b57cec5SDimitry Andric // next lightweight team (if any) 3860b57cec5SDimitry Andric if (lwt) 3870b57cec5SDimitry Andric lwt = lwt->parent; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric // next heavyweight team (if any) after 3900b57cec5SDimitry Andric // lightweight teams are exhausted 3910b57cec5SDimitry Andric if (!lwt && taskdata) { 3920b57cec5SDimitry Andric // first try scheduling parent (for explicit task scheduling) 3930b57cec5SDimitry Andric if (taskdata->ompt_task_info.scheduling_parent) { 3940b57cec5SDimitry Andric taskdata = taskdata->ompt_task_info.scheduling_parent; 3950b57cec5SDimitry Andric } else if (next_lwt) { 3960b57cec5SDimitry Andric lwt = next_lwt; 3970b57cec5SDimitry Andric next_lwt = NULL; 3980b57cec5SDimitry Andric } else { 3990b57cec5SDimitry Andric // then go for implicit tasks 4000b57cec5SDimitry Andric taskdata = taskdata->td_parent; 4010b57cec5SDimitry Andric if (team == NULL) 4020b57cec5SDimitry Andric return 0; 403349cc55cSDimitry Andric prev_team = team; 4040b57cec5SDimitry Andric team = team->t.t_parent; 4050b57cec5SDimitry Andric if (taskdata) { 4060b57cec5SDimitry Andric next_lwt = LWT_FROM_TEAM(taskdata->td_team); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric ancestor_level--; 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric if (lwt) { 4140b57cec5SDimitry Andric info = &lwt->ompt_task_info; 4150b57cec5SDimitry Andric team_info = &lwt->ompt_team_info; 4160b57cec5SDimitry Andric if (type) { 4170b57cec5SDimitry Andric *type = ompt_task_implicit; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric } else if (taskdata) { 4200b57cec5SDimitry Andric info = &taskdata->ompt_task_info; 4210b57cec5SDimitry Andric team_info = &team->t.ompt_team_info; 4220b57cec5SDimitry Andric if (type) { 4230b57cec5SDimitry Andric if (taskdata->td_parent) { 424*0fca6ea1SDimitry Andric *type = TASK_TYPE_DETAILS_FORMAT(taskdata); 4250b57cec5SDimitry Andric } else { 4260b57cec5SDimitry Andric *type = ompt_task_initial; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric if (task_data) { 4310b57cec5SDimitry Andric *task_data = info ? &info->task_data : NULL; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric if (task_frame) { 4340b57cec5SDimitry Andric // OpenMP spec asks for the scheduling task to be returned. 4350b57cec5SDimitry Andric *task_frame = info ? &info->frame : NULL; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric if (parallel_data) { 4380b57cec5SDimitry Andric *parallel_data = team_info ? &(team_info->parallel_data) : NULL; 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric if (thread_num) { 4410b57cec5SDimitry Andric if (level == 0) 4420b57cec5SDimitry Andric *thread_num = __kmp_get_tid(); 443349cc55cSDimitry Andric else if (lwt) 4440b57cec5SDimitry Andric *thread_num = 0; 445349cc55cSDimitry Andric else if (!prev_team) { 446349cc55cSDimitry Andric // The innermost parallel region contains at least one explicit task. 447349cc55cSDimitry Andric // The task at level > 0 is either an implicit task that 448349cc55cSDimitry Andric // corresponds to the mentioned region or one of the explicit tasks 449349cc55cSDimitry Andric // nested inside the same region. Note that the task isn't the 450349cc55cSDimitry Andric // innermost explicit tasks (because of condition level > 0). 451349cc55cSDimitry Andric // Since the task at this level still belongs to the innermost parallel 452349cc55cSDimitry Andric // region, thread_num is determined the same way as for level==0. 453349cc55cSDimitry Andric *thread_num = __kmp_get_tid(); 454349cc55cSDimitry Andric } else 4550b57cec5SDimitry Andric *thread_num = prev_team->t.t_master_tid; 4560b57cec5SDimitry Andric // *thread_num = team->t.t_master_tid; 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric return info ? 2 : 0; 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric return 0; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric int __ompt_get_task_memory_internal(void **addr, size_t *size, int blocknum) { 4645f757f3fSDimitry Andric *size = 0; 4650b57cec5SDimitry Andric if (blocknum != 0) 4660b57cec5SDimitry Andric return 0; // support only a single block 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric kmp_info_t *thr = ompt_get_thread(); 4690b57cec5SDimitry Andric if (!thr) 4700b57cec5SDimitry Andric return 0; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric kmp_taskdata_t *taskdata = thr->th.th_current_task; 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric if (taskdata->td_flags.tasktype != TASK_EXPLICIT) 4750b57cec5SDimitry Andric return 0; // support only explicit task 4760b57cec5SDimitry Andric 4775f757f3fSDimitry Andric *addr = taskdata; 4785f757f3fSDimitry Andric *size = taskdata->td_size_alloc; 4790b57cec5SDimitry Andric return 0; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric //---------------------------------------------------------- 4830b57cec5SDimitry Andric // team support 4840b57cec5SDimitry Andric //---------------------------------------------------------- 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric void __ompt_team_assign_id(kmp_team_t *team, ompt_data_t ompt_pid) { 4870b57cec5SDimitry Andric team->t.ompt_team_info.parallel_data = ompt_pid; 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric //---------------------------------------------------------- 4910b57cec5SDimitry Andric // misc 4920b57cec5SDimitry Andric //---------------------------------------------------------- 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric static uint64_t __ompt_get_unique_id_internal() { 4950b57cec5SDimitry Andric static uint64_t thread = 1; 4960b57cec5SDimitry Andric static THREAD_LOCAL uint64_t ID = 0; 4970b57cec5SDimitry Andric if (ID == 0) { 4980b57cec5SDimitry Andric uint64_t new_thread = KMP_TEST_THEN_INC64((kmp_int64 *)&thread); 4990b57cec5SDimitry Andric ID = new_thread << (sizeof(uint64_t) * 8 - OMPT_THREAD_ID_BITS); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric return ++ID; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric ompt_sync_region_t __ompt_get_barrier_kind(enum barrier_type bt, 5050b57cec5SDimitry Andric kmp_info_t *thr) { 506*0fca6ea1SDimitry Andric if (bt == bs_forkjoin_barrier) { 507*0fca6ea1SDimitry Andric if (thr->th.ompt_thread_info.parallel_flags & ompt_parallel_league) 508*0fca6ea1SDimitry Andric return ompt_sync_region_barrier_teams; 509*0fca6ea1SDimitry Andric else 510*0fca6ea1SDimitry Andric return ompt_sync_region_barrier_implicit_parallel; 511*0fca6ea1SDimitry Andric } 5120b57cec5SDimitry Andric 513*0fca6ea1SDimitry Andric if (bt != bs_plain_barrier || !thr->th.th_ident) 5140b57cec5SDimitry Andric return ompt_sync_region_barrier_implementation; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric kmp_int32 flags = thr->th.th_ident->flags; 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric if ((flags & KMP_IDENT_BARRIER_EXPL) != 0) 5190b57cec5SDimitry Andric return ompt_sync_region_barrier_explicit; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric if ((flags & KMP_IDENT_BARRIER_IMPL) != 0) 522*0fca6ea1SDimitry Andric return ompt_sync_region_barrier_implicit_workshare; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric return ompt_sync_region_barrier_implementation; 5250b57cec5SDimitry Andric } 526