151c0b2f7Stbbdev /*
2*c21e688aSSergey Zheltov Copyright (c) 2005-2022 Intel Corporation
351c0b2f7Stbbdev
451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev you may not use this file except in compliance with the License.
651c0b2f7Stbbdev You may obtain a copy of the License at
751c0b2f7Stbbdev
851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev
1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev See the License for the specific language governing permissions and
1451c0b2f7Stbbdev limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev
1749e08aacStbbdev #include "oneapi/tbb/detail/_config.h"
1849e08aacStbbdev #include "oneapi/tbb/detail/_template_helpers.h"
1951c0b2f7Stbbdev
2051c0b2f7Stbbdev #include "main.h"
2151c0b2f7Stbbdev #include "itt_notify.h"
2251c0b2f7Stbbdev
2349e08aacStbbdev #include "oneapi/tbb/profiling.h"
2451c0b2f7Stbbdev
2551c0b2f7Stbbdev #include <string.h>
2651c0b2f7Stbbdev
2751c0b2f7Stbbdev namespace tbb {
2851c0b2f7Stbbdev namespace detail {
2951c0b2f7Stbbdev namespace r1 {
3051c0b2f7Stbbdev
3151c0b2f7Stbbdev #if __TBB_USE_ITT_NOTIFY
3251c0b2f7Stbbdev bool ITT_Present;
3351c0b2f7Stbbdev static std::atomic<bool> ITT_InitializationDone;
3451c0b2f7Stbbdev
3551c0b2f7Stbbdev static __itt_domain *tbb_domains[d1::ITT_NUM_DOMAINS] = {};
3651c0b2f7Stbbdev
3751c0b2f7Stbbdev struct resource_string {
3851c0b2f7Stbbdev const char *str;
3951c0b2f7Stbbdev __itt_string_handle *itt_str_handle;
4051c0b2f7Stbbdev };
4151c0b2f7Stbbdev
4251c0b2f7Stbbdev //
4351c0b2f7Stbbdev // populate resource strings
4451c0b2f7Stbbdev //
4551c0b2f7Stbbdev #define TBB_STRING_RESOURCE( index_name, str ) { str, nullptr },
4651c0b2f7Stbbdev static resource_string strings_for_itt[] = {
4749e08aacStbbdev #include "oneapi/tbb/detail/_string_resource.h"
4851c0b2f7Stbbdev { "num_resource_strings", nullptr }
4951c0b2f7Stbbdev };
5051c0b2f7Stbbdev #undef TBB_STRING_RESOURCE
5151c0b2f7Stbbdev
ITT_get_string_handle(std::uintptr_t idx)5251c0b2f7Stbbdev static __itt_string_handle* ITT_get_string_handle(std::uintptr_t idx) {
5351c0b2f7Stbbdev __TBB_ASSERT(idx < NUM_STRINGS, "string handle out of valid range");
5457f524caSIlya Isaev return idx < NUM_STRINGS ? strings_for_itt[idx].itt_str_handle : nullptr;
5551c0b2f7Stbbdev }
5651c0b2f7Stbbdev
ITT_init_domains()5751c0b2f7Stbbdev static void ITT_init_domains() {
5851c0b2f7Stbbdev tbb_domains[d1::ITT_DOMAIN_MAIN] = __itt_domain_create( _T("tbb") );
5951c0b2f7Stbbdev tbb_domains[d1::ITT_DOMAIN_MAIN]->flags = 1;
6051c0b2f7Stbbdev tbb_domains[d1::ITT_DOMAIN_FLOW] = __itt_domain_create( _T("tbb.flow") );
6151c0b2f7Stbbdev tbb_domains[d1::ITT_DOMAIN_FLOW]->flags = 1;
6251c0b2f7Stbbdev tbb_domains[d1::ITT_DOMAIN_ALGO] = __itt_domain_create( _T("tbb.algorithm") );
6351c0b2f7Stbbdev tbb_domains[d1::ITT_DOMAIN_ALGO]->flags = 1;
6451c0b2f7Stbbdev }
6551c0b2f7Stbbdev
ITT_init_strings()6651c0b2f7Stbbdev static void ITT_init_strings() {
6751c0b2f7Stbbdev for ( std::uintptr_t i = 0; i < NUM_STRINGS; ++i ) {
6851c0b2f7Stbbdev #if _WIN32||_WIN64
6951c0b2f7Stbbdev strings_for_itt[i].itt_str_handle = __itt_string_handle_createA( strings_for_itt[i].str );
7051c0b2f7Stbbdev #else
7151c0b2f7Stbbdev strings_for_itt[i].itt_str_handle = __itt_string_handle_create( strings_for_itt[i].str );
7251c0b2f7Stbbdev #endif
7351c0b2f7Stbbdev }
7451c0b2f7Stbbdev }
7551c0b2f7Stbbdev
ITT_init()7651c0b2f7Stbbdev static void ITT_init() {
7751c0b2f7Stbbdev ITT_init_domains();
7851c0b2f7Stbbdev ITT_init_strings();
7951c0b2f7Stbbdev }
8051c0b2f7Stbbdev
8151c0b2f7Stbbdev /** Thread-unsafe lazy one-time initialization of tools interop.
8251c0b2f7Stbbdev Used by both dummy handlers and general TBB one-time initialization routine. **/
ITT_DoUnsafeOneTimeInitialization()8351c0b2f7Stbbdev void ITT_DoUnsafeOneTimeInitialization () {
8451c0b2f7Stbbdev // Double check ITT_InitializationDone is necessary because the first check
8551c0b2f7Stbbdev // in ITT_DoOneTimeInitialization is not guarded with the __TBB_InitOnce lock.
8651c0b2f7Stbbdev if ( !ITT_InitializationDone ) {
8751c0b2f7Stbbdev ITT_Present = (__TBB_load_ittnotify()!=0);
8851c0b2f7Stbbdev if (ITT_Present) ITT_init();
8951c0b2f7Stbbdev ITT_InitializationDone = true;
9051c0b2f7Stbbdev }
9151c0b2f7Stbbdev }
9251c0b2f7Stbbdev
9351c0b2f7Stbbdev /** Thread-safe lazy one-time initialization of tools interop.
9451c0b2f7Stbbdev Used by dummy handlers only. **/
9551c0b2f7Stbbdev extern "C"
ITT_DoOneTimeInitialization()9651c0b2f7Stbbdev void ITT_DoOneTimeInitialization() {
9751c0b2f7Stbbdev if ( !ITT_InitializationDone ) {
9851c0b2f7Stbbdev __TBB_InitOnce::lock();
9951c0b2f7Stbbdev ITT_DoUnsafeOneTimeInitialization();
10051c0b2f7Stbbdev __TBB_InitOnce::unlock();
10151c0b2f7Stbbdev }
10251c0b2f7Stbbdev }
10351c0b2f7Stbbdev
create_itt_sync(void * ptr,const tchar * objtype,const tchar * objname)10451c0b2f7Stbbdev void create_itt_sync(void* ptr, const tchar* objtype, const tchar* objname) {
10551c0b2f7Stbbdev ITT_SYNC_CREATE(ptr, objtype, objname);
10651c0b2f7Stbbdev }
10751c0b2f7Stbbdev
call_itt_notify(int t,void * ptr)10851c0b2f7Stbbdev void call_itt_notify(int t, void *ptr) {
10951c0b2f7Stbbdev switch (t) {
11051c0b2f7Stbbdev case 0: ITT_NOTIFY(sync_prepare, ptr); break;
11151c0b2f7Stbbdev case 1: ITT_NOTIFY(sync_cancel, ptr); break;
11251c0b2f7Stbbdev case 2: ITT_NOTIFY(sync_acquired, ptr); break;
11351c0b2f7Stbbdev case 3: ITT_NOTIFY(sync_releasing, ptr); break;
11451c0b2f7Stbbdev case 4: ITT_NOTIFY(sync_destroy, ptr); break;
11551c0b2f7Stbbdev }
11651c0b2f7Stbbdev }
11751c0b2f7Stbbdev
itt_set_sync_name(void * obj,const tchar * name)11851c0b2f7Stbbdev void itt_set_sync_name(void* obj, const tchar* name) {
11951c0b2f7Stbbdev __itt_sync_rename(obj, name);
12051c0b2f7Stbbdev }
12151c0b2f7Stbbdev
12251c0b2f7Stbbdev const __itt_id itt_null_id = { 0, 0, 0 };
12351c0b2f7Stbbdev
get_itt_domain(d1::itt_domain_enum idx)12451c0b2f7Stbbdev static inline __itt_domain* get_itt_domain(d1::itt_domain_enum idx) {
12557f524caSIlya Isaev if (tbb_domains[idx] == nullptr) {
12651c0b2f7Stbbdev ITT_DoOneTimeInitialization();
12751c0b2f7Stbbdev }
12851c0b2f7Stbbdev return tbb_domains[idx];
12951c0b2f7Stbbdev }
13051c0b2f7Stbbdev
itt_id_make(__itt_id * id,void * addr,unsigned long long extra)13151c0b2f7Stbbdev static inline void itt_id_make(__itt_id* id, void* addr, unsigned long long extra) {
13251c0b2f7Stbbdev *id = __itt_id_make(addr, extra);
13351c0b2f7Stbbdev }
13451c0b2f7Stbbdev
itt_id_create(const __itt_domain * domain,__itt_id id)13551c0b2f7Stbbdev static inline void itt_id_create(const __itt_domain* domain, __itt_id id) {
13651c0b2f7Stbbdev __itt_id_create(domain, id);
13751c0b2f7Stbbdev }
13851c0b2f7Stbbdev
itt_make_task_group(d1::itt_domain_enum domain,void * group,unsigned long long group_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)13951c0b2f7Stbbdev void itt_make_task_group(d1::itt_domain_enum domain, void* group, unsigned long long group_extra,
14051c0b2f7Stbbdev void* parent, unsigned long long parent_extra, string_resource_index name_index) {
14151c0b2f7Stbbdev if (__itt_domain* d = get_itt_domain(domain)) {
14251c0b2f7Stbbdev __itt_id group_id = itt_null_id;
14351c0b2f7Stbbdev __itt_id parent_id = itt_null_id;
14451c0b2f7Stbbdev itt_id_make(&group_id, group, group_extra);
14551c0b2f7Stbbdev itt_id_create(d, group_id);
14651c0b2f7Stbbdev if (parent) {
14751c0b2f7Stbbdev itt_id_make(&parent_id, parent, parent_extra);
14851c0b2f7Stbbdev }
14951c0b2f7Stbbdev __itt_string_handle* n = ITT_get_string_handle(name_index);
15051c0b2f7Stbbdev __itt_task_group(d, group_id, parent_id, n);
15151c0b2f7Stbbdev }
15251c0b2f7Stbbdev }
15351c0b2f7Stbbdev
itt_metadata_str_add(d1::itt_domain_enum domain,void * addr,unsigned long long addr_extra,string_resource_index key,const char * value)15451c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_metadata_str_add(d1::itt_domain_enum domain, void *addr, unsigned long long addr_extra,
15551c0b2f7Stbbdev string_resource_index key, const char *value ) {
15651c0b2f7Stbbdev if ( __itt_domain *d = get_itt_domain( domain ) ) {
15751c0b2f7Stbbdev __itt_id id = itt_null_id;
15851c0b2f7Stbbdev itt_id_make( &id, addr, addr_extra );
15951c0b2f7Stbbdev __itt_string_handle *k = ITT_get_string_handle(key);
16051c0b2f7Stbbdev size_t value_length = strlen( value );
16151c0b2f7Stbbdev #if _WIN32||_WIN64
16251c0b2f7Stbbdev __itt_metadata_str_addA(d, id, k, value, value_length);
16351c0b2f7Stbbdev #else
16451c0b2f7Stbbdev __itt_metadata_str_add(d, id, k, value, value_length);
16551c0b2f7Stbbdev #endif
16651c0b2f7Stbbdev }
16751c0b2f7Stbbdev }
16851c0b2f7Stbbdev
itt_metadata_ptr_add(d1::itt_domain_enum domain,void * addr,unsigned long long addr_extra,string_resource_index key,void * value)16951c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_metadata_ptr_add(d1::itt_domain_enum domain, void *addr, unsigned long long addr_extra,
17051c0b2f7Stbbdev string_resource_index key, void *value ) {
17151c0b2f7Stbbdev if ( __itt_domain *d = get_itt_domain( domain ) ) {
17251c0b2f7Stbbdev __itt_id id = itt_null_id;
17351c0b2f7Stbbdev itt_id_make( &id, addr, addr_extra );
17451c0b2f7Stbbdev __itt_string_handle *k = ITT_get_string_handle(key);
17551c0b2f7Stbbdev #if __TBB_x86_32
17651c0b2f7Stbbdev __itt_metadata_add(d, id, k, __itt_metadata_u32, 1, value);
17751c0b2f7Stbbdev #else
17851c0b2f7Stbbdev __itt_metadata_add(d, id, k, __itt_metadata_u64, 1, value);
17951c0b2f7Stbbdev #endif
18051c0b2f7Stbbdev }
18151c0b2f7Stbbdev }
18251c0b2f7Stbbdev
itt_relation_add(d1::itt_domain_enum domain,void * addr0,unsigned long long addr0_extra,itt_relation relation,void * addr1,unsigned long long addr1_extra)18351c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_relation_add(d1::itt_domain_enum domain, void *addr0, unsigned long long addr0_extra,
18451c0b2f7Stbbdev itt_relation relation, void *addr1, unsigned long long addr1_extra ) {
18551c0b2f7Stbbdev if ( __itt_domain *d = get_itt_domain( domain ) ) {
18651c0b2f7Stbbdev __itt_id id0 = itt_null_id;
18751c0b2f7Stbbdev __itt_id id1 = itt_null_id;
18851c0b2f7Stbbdev itt_id_make( &id0, addr0, addr0_extra );
18951c0b2f7Stbbdev itt_id_make( &id1, addr1, addr1_extra );
19051c0b2f7Stbbdev __itt_relation_add( d, id0, (__itt_relation)relation, id1 );
19151c0b2f7Stbbdev }
19251c0b2f7Stbbdev }
19351c0b2f7Stbbdev
itt_task_begin(d1::itt_domain_enum domain,void * task,unsigned long long task_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)19451c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_task_begin(d1::itt_domain_enum domain, void* task, unsigned long long task_extra,
19551c0b2f7Stbbdev void* parent, unsigned long long parent_extra, string_resource_index name_index) {
19651c0b2f7Stbbdev if (__itt_domain* d = get_itt_domain(domain)) {
19751c0b2f7Stbbdev __itt_id task_id = itt_null_id;
19851c0b2f7Stbbdev __itt_id parent_id = itt_null_id;
19951c0b2f7Stbbdev if (task) {
20051c0b2f7Stbbdev itt_id_make(&task_id, task, task_extra);
20151c0b2f7Stbbdev }
20251c0b2f7Stbbdev if (parent) {
20351c0b2f7Stbbdev itt_id_make(&parent_id, parent, parent_extra);
20451c0b2f7Stbbdev }
20551c0b2f7Stbbdev __itt_string_handle* n = ITT_get_string_handle(name_index);
20651c0b2f7Stbbdev __itt_task_begin(d, task_id, parent_id, n);
20751c0b2f7Stbbdev }
20851c0b2f7Stbbdev }
20951c0b2f7Stbbdev
itt_task_end(d1::itt_domain_enum domain)21051c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_task_end(d1::itt_domain_enum domain) {
21151c0b2f7Stbbdev if (__itt_domain* d = get_itt_domain(domain)) {
21251c0b2f7Stbbdev __itt_task_end(d);
21351c0b2f7Stbbdev }
21451c0b2f7Stbbdev }
21551c0b2f7Stbbdev
itt_region_begin(d1::itt_domain_enum domain,void * region,unsigned long long region_extra,void * parent,unsigned long long parent_extra,string_resource_index)21651c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_region_begin(d1::itt_domain_enum domain, void *region, unsigned long long region_extra,
21751c0b2f7Stbbdev void *parent, unsigned long long parent_extra, string_resource_index /* name_index */ ) {
21851c0b2f7Stbbdev if ( __itt_domain *d = get_itt_domain( domain ) ) {
21951c0b2f7Stbbdev __itt_id region_id = itt_null_id;
22051c0b2f7Stbbdev __itt_id parent_id = itt_null_id;
22151c0b2f7Stbbdev itt_id_make( ®ion_id, region, region_extra );
22251c0b2f7Stbbdev if ( parent ) {
22351c0b2f7Stbbdev itt_id_make( &parent_id, parent, parent_extra );
22451c0b2f7Stbbdev }
22557f524caSIlya Isaev __itt_region_begin( d, region_id, parent_id, nullptr );
22651c0b2f7Stbbdev }
22751c0b2f7Stbbdev }
22851c0b2f7Stbbdev
itt_region_end(d1::itt_domain_enum domain,void * region,unsigned long long region_extra)22951c0b2f7Stbbdev void __TBB_EXPORTED_FUNC itt_region_end(d1::itt_domain_enum domain, void *region, unsigned long long region_extra ) {
23051c0b2f7Stbbdev if ( __itt_domain *d = get_itt_domain( domain ) ) {
23151c0b2f7Stbbdev __itt_id region_id = itt_null_id;
23251c0b2f7Stbbdev itt_id_make( ®ion_id, region, region_extra );
23351c0b2f7Stbbdev __itt_region_end( d, region_id );
23451c0b2f7Stbbdev }
23551c0b2f7Stbbdev }
23651c0b2f7Stbbdev
23751c0b2f7Stbbdev #else
23851c0b2f7Stbbdev void create_itt_sync(void* /*ptr*/, const tchar* /*objtype*/, const tchar* /*objname*/) {}
23951c0b2f7Stbbdev void call_itt_notify(int /*t*/, void* /*ptr*/) {}
24051c0b2f7Stbbdev void itt_set_sync_name(void* /*obj*/, const tchar* /*name*/) {}
24151c0b2f7Stbbdev void itt_make_task_group(d1::itt_domain_enum /*domain*/, void* /*group*/, unsigned long long /*group_extra*/,
24251c0b2f7Stbbdev void* /*parent*/, unsigned long long /*parent_extra*/, string_resource_index /*name_index*/) {}
24351c0b2f7Stbbdev void itt_metadata_str_add(d1::itt_domain_enum /*domain*/, void* /*addr*/, unsigned long long /*addr_extra*/,
24451c0b2f7Stbbdev string_resource_index /*key*/, const char* /*value*/ ) { }
24551c0b2f7Stbbdev void itt_metadata_ptr_add(d1::itt_domain_enum /*domain*/, void * /*addr*/, unsigned long long /*addr_extra*/,
24651c0b2f7Stbbdev string_resource_index /*key*/, void * /*value*/ ) {}
24751c0b2f7Stbbdev void itt_relation_add(d1::itt_domain_enum /*domain*/, void* /*addr0*/, unsigned long long /*addr0_extra*/,
24851c0b2f7Stbbdev itt_relation /*relation*/, void* /*addr1*/, unsigned long long /*addr1_extra*/ ) { }
24951c0b2f7Stbbdev void itt_task_begin(d1::itt_domain_enum /*domain*/, void* /*task*/, unsigned long long /*task_extra*/,
25051c0b2f7Stbbdev void* /*parent*/, unsigned long long /*parent_extra*/, string_resource_index /*name_index*/ ) { }
25151c0b2f7Stbbdev void itt_task_end(d1::itt_domain_enum /*domain*/ ) { }
25251c0b2f7Stbbdev void itt_region_begin(d1::itt_domain_enum /*domain*/, void* /*region*/, unsigned long long /*region_extra*/,
25351c0b2f7Stbbdev void* /*parent*/, unsigned long long /*parent_extra*/, string_resource_index /*name_index*/ ) { }
25451c0b2f7Stbbdev void itt_region_end(d1::itt_domain_enum /*domain*/, void* /*region*/, unsigned long long /*region_extra*/ ) { }
25551c0b2f7Stbbdev #endif /* __TBB_USE_ITT_NOTIFY */
25651c0b2f7Stbbdev
25751c0b2f7Stbbdev const tchar
25851c0b2f7Stbbdev *SyncType_Scheduler = _T("%Constant")
25951c0b2f7Stbbdev ;
26051c0b2f7Stbbdev const tchar
26151c0b2f7Stbbdev *SyncObj_ContextsList = _T("TBB Scheduler")
26251c0b2f7Stbbdev ;
26351c0b2f7Stbbdev } // namespace r1
26451c0b2f7Stbbdev } // namespace detail
26551c0b2f7Stbbdev } // namespace tbb
266