15#include "arcane/utils/ArcanePrecomp.h"
17#include "arcane/utils/Array.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/StringBuilder.h"
20#include "arcane/utils/PlatformUtils.h"
21#include "arcane/utils/JSONWriter.h"
23#include "arcane/std/ProfilingInfo.h"
28#include "arcane_packages.h"
32#ifdef ARCANE_HAS_PACKAGE_LIBUNWIND
41#if defined(ARCANE_OS_LINUX)
50#if defined(ARCANE_OS_LINUX)
51#define ARCANE_HAS_GLIBC_BACKTRACE
54#ifdef ARCANE_USE_MALLOC_HOOK
78 virtual Integer nbIndex()
const =0;
79 virtual intptr_t functionStartAddress(Int32
stack_index) =0;
104 pfi.m_func_name[0] =
'\0';
105 pfi.setHasFuncName(
true);
112#ifdef ARCANE_HAS_PACKAGE_LIBUNWIND
113class ProfInfos::LibUnwindFuncInfos
123 pfi.setHasFuncName(
true);
130 unw_cursor_t func_cursor[MAX_FUNC];
133class ProfInfos::LibUnwindStackInfo
134:
public IStackInfoProvider
137 LibUnwindStackInfo(LibUnwindFuncInfos* func_infos)
138 : m_nb_index(0), m_func_infos(func_infos){}
140 void fillStack(Integer function_depth)
override
146 unw_init_local(&cursor, &uc);
147 unw_proc_info_t proc_info;
148 while (unw_step(&cursor) > 0 && index<(MAX_STACK+function_depth)) {
149 unw_get_proc_info(&cursor,&proc_info);
150 m_cursors[index] = cursor;
151 m_proc_start[index] = proc_info.start_ip;
156 void setFunc(
Int32 func_index,
Int32 stack_index)
override
158 m_func_infos->setFunc(func_index,m_cursors[stack_index]);
161 Integer nbIndex()
const override {
return m_nb_index; }
162 intptr_t functionStartAddress(
Int32 stack_index)
override
164 return (intptr_t)m_proc_start[stack_index];
168 unw_cursor_t m_cursors[256];
169 unw_word_t m_proc_start[256];
171 LibUnwindFuncInfos* m_func_infos;
178#ifdef ARCANE_HAS_GLIBC_BACKTRACE
179class ProfInfos::BacktraceFuncInfos
180:
public IFuncInfoProvider
183 void fillFuncName(ProfFuncInfo& pfi)
override
185 Int32 func_index = pfi.index();
187 const char* func_name = func_dl_info[func_index].dli_sname;
189 for( ; copy_index<MAX_FUNC_LEN; ++copy_index ){
190 char c = func_name[copy_index];
191 pfi.m_func_name[copy_index] = c;
196 pfi.m_func_name[copy_index] =
'\0';
197 pfi.setHasFuncName(
true);
199 void setFunc(
Int32 func_index,
const Dl_info& dl_info)
201 func_dl_info[func_index] = dl_info;
204 Dl_info func_dl_info[MAX_FUNC];
206class ProfInfos::BacktraceStackInfo
207:
public IStackInfoProvider
210 BacktraceStackInfo(BacktraceFuncInfos* func_infos)
211 : m_nb_index(0), m_func_infos(func_infos){}
213 void fillStack(Integer function_depth)
override
215 ARCANE_UNUSED(function_depth);
217 m_nb_index = backtrace(addrs,64);
218 for( Integer index=0; index<m_nb_index; ++index ){
219 int err_code = dladdr(addrs[index],&m_dl_infos[index]);
221 m_proc_start[index] = (intptr_t)m_dl_infos[index].dli_saddr;
223 m_proc_start[index] = 0;
226 void setFunc(
Int32 func_index,
Int32 stack_index)
override
228 m_func_infos->setFunc(func_index,m_dl_infos[stack_index]);
231 Integer nbIndex()
const override {
return m_nb_index; }
232 intptr_t functionStartAddress(
Int32 stack_index)
override
234 return (intptr_t)m_proc_start[stack_index];
238 std::array<Dl_info,256> m_dl_infos = { };
239 std::array<intptr_t,256> m_proc_start = { };
241 BacktraceFuncInfos* m_func_infos;
255 typedef void* (*mono_jit_info_get_code_start_func)(
_MonoJitInfo*
ji);
258 typedef char* (*mono_pmip_func)(
void*
ip);
260 typedef char* (*mono_method_full_name_func)(
_MonoMethod* method,
bool full);
264 empty_func_name[0] =
'\0';
265#if defined(ARCANE_OS_LINUX)
270 m_mono_jit_info_get_code_start_ptr = (mono_jit_info_get_code_start_func)(
dlsym(handle,
"mono_jit_info_get_code_start"));
271 m_mono_domain_get_ptr = (mono_domain_get_func)(
dlsym(handle,
"mono_domain_get"));
272 m_mono_jit_info_table_find_ptr = (mono_jit_info_table_find_func)(
dlsym(handle,
"mono_jit_info_table_find"));
273 m_mono_pmip_ptr = (mono_pmip_func)(
dlsym(handle,
"mono_pmip"));
274 m_mono_jit_info_get_method_ptr = (mono_jit_info_get_method_func)(
dlsym(handle,
"mono_jit_info_get_method"));
275 m_mono_method_full_name_ptr = (mono_method_full_name_func)(
dlsym(handle,
"mono_method_full_name"));
277 if (!m_mono_jit_info_get_code_start_ptr)
279 if (!m_mono_domain_get_ptr)
281 if (!m_mono_jit_info_table_find_ptr)
283 if (!m_mono_pmip_ptr)
285 if (!m_mono_jit_info_get_method_ptr)
287 if (!m_mono_method_full_name_ptr)
294#if defined(ARCANE_OS_LINUX)
303 char empty_func_name[1];
308 char* func_name = empty_func_name;
312 void* start_addr = 0;
314 start_addr = (*m_mono_jit_info_get_code_start_ptr)(
ji);
316 func_name = (*m_mono_method_full_name_ptr)(method,
true);
327 bool m_is_valid =
false;
328 mono_jit_info_get_code_start_func m_mono_jit_info_get_code_start_ptr =
nullptr;
329 mono_domain_get_func m_mono_domain_get_ptr =
nullptr;
330 mono_jit_info_table_find_func m_mono_jit_info_table_find_ptr =
nullptr;
331 mono_pmip_func m_mono_pmip_ptr =
nullptr;
332 mono_jit_info_get_method_func m_mono_jit_info_get_method_ptr =
nullptr;
333 mono_method_full_name_func m_mono_method_full_name_ptr =
nullptr;
334 void* m_handle =
nullptr;
340static std::atomic<Int32> global_in_malloc;
342#ifdef ARCANE_USE_MALLOC_HOOK
345void*(*my_old_malloc_hook)(size_t,
const void*);
352extern void* prof_malloc_hook(
size_t size,
const void* caller);
353extern void prof_free_hook(
void* ptr,
const void* caller);
354extern void* prof_realloc_hook(
void* __ptr,
size_t __size,__const
void*);
359extern ARCANE_STD_EXPORT
void _pushHook()
361 __malloc_hook = my_old_malloc_hook;
362 __free_hook = my_old_free_hook;
363 __realloc_hook = my_old_realloc_hook;
366extern ARCANE_STD_EXPORT
void _popHook()
368 __malloc_hook = prof_malloc_hook;
369 __free_hook = prof_free_hook;
370 __realloc_hook = prof_realloc_hook;
373void* prof_malloc_hook(
size_t size,
const void* )
377 void* r = malloc(size);
383void prof_free_hook(
void* ptr,
const void* )
390void* prof_realloc_hook(
void* ptr,
size_t size,
const void* )
394 void* r = realloc(ptr,size);
400void _profInitMallocHook()
402 global_in_malloc = 0;
403 my_old_malloc_hook = __malloc_hook;
404 __malloc_hook = prof_malloc_hook;
405 my_old_free_hook = __free_hook;
406 __free_hook = prof_free_hook;
407 my_old_realloc_hook = __realloc_hook;
408 __realloc_hook = prof_realloc_hook;
411void _profRestoreMallocHook()
413 __free_hook = my_old_free_hook;
414 __malloc_hook = my_old_malloc_hook;
415 __realloc_hook = my_old_realloc_hook;
418void _profInitMallocHook()
421void _profRestoreMallocHook()
442_getDemangledName(
const char* true_func_name,
char* demangled_buf,
size_t demangled_buf_len)
444 if (demangled_buf_len<=1)
445 return true_func_name;
446 size_t len = demangled_buf_len - 1;
448 const char* buf =
nullptr;
450 buf = abi::__cxa_demangle(true_func_name,demangled_buf,&len,&dstatus);
453 buf = true_func_name;
462ProfInfos(ITraceMng* tm)
464, m_default_func_info_provider(new NullFuncInfoProvider())
465, m_func_info_provider(m_default_func_info_provider)
467 for( Integer i=0; i<MAX_COUNTER; ++i )
472 if (!platform::getEnvironmentVariable(
"ARCANE_DOTNET_BACKTRACE").null()){
473 m_mono_func_getter =
new MonoFuncAddrGetter();
474 if (!m_mono_func_getter->isValid()){
475 delete m_mono_func_getter;
476 m_mono_func_getter = 0;
480#ifdef ARCANE_HAS_PACKAGE_LIBUNWIND
481 m_libunwind_func_info_provider =
new LibUnwindFuncInfos();
482 m_use_libunwind =
true;
484#ifdef ARCANE_HAS_GLIBC_BACKTRACE
485 m_backtrace_func_info_provider =
new BacktraceFuncInfos();
495 delete m_default_func_info_provider;
496 delete m_backtrace_func_info_provider;
497 delete m_libunwind_func_info_provider;
498 delete m_mono_func_getter;
504ProfFuncInfo* ProfInfos::
509 ProfFuncInfo* fi = &m_func_info_buffer[m_current_func_info];
510 fi->setIndex(m_current_func_info);
511 ++m_current_func_info;
523 info() <<
"START PROFILING";
529 _profInitMallocHook();
532 String stack_unwinder_str = platform::getEnvironmentVariable(
"ARCANE_PROFILING_STACKUNWINDING");
533 info() <<
"STACK_UNWIND=" << stack_unwinder_str;
534 if (stack_unwinder_str==
"backtrace"){
535 m_use_backtrace =
true;
536 m_use_libunwind =
false;
538 m_func_info_provider = m_default_func_info_provider;
540 m_func_info_provider = m_backtrace_func_info_provider;
541 else if (m_use_libunwind)
542 m_func_info_provider = m_libunwind_func_info_provider;
543 info() <<
"Start profiling: use_backtrace=" << m_use_backtrace
544 <<
" use_libunwind=" << m_use_libunwind
545 <<
" has_mono=" << m_mono_func_getter;
554 m_is_started =
false;
555 _profRestoreMallocHook();
560 for(
Int32 i=0, n=m_current_func_info; i<n; ++i ){
561 ProfFuncInfo& pfi = m_func_info_buffer[i];
562 if (!pfi.hasFuncName())
563 m_func_info_provider->fillFuncName(pfi);
581setFunctionDepth(
int v)
584 m_function_depth = v;
601int global_nb_in_handler = 0;
605addEvent(
void* address,
int overflow_event[MAX_COUNTER],
int nb_overflow_event)
607 static bool is_in_handler =
false;
610 ++global_nb_in_handler;
613 is_in_handler =
true;
614 if (m_use_backtrace){
616#ifdef ARCANE_HAS_GLIBC_BACKTRACE
617 BacktraceStackInfo stack_info((BacktraceFuncInfos*)m_backtrace_func_info_provider);
618 _addEvent(address,overflow_event,nb_overflow_event,stack_info,m_function_depth+2);
621 else if (m_use_libunwind){
622#ifdef ARCANE_HAS_PACKAGE_LIBUNWIND
623 LibUnwindStackInfo stack_info((LibUnwindFuncInfos*)m_libunwind_func_info_provider);
624 _addEvent(address,overflow_event,nb_overflow_event,stack_info,m_function_depth+1);
627 is_in_handler =
false;
634_sortFunctions(std::set<ProfFuncInfo*,ProfFuncComparer>& sorted_func)
636 for(
const auto& x : m_func_map )
638 sorted_func.insert(x.second);
645_storeAddress(
void* address,
bool is_counter0,
int overflow_event[MAX_COUNTER],
int nb_overflow_event,
646 bool* do_add,
bool* do_stack,
bool* func_already_added)
649 ProfInfos::AddrMap::iterator v = m_addr_map.find(address);
650 if (v!=m_addr_map.end()){
651 ProfAddrInfo& ai = v->second;
652 for(
int i=0; i<nb_overflow_event; ++i )
653 ++ai.m_counters[ overflow_event[i] ];
655 for(
int i=0; i<nb_overflow_event; ++i )
656 ++ai.m_func_info->m_counters[ overflow_event[i] ];
657 *func_already_added =
true;
660 if (m_total_event>m_nb_event_before_getting_stack){
661 if ((ai.m_func_info->m_counters[0]*100)>m_total_event){
662 ai.m_func_info->m_do_stack =
true;
677_addEvent(
void* address,
int overflow_event[MAX_COUNTER],
int nb_overflow_event,
678 IStackInfoProvider& stack_info,Integer function_depth)
684 if (global_in_malloc!=0){
689 bool is_counter0 =
false;
691 for(
int i=0; i<nb_overflow_event; ++i ){
692 if (overflow_event[i]==0)
694 if (overflow_event[i]<0 || overflow_event[i]>=MAX_COUNTER)
695 cerr <<
"arcane_papi_handler: EVENT ERROR n=" << overflow_event[i] <<
'\n';
698 bool do_stack =
false;
700 bool func_already_added =
false;
701 _storeAddress(address,is_counter0,overflow_event,nb_overflow_event,
702 &do_add,&do_stack,&func_already_added);
704 if (do_add || do_stack){
705 ProfAddrInfo papi_address_info;
706 ProfStackInfo papi_stack_info;
707 for(
int i=0; i<nb_overflow_event; ++i )
708 ++papi_address_info.m_counters[ overflow_event[i] ];
710 stack_info.fillStack(function_depth);
712 for (Integer index=function_depth, nb_index=stack_info.nbIndex(); index<nb_index; ++index ){
713 intptr_t proc_start = stack_info.functionStartAddress(index);
715 ProfInfos::FuncMap::iterator func = m_func_map.find(proc_start);
716 ProfFuncInfo* papi_func_info =
nullptr;
717 if (func==m_func_map.end()){
718 if (m_current_func_info>=MAX_FUNC){
719 cerr <<
"arcane_papi_handler: MAX_FUNC reached !\n";
722 papi_func_info = _getNextFuncInfo();
723 papi_address_info.m_func_info = papi_func_info;
724 Int32 func_index = papi_func_info->index();
725 stack_info.setFunc(func_index,index);
726 m_func_map.insert(ProfInfos::FuncMap::value_type(proc_start,papi_func_info));
729 papi_func_info = func->second;
732 if (index<(MAX_STACK+function_depth))
733 papi_stack_info.m_funcs_info_indexes[index-function_depth] = papi_func_info->index();
734 if (index==function_depth){
735 papi_address_info.m_func_info = papi_func_info;
736 if (!func_already_added)
737 for(
int i=0; i<nb_overflow_event; ++i )
738 ++papi_func_info->m_counters[ overflow_event[i] ];
739 if (!papi_func_info->m_do_stack || !is_counter0)
747 ProfInfos::StackMap::iterator st = m_stack_map.find(papi_stack_info);
748 if (st!=m_stack_map.end()){
752 m_stack_map.insert(ProfInfos::StackMap::value_type(papi_stack_info,1));
755 m_addr_map.insert(ProfInfos::AddrMap::value_type(address,papi_address_info));
764_getFunc(
void* addr,FuncAddrInfo& info)
766#ifdef ARCANE_OS_LINUX
768 int r = dladdr(addr,&dl_info);
769 info.func_name =
"unknown";
775 info.start_addr = dl_info.dli_saddr;
776 if (dl_info.dli_sname){
777 info.func_name = dl_info.dli_sname;
781 if (m_mono_func_getter){
782 void* start_addr = 0;
783 char* func_name = m_mono_func_getter->getInfo(addr,&start_addr);
784 if (func_name && start_addr){
785 info.start_addr = start_addr;
786 info.func_name = func_name;
800 ProfInfos* global_infos =
this;
802 ProfInfos::AddrMap::iterator begin = global_infos->m_addr_map.begin();
803 for( ; begin!=global_infos->m_addr_map.end(); ++begin ){
804 for( Integer i=0; i<MAX_COUNTER; ++i )
805 begin->second.m_counters[i] = 0;
809 ProfInfos::FuncMap::iterator begin = global_infos->m_func_map.begin();
810 for( ; begin!=global_infos->m_func_map.end(); ++begin ){
811 ProfFuncInfo* pf = begin->second;
812 for( Integer i=0; i<MAX_COUNTER; ++i )
813 pf->m_counters[i] =0;
823printInfos(
bool dump_file)
825 ProfInfos* global_infos =
this;
827 Int64 total_event = 1;
829 int process_id = platform::getProcessId();
831 info() <<
" PROCESS_ID = " << process_id;
832 info() <<
" NB ADDRESS MAP = " << global_infos->m_addr_map.size();
833 info() <<
" NB FUNC MAP = " << global_infos->m_func_map.size();
834 info() <<
" NB STACK MAP = " << global_infos->m_stack_map.size();
835 info() <<
" TOTAL STACK = " << global_infos->m_total_stack;
837 ProfInfos::AddrMap::const_iterator begin = global_infos->m_addr_map.begin();
838 for( ; begin!=global_infos->m_addr_map.end(); ++begin ){
839 Int64 nb_event = begin->second.m_counters[0];
840 total_event += nb_event;
841 Int64 nb_fp = begin->second.m_counters[2];
846 ProfInfos::FuncMap::const_iterator begin = global_infos->m_func_map.begin();
847 Int64 total_func_event = 0;
848 Int64 total_func_fp = 0;
849 for( ; begin!=global_infos->m_func_map.end(); ++begin ){
850 ProfFuncInfo* pf = begin->second;
851 Int64 nb_event = pf->m_counters[0];
852 total_func_event += nb_event;
853 Int64 nb_fp = pf->m_counters[2];
854 total_func_fp += nb_fp;
856 info() <<
" FUNC EVENT=" << total_func_event;
857 info() <<
" FUNC FP=" << total_func_fp;
861 StringBuilder sfile_name =
"profiling.addr";
862 sfile_name += process_id;
863 sfile_name +=
".xml";
864 String file_name = sfile_name;
865 std::ofstream ofile(file_name.localstr());
866 ofile <<
"<?xml version='1.0'?>\n";
867 ofile <<
"<addresses>\n";
868 ProfInfos::AddrMap::const_iterator begin = global_infos->m_addr_map.begin();
869 for( ; begin!=global_infos->m_addr_map.end(); ++begin ){
870 void* addr = begin->first;
871 const ProfAddrInfo& pa = begin->second;
872 ProfFuncInfo* fi = pa.m_func_info;
874 ofile <<
"<addr addr='" << addr <<
"'"
875 <<
" count='" << pa.m_counters[0] <<
"'"
876 <<
" fi='" << fi <<
"'"
877 <<
" fi_count='" << fi->m_counters[0] <<
"'"
878 <<
" func='" << fi->m_func_name <<
"'"
882 ofile <<
"/<addresses>\n";
886 std::set<ProfFuncInfo*,ProfFuncComparer> sorted_func;
887 _sortFunctions(sorted_func);
889 const size_t NAME_BUF_SIZE = 8120;
890 char demangled_func_name[NAME_BUF_SIZE];
892 info() <<
" TOTAL EVENT = " << total_event;
893 info() <<
" TOTAL NB_IN_HANDLER = " << global_nb_in_handler;
894 Real nb_gflop = ((
Real)total_fp*(
Real)m_period) * 1e-09;
895 info() <<
" TOTAL FP = " << total_fp <<
" (nb_giga_flip=" << nb_gflop <<
")";
896 info() <<
" RATIO FP/CYC = " << ((
Real)total_fp/(
Real)total_event);
904 <<
" " <<
"function";
906 Int64 cumulative_nb_event = 0;
907 for( ProfFuncInfo* pfi : sorted_func ){
908 const char* func_name = pfi->m_func_name;
909 const char* buf = _getDemangledName(func_name,demangled_func_name,NAME_BUF_SIZE);
910 Int64 nb_event = pfi->m_counters[0];
911 cumulative_nb_event += nb_event;
912 Int64 cumulative_total_percent = (cumulative_nb_event * 1000) / total_event;
913 Int64 total_percent = (nb_event * 1000) / total_event;
914 Int64 cumulative_percent = (cumulative_total_percent/10);
915 Int64 percent = (total_percent/10);
917 <<
" " <<
Trace::Width(3) << percent <<
"." << (total_percent % 10)
918 <<
" " <<
Trace::Width(3) << cumulative_percent <<
"." << (cumulative_total_percent % 10)
922 <<
" " << pfi->m_do_stack
924 if (total_percent<5 && index>20)
932 UniqueArray<SortedProfStackInfo> sorted_stacks;
933 for(
const auto& x : global_infos->m_stack_map ){
934 const ProfStackInfo& psi = x.first;
935 Int64 nb_stack = x.second;
936 sorted_stacks.add(SortedProfStackInfo(psi,nb_stack));
938 std::sort(std::begin(sorted_stacks),std::end(sorted_stacks));
940 String file_name = String(
"profiling.callstack") + platform::getProcessId();
942 ofile.open(file_name.localstr());
944 for(
const auto& x : sorted_stacks ){
945 const ProfStackInfo& psi = x.stackInfo();
946 Int64 nb_stack = x.nbCount();
949 ofile <<
" Stack nb=" << nb_stack <<
'\n';
950 for( Integer z=0; z<MAX_STACK; ++z ){
951 Int32 fidx = psi.m_funcs_info_indexes[z];
953 ProfFuncInfo& pfi = _funcInfoFromIndex(fidx);
954 const char* func_name = pfi.m_func_name;
955 const char* buf = _getDemangledName(func_name,demangled_func_name,NAME_BUF_SIZE);
956 ofile <<
" " << buf <<
'\n';
985 const size_t NAME_BUF_SIZE = 8192;
986 char demangled_func_name[NAME_BUF_SIZE];
987 ProfInfos* global_infos =
this;
988 Int64 total_event = 1;
993 ProfInfos::AddrMap::const_iterator begin = global_infos->m_addr_map.begin();
994 for( ; begin!=global_infos->m_addr_map.end(); ++begin ){
995 Int64 nb_event = begin->second.m_counters[0];
996 total_event += nb_event;
997 Int64 nb_fp = begin->second.m_counters[2];
1002 pkt.add(total_event);
1004 pkt.add((
Int64)m_period);
1005 info()<<
"[ProfInfos::getInfos] total_event="<<total_event<<
", total_fp="<<total_fp<<
", m_period="<<m_period;
1007 std::set<ProfFuncInfo*,ProfFuncComparer> sorted_func;
1008 _sortFunctions(sorted_func);
1011 pkt.add((
Int64)index);
1014 for( ProfFuncInfo* pfi : sorted_func ){
1015 const char* func_name = pfi->m_func_name;
1016 const char* buf = _getDemangledName(func_name,demangled_func_name,NAME_BUF_SIZE);
1017 Int64 nb_event = pfi->m_counters[0];
1019 Int64 total_percent = (nb_event * 1000) / total_event;
1020 pkt.add(total_percent);
1021 pkt.add(pfi->m_counters[0]);
1022 pkt.add(pfi->m_counters[1]);
1023 pkt.add(pfi->m_counters[2]);
1025 Int64 mx = strlen(buf);
1027 for(
Int64 i=0; i<mx; i+=8)
1028 pkt.add(*(
Int64*)&buf[i]);
1030 if (total_percent<1 && index>16)
1034 pkt[5]=(
Int64)(index);
1035 info()<<
"[ProfInfos::getInfos] index @[4] ="<<pkt[5];
1042dumpJSON(JSONWriter& writer)
1047 ProfInfos* global_infos =
this;
1049 Int64 total_event = 1;
1050 for(
const auto& x : global_infos->m_addr_map ){
1051 Int64 nb_event = x.second.m_counters[0];
1052 total_event += nb_event;
1056 int process_id = platform::getProcessId();
1057 writer.write(
"ProcessId",(
Int64)process_id);
1058 writer.write(
"NbAddressMap",global_infos->m_addr_map.size());
1059 writer.write(
"NbFuncMap",global_infos->m_func_map.size());
1060 writer.write(
"NbStackMap",global_infos->m_stack_map.size());
1061 writer.write(
"TotalStack",global_infos->m_total_stack);
1062 writer.write(
"TotalEvent",total_event);
1065 std::set<ProfFuncInfo*,ProfFuncComparer> sorted_func;
1066 _sortFunctions(sorted_func);
1068 const size_t NAME_BUF_SIZE = 8192;
1069 char demangled_func_name[NAME_BUF_SIZE];
1073 writer.writeKey(
"Functions");
1074 writer.beginArray();
1075 for(
Int32 i=0, n=m_current_func_info; i<n; ++i ){
1076 const ProfFuncInfo& pfi = m_func_info_buffer[i];
1077 const char* func_name = pfi.m_func_name;
1078 const char* buf = _getDemangledName(func_name,demangled_func_name,NAME_BUF_SIZE);
1081 JSONWriter::Object o(writer);
1082 writer.write(
"Index",(
Int64)pfi.index());
1083 writer.write(
"Name",func_name);
1084 writer.write(
"DemangledName",buf);
1095 writer.writeKey(
"SortedFuncTimes");
1096 writer.beginArray();
1097 for( ProfFuncInfo* pfi : sorted_func ){
1098 const char* func_name = pfi->m_func_name;
1099 const char* buf = _getDemangledName(func_name,demangled_func_name,NAME_BUF_SIZE);
1101 JSONWriter::Object o(writer);
1102 writer.write(
"Index",(
Int64)(pfi->index()));
1103 writer.write(
"Name",buf);
1115 UniqueArray<SortedProfStackInfo> sorted_stacks;
1116 for(
const auto& x : global_infos->m_stack_map ){
1117 const ProfStackInfo& psi = x.first;
1118 Int64 nb_stack = x.second;
1119 sorted_stacks.add(SortedProfStackInfo(psi,nb_stack));
1121 std::sort(std::begin(sorted_stacks),std::end(sorted_stacks));
1123 writer.writeKey(
"StackMap");
1124 writer.beginArray();
1125 for(
const auto& x : sorted_stacks ){
1126 const ProfStackInfo& psi = x.stackInfo();
1127 Int64 nb_stack = x.nbCount();
1131 JSONWriter::Object o(writer);
1132 writer.write(
"Count",nb_stack);
1135 writer.writeKey(
"StackNames");
1136 writer.beginArray();
1137 for( Integer z=0; z<MAX_STACK; ++z ){
1138 Int32 fidx = psi.m_funcs_info_indexes[z];
1140 ProfFuncInfo& pfi = _funcInfoFromIndex(fidx);
1141 const char* func_name = pfi.m_func_name;
1142 const char* buf = _getDemangledName(func_name,demangled_func_name,NAME_BUF_SIZE);
1143 writer.writeValue(buf);
1146 writer.writeValue(String());
Fichier de configuration d'Arcane.
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Interface pour récupérer les infos d'une pile d'appel.
TraceMessage info() const
Flot pour un message d'information.
Formattage du flot en longueur.
Integer len(const char *s)
Retourne la longueur de la chaîne s.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Array< Int64 > Int64Array
Tableau dynamique à une dimension d'entiers 64 bits.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Int32 Integer
Type représentant un entier.