80 void Process(
const std::shared_ptr<const JEvent>& event)
override {
82 auto stack =
event->GetJCallGraphRecorder()->GetCallGraph();
85 std::lock_guard<std::mutex> lck(mutex);
88 for (
unsigned int i = 0; i < stack.size(); i++) {
91 std::string nametag1 = MakeNametag(stack[i].caller_name, stack[i].caller_tag);
92 std::string nametag2 = MakeNametag(stack[i].callee_name, stack[i].callee_tag);
94 FactoryCallStats& fcallstats1 = factory_stats[nametag1];
95 FactoryCallStats& fcallstats2 = factory_stats[nametag2];
97 auto delta_t_ms = std::chrono::duration_cast<std::chrono::milliseconds>(stack[i].end_time -
100 fcallstats1.time_waiting += delta_t_ms;
101 fcallstats2.time_waited_on += delta_t_ms;
105 link.caller_name = stack[i].caller_name;
106 link.caller_tag = stack[i].caller_tag;
107 link.callee_name = stack[i].callee_name;
108 link.callee_tag = stack[i].callee_tag;
112 switch (stack[i].data_source) {
113 case JCallGraphRecorder::DATA_NOT_AVAILABLE:
114 stats.Ndata_not_available++;
115 stats.data_not_available_ms += delta_t_ms;
117 case JCallGraphRecorder::DATA_FROM_CACHE:
118 fcallstats2.Nfrom_cache++;
120 stats.from_cache_ms += delta_t_ms;
122 case JCallGraphRecorder::DATA_FROM_SOURCE:
123 fcallstats2.Nfrom_source++;
124 stats.Nfrom_source++;
125 stats.from_source_ms += delta_t_ms;
127 case JCallGraphRecorder::DATA_FROM_FACTORY:
128 fcallstats2.Nfrom_factory++;
129 stats.Nfrom_factory++;
130 stats.from_factory_ms += delta_t_ms;
142 std::set<std::string> callers;
143 std::set<std::string> callees;
144 for (
auto iter = call_links.begin(); iter != call_links.end(); iter++) {
145 const CallLink& link = iter->first;
146 std::string caller = MakeNametag(link.caller_name, link.caller_tag);
147 std::string callee = MakeNametag(link.callee_name, link.callee_tag);
148 callers.insert(caller);
149 callees.insert(callee);
154 double total_ms = 0.0;
155 for (
auto iter = call_links.begin(); iter != call_links.end(); iter++) {
156 const CallLink& link = iter->first;
157 const CallStats& stats = iter->second;
158 std::string caller = MakeNametag(link.caller_name, link.caller_tag);
159 std::string callee = MakeNametag(link.callee_name, link.callee_tag);
160 if (callees.find(caller) == callees.end()) {
161 total_ms += stats.from_factory_ms + stats.from_source_ms + stats.from_cache_ms +
162 stats.data_not_available_ms;
169 std::cout <<
"Links:" << std::endl;
170 std::vector<std::pair<CallLink, CallStats>> call_links_vector{
171 std::make_move_iterator(std::begin(call_links)),
172 std::make_move_iterator(std::end(call_links))};
173 [[maybe_unused]]
auto call_links_compare_time = [](
const auto& a,
const auto& b) {
174 return ((a.second.from_factory_ms + a.second.from_source_ms + a.second.from_cache_ms) <
175 (b.second.from_factory_ms + b.second.from_source_ms + b.second.from_cache_ms));
177 [[maybe_unused]]
auto call_links_compare_N = [](
const auto& a,
const auto& b) {
178 return ((a.second.Nfrom_factory + a.second.Nfrom_source + a.second.Nfrom_cache) <
179 (b.second.Nfrom_factory + b.second.Nfrom_source + b.second.Nfrom_cache));
181 std::sort(call_links_vector.begin(), call_links_vector.end(), call_links_compare_time);
182 for (
auto iter = call_links_vector.end() - std::min(call_links_vector.size(), 10ul);
183 iter != call_links_vector.end(); iter++) {
184 const CallLink& link = iter->first;
185 const CallStats& stats = iter->second;
187 unsigned int Ntotal = stats.Nfrom_cache + stats.Nfrom_source + stats.Nfrom_factory;
189 std::string nametag1 = MakeNametag(link.caller_name, link.caller_tag);
190 std::string nametag2 = MakeNametag(link.callee_name, link.callee_tag);
192 double this_ms = stats.from_factory_ms + stats.from_source_ms + stats.from_cache_ms;
193 std::string timestr = MakeTimeString(stats.from_factory_ms);
194 double percent = 100.0 * this_ms / total_ms;
196 snprintf(percentstr, 32,
"%5.1f%%", percent);
198 std::cout << Ntotal <<
" calls, " << timestr <<
" (" << percentstr <<
") ";
199 std::cout << nametag1 <<
" -> " << nametag2;
200 std::cout << std::endl;
204 std::cout <<
"Factories:" << std::endl;
205 std::vector<std::pair<std::string, FactoryCallStats>> factory_stats_vector{
206 std::make_move_iterator(std::begin(factory_stats)),
207 std::make_move_iterator(std::end(factory_stats))};
208 auto factory_stats_compare = [](
const auto& a,
const auto& b) {
209 return ((a.second.time_waited_on - a.second.time_waiting) <
210 (b.second.time_waited_on - b.second.time_waiting));
212 std::sort(factory_stats_vector.begin(), factory_stats_vector.end(), factory_stats_compare);
213 for (
auto iter = factory_stats_vector.end() - std::min(factory_stats_vector.size(), 10ul);
214 iter != factory_stats_vector.end(); iter++) {
215 FactoryCallStats& fcall_stats = iter->second;
216 std::string nodename = iter->first;
219 double time_spent_in_factory = fcall_stats.time_waited_on - fcall_stats.time_waiting;
220 std::string timestr = MakeTimeString(time_spent_in_factory);
221 double percent = 100.0 * time_spent_in_factory / total_ms;
223 snprintf(percentstr, 32,
"%5.1f%%", percent);
225 std::cout << timestr <<
" (" << percentstr <<
") ";
226 std::cout << nodename;
227 std::cout << std::endl;