149e08aacStbbdev /* 2*0cf592bdSAndrew Corrigan Copyright (c) 2005-2023 Intel Corporation 349e08aacStbbdev 449e08aacStbbdev Licensed under the Apache License, Version 2.0 (the "License"); 549e08aacStbbdev you may not use this file except in compliance with the License. 649e08aacStbbdev You may obtain a copy of the License at 749e08aacStbbdev 849e08aacStbbdev http://www.apache.org/licenses/LICENSE-2.0 949e08aacStbbdev 1049e08aacStbbdev Unless required by applicable law or agreed to in writing, software 1149e08aacStbbdev distributed under the License is distributed on an "AS IS" BASIS, 1249e08aacStbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349e08aacStbbdev See the License for the specific language governing permissions and 1449e08aacStbbdev limitations under the License. 1549e08aacStbbdev */ 1649e08aacStbbdev 1749e08aacStbbdev #ifndef __TBB_profiling_H 1849e08aacStbbdev #define __TBB_profiling_H 1949e08aacStbbdev 2049e08aacStbbdev #include "detail/_config.h" 2149e08aacStbbdev #include <cstdint> 2249e08aacStbbdev 2349e08aacStbbdev #include <string> 2449e08aacStbbdev 2549e08aacStbbdev namespace tbb { 2649e08aacStbbdev namespace detail { 2749e08aacStbbdev inline namespace d0 { 2849e08aacStbbdev // include list of index names 2949e08aacStbbdev #define TBB_STRING_RESOURCE(index_name,str) index_name, 3049e08aacStbbdev enum string_resource_index : std::uintptr_t { 3149e08aacStbbdev #include "detail/_string_resource.h" 3249e08aacStbbdev NUM_STRINGS 3349e08aacStbbdev }; 3449e08aacStbbdev #undef TBB_STRING_RESOURCE 3549e08aacStbbdev 3649e08aacStbbdev enum itt_relation 3749e08aacStbbdev { 3849e08aacStbbdev __itt_relation_is_unknown = 0, 3949e08aacStbbdev __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ 4049e08aacStbbdev __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ 4149e08aacStbbdev __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ 4249e08aacStbbdev __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ 4349e08aacStbbdev __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ 4449e08aacStbbdev __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ 4549e08aacStbbdev __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ 4649e08aacStbbdev }; 4749e08aacStbbdev 4849e08aacStbbdev //! Unicode support 498827ea7dSLong Nguyen #if (_WIN32||_WIN64) 5049e08aacStbbdev //! Unicode character type. Always wchar_t on Windows. 5149e08aacStbbdev using tchar = wchar_t; 5249e08aacStbbdev #else /* !WIN */ 5349e08aacStbbdev using tchar = char; 5449e08aacStbbdev #endif /* !WIN */ 5549e08aacStbbdev 5649e08aacStbbdev } // namespace d0 5749e08aacStbbdev } // namespace detail 5849e08aacStbbdev } // namespace tbb 5949e08aacStbbdev 6049e08aacStbbdev #include <atomic> 6149e08aacStbbdev #if _WIN32||_WIN64 6249e08aacStbbdev #include <stdlib.h> /* mbstowcs_s */ 6349e08aacStbbdev #endif 6449e08aacStbbdev // Need these to work regardless of tools support 6549e08aacStbbdev namespace tbb { 6649e08aacStbbdev namespace detail { 6749e08aacStbbdev namespace d1 { 6849e08aacStbbdev enum notify_type {prepare=0, cancel, acquired, releasing, destroy}; 6949e08aacStbbdev enum itt_domain_enum { ITT_DOMAIN_FLOW=0, ITT_DOMAIN_MAIN=1, ITT_DOMAIN_ALGO=2, ITT_NUM_DOMAINS }; 7049e08aacStbbdev } // namespace d1 7149e08aacStbbdev 7249e08aacStbbdev namespace r1 { 738827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC call_itt_notify(int t, void* ptr); 748827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC create_itt_sync(void* ptr, const tchar* objtype, const tchar* objname); 758827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_make_task_group(d1::itt_domain_enum domain, void* group, unsigned long long group_extra, 7649e08aacStbbdev void* parent, unsigned long long parent_extra, string_resource_index name_index); 778827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_task_begin(d1::itt_domain_enum domain, void* task, unsigned long long task_extra, 7849e08aacStbbdev void* parent, unsigned long long parent_extra, string_resource_index name_index); 798827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_task_end(d1::itt_domain_enum domain); 808827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_set_sync_name(void* obj, const tchar* name); 818827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_metadata_str_add(d1::itt_domain_enum domain, void* addr, unsigned long long addr_extra, 8249e08aacStbbdev string_resource_index key, const char* value); 838827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_metadata_ptr_add(d1::itt_domain_enum domain, void* addr, unsigned long long addr_extra, 8449e08aacStbbdev string_resource_index key, void* value); 858827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_relation_add(d1::itt_domain_enum domain, void* addr0, unsigned long long addr0_extra, 8649e08aacStbbdev itt_relation relation, void* addr1, unsigned long long addr1_extra); 878827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_region_begin(d1::itt_domain_enum domain, void* region, unsigned long long region_extra, 8849e08aacStbbdev void* parent, unsigned long long parent_extra, string_resource_index /* name_index */); 898827ea7dSLong Nguyen TBB_EXPORT void __TBB_EXPORTED_FUNC itt_region_end(d1::itt_domain_enum domain, void* region, unsigned long long region_extra); 9049e08aacStbbdev } // namespace r1 9149e08aacStbbdev 9249e08aacStbbdev namespace d1 { 938827ea7dSLong Nguyen #if TBB_USE_PROFILING_TOOLS && (_WIN32||_WIN64) multibyte_to_widechar(wchar_t * wcs,const char * mbs,std::size_t bufsize)9449e08aacStbbdev inline std::size_t multibyte_to_widechar(wchar_t* wcs, const char* mbs, std::size_t bufsize) { 9549e08aacStbbdev std::size_t len; 9649e08aacStbbdev mbstowcs_s(&len, wcs, bufsize, mbs, _TRUNCATE); 9749e08aacStbbdev return len; // mbstowcs_s counts null terminator 9849e08aacStbbdev } 9949e08aacStbbdev #endif 10049e08aacStbbdev 10149e08aacStbbdev #if TBB_USE_PROFILING_TOOLS create_itt_sync(void * ptr,const char * objtype,const char * objname)10249e08aacStbbdev inline void create_itt_sync(void *ptr, const char *objtype, const char *objname) { 1038827ea7dSLong Nguyen #if (_WIN32||_WIN64) 10449e08aacStbbdev std::size_t len_type = multibyte_to_widechar(nullptr, objtype, 0); 10549e08aacStbbdev wchar_t *type = new wchar_t[len_type]; 10649e08aacStbbdev multibyte_to_widechar(type, objtype, len_type); 10749e08aacStbbdev std::size_t len_name = multibyte_to_widechar(nullptr, objname, 0); 10849e08aacStbbdev wchar_t *name = new wchar_t[len_name]; 10949e08aacStbbdev multibyte_to_widechar(name, objname, len_name); 11049e08aacStbbdev #else // WIN 11149e08aacStbbdev const char *type = objtype; 11249e08aacStbbdev const char *name = objname; 11349e08aacStbbdev #endif 11449e08aacStbbdev r1::create_itt_sync(ptr, type, name); 11549e08aacStbbdev 1168827ea7dSLong Nguyen #if (_WIN32||_WIN64) 11749e08aacStbbdev delete[] type; 11849e08aacStbbdev delete[] name; 11949e08aacStbbdev #endif // WIN 12049e08aacStbbdev } 12149e08aacStbbdev 12249e08aacStbbdev // Distinguish notifications on task for reducing overheads 12349e08aacStbbdev #if TBB_USE_PROFILING_TOOLS == 2 call_itt_task_notify(d1::notify_type t,void * ptr)12449e08aacStbbdev inline void call_itt_task_notify(d1::notify_type t, void *ptr) { 125*0cf592bdSAndrew Corrigan r1::call_itt_notify(static_cast<int>(t), ptr); 12649e08aacStbbdev } 12749e08aacStbbdev #else call_itt_task_notify(d1::notify_type,void *)12849e08aacStbbdev inline void call_itt_task_notify(d1::notify_type, void *) {} 12949e08aacStbbdev #endif // TBB_USE_PROFILING_TOOLS 13049e08aacStbbdev call_itt_notify(d1::notify_type t,void * ptr)13149e08aacStbbdev inline void call_itt_notify(d1::notify_type t, void *ptr) { 132*0cf592bdSAndrew Corrigan r1::call_itt_notify(static_cast<int>(t), ptr); 13349e08aacStbbdev } 13449e08aacStbbdev 13549e08aacStbbdev #if (_WIN32||_WIN64) && !__MINGW32__ itt_set_sync_name(void * obj,const wchar_t * name)13649e08aacStbbdev inline void itt_set_sync_name(void* obj, const wchar_t* name) { 13749e08aacStbbdev r1::itt_set_sync_name(obj, name); 13849e08aacStbbdev } itt_set_sync_name(void * obj,const char * name)13949e08aacStbbdev inline void itt_set_sync_name(void* obj, const char* name) { 14049e08aacStbbdev std::size_t len_name = multibyte_to_widechar(nullptr, name, 0); 14149e08aacStbbdev wchar_t *obj_name = new wchar_t[len_name]; 14249e08aacStbbdev multibyte_to_widechar(obj_name, name, len_name); 14349e08aacStbbdev r1::itt_set_sync_name(obj, obj_name); 14449e08aacStbbdev delete[] obj_name; 14549e08aacStbbdev } 14649e08aacStbbdev #else itt_set_sync_name(void * obj,const char * name)14749e08aacStbbdev inline void itt_set_sync_name( void* obj, const char* name) { 14849e08aacStbbdev r1::itt_set_sync_name(obj, name); 14949e08aacStbbdev } 15049e08aacStbbdev #endif //WIN 15149e08aacStbbdev itt_make_task_group(itt_domain_enum domain,void * group,unsigned long long group_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)15249e08aacStbbdev inline void itt_make_task_group(itt_domain_enum domain, void* group, unsigned long long group_extra, 15349e08aacStbbdev void* parent, unsigned long long parent_extra, string_resource_index name_index) { 15449e08aacStbbdev r1::itt_make_task_group(domain, group, group_extra, parent, parent_extra, name_index); 15549e08aacStbbdev } 15649e08aacStbbdev itt_metadata_str_add(itt_domain_enum domain,void * addr,unsigned long long addr_extra,string_resource_index key,const char * value)15749e08aacStbbdev inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra, 15849e08aacStbbdev string_resource_index key, const char *value ) { 15949e08aacStbbdev r1::itt_metadata_str_add( domain, addr, addr_extra, key, value ); 16049e08aacStbbdev } 16149e08aacStbbdev register_node_addr(itt_domain_enum domain,void * addr,unsigned long long addr_extra,string_resource_index key,void * value)16249e08aacStbbdev inline void register_node_addr(itt_domain_enum domain, void *addr, unsigned long long addr_extra, 16349e08aacStbbdev string_resource_index key, void *value) { 16449e08aacStbbdev r1::itt_metadata_ptr_add(domain, addr, addr_extra, key, value); 16549e08aacStbbdev } 16649e08aacStbbdev itt_relation_add(itt_domain_enum domain,void * addr0,unsigned long long addr0_extra,itt_relation relation,void * addr1,unsigned long long addr1_extra)16749e08aacStbbdev inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, 16849e08aacStbbdev itt_relation relation, void *addr1, unsigned long long addr1_extra ) { 16949e08aacStbbdev r1::itt_relation_add( domain, addr0, addr0_extra, relation, addr1, addr1_extra ); 17049e08aacStbbdev } 17149e08aacStbbdev itt_task_begin(itt_domain_enum domain,void * task,unsigned long long task_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)17249e08aacStbbdev inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra, 17349e08aacStbbdev void *parent, unsigned long long parent_extra, string_resource_index name_index ) { 17449e08aacStbbdev r1::itt_task_begin( domain, task, task_extra, parent, parent_extra, name_index ); 17549e08aacStbbdev } 17649e08aacStbbdev itt_task_end(itt_domain_enum domain)17749e08aacStbbdev inline void itt_task_end( itt_domain_enum domain ) { 17849e08aacStbbdev r1::itt_task_end( domain ); 17949e08aacStbbdev } 18049e08aacStbbdev itt_region_begin(itt_domain_enum domain,void * region,unsigned long long region_extra,void * parent,unsigned long long parent_extra,string_resource_index name_index)18149e08aacStbbdev inline void itt_region_begin( itt_domain_enum domain, void *region, unsigned long long region_extra, 18249e08aacStbbdev void *parent, unsigned long long parent_extra, string_resource_index name_index ) { 18349e08aacStbbdev r1::itt_region_begin( domain, region, region_extra, parent, parent_extra, name_index ); 18449e08aacStbbdev } 18549e08aacStbbdev itt_region_end(itt_domain_enum domain,void * region,unsigned long long region_extra)18649e08aacStbbdev inline void itt_region_end( itt_domain_enum domain, void *region, unsigned long long region_extra ) { 18749e08aacStbbdev r1::itt_region_end( domain, region, region_extra ); 18849e08aacStbbdev } 18949e08aacStbbdev #else create_itt_sync(void *,const char *,const char *)19049e08aacStbbdev inline void create_itt_sync(void* /*ptr*/, const char* /*objtype*/, const char* /*objname*/) {} 19149e08aacStbbdev call_itt_notify(notify_type,void *)19249e08aacStbbdev inline void call_itt_notify(notify_type /*t*/, void* /*ptr*/) {} 19349e08aacStbbdev call_itt_task_notify(notify_type,void *)19449e08aacStbbdev inline void call_itt_task_notify(notify_type /*t*/, void* /*ptr*/) {} 19549e08aacStbbdev #endif // TBB_USE_PROFILING_TOOLS 19649e08aacStbbdev 19749e08aacStbbdev #if TBB_USE_PROFILING_TOOLS && !(TBB_USE_PROFILING_TOOLS == 2) 19849e08aacStbbdev class event { 19949e08aacStbbdev /** This class supports user event traces through itt. 20049e08aacStbbdev Common use-case is tagging data flow graph tasks (data-id) 20149e08aacStbbdev and visualization by Intel Advisor Flow Graph Analyzer (FGA) **/ 20249e08aacStbbdev // TODO: Replace implementation by itt user event api. 20349e08aacStbbdev 20449e08aacStbbdev const std::string my_name; 20549e08aacStbbdev emit_trace(const std::string & input)20649e08aacStbbdev static void emit_trace(const std::string &input) { 20757f524caSIlya Isaev itt_metadata_str_add( ITT_DOMAIN_FLOW, nullptr, FLOW_NULL, USER_EVENT, ( "FGA::DATAID::" + input ).c_str() ); 20849e08aacStbbdev } 20949e08aacStbbdev 21049e08aacStbbdev public: event(const std::string & input)21149e08aacStbbdev event(const std::string &input) 21249e08aacStbbdev : my_name( input ) 21349e08aacStbbdev { } 21449e08aacStbbdev emit()21549e08aacStbbdev void emit() { 21649e08aacStbbdev emit_trace(my_name); 21749e08aacStbbdev } 21849e08aacStbbdev emit(const std::string & description)21949e08aacStbbdev static void emit(const std::string &description) { 22049e08aacStbbdev emit_trace(description); 22149e08aacStbbdev } 22249e08aacStbbdev 22349e08aacStbbdev }; 22449e08aacStbbdev #else // TBB_USE_PROFILING_TOOLS && !(TBB_USE_PROFILING_TOOLS == 2) 22549e08aacStbbdev // Using empty struct if user event tracing is disabled: 22649e08aacStbbdev struct event { eventevent22749e08aacStbbdev event(const std::string &) { } 22849e08aacStbbdev emitevent22949e08aacStbbdev void emit() { } 23049e08aacStbbdev emitevent23149e08aacStbbdev static void emit(const std::string &) { } 23249e08aacStbbdev }; 23349e08aacStbbdev #endif // TBB_USE_PROFILING_TOOLS && !(TBB_USE_PROFILING_TOOLS == 2) 23449e08aacStbbdev } // namespace d1 23549e08aacStbbdev } // namespace detail 23649e08aacStbbdev 23749e08aacStbbdev namespace profiling { 23849e08aacStbbdev using detail::d1::event; 23949e08aacStbbdev } 24049e08aacStbbdev } // namespace tbb 24149e08aacStbbdev 24249e08aacStbbdev 24349e08aacStbbdev #endif /* __TBB_profiling_H */ 244