blob: 864e79142e3d90e35a08f76caeb5afdf92be4136 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "tools/fidlcat/lib/top.h"
#include <vector>
#include "tools/fidlcat/lib/event.h"
#include "tools/fidlcat/lib/syscall_decoder_dispatcher.h"
namespace fidlcat {
void Top::Display(std::ostream& os) {
std::vector<Process*> sorted_processes;
for (const auto& process : dispatcher_->processes()) {
sorted_processes.emplace_back(process.second.get());
}
std::sort(sorted_processes.begin(), sorted_processes.end(), [](Process* left, Process* right) {
return left->event_count() > right->event_count();
});
const char* separator = "";
// Displays all the processes one after the other.
for (const auto& process : sorted_processes) {
FidlcatPrinter printer(dispatcher_, process, os,
dispatcher_->extra_generation_needs_colors() ? fidl_codec::WithColors
: fidl_codec::WithoutColors,
"");
printer << separator;
for (int i = 0; i < dispatcher_->columns(); ++i) {
printer << '-';
}
printer << *process << ": " << process->event_count()
<< ((process->event_count() == 1) ? " event" : " events") << '\n';
fidl_codec::Indent indent(printer);
DisplayProcessContent(printer, process);
separator = "\n";
}
}
void Top::DisplayProcessContent(FidlcatPrinter& printer, Process* process) {
std::vector<Protocol*> sorted_protocols;
for (const auto& protocol : process->protocols()) {
sorted_protocols.emplace_back(protocol.second.get());
}
std::sort(sorted_protocols.begin(), sorted_protocols.end(), [](Protocol* left, Protocol* right) {
return (left->event_count() > right->event_count()) ||
((left->event_count() == right->event_count()) &&
((left->interface() == nullptr) || (right->interface() == nullptr) ||
(left->interface()->name().compare(right->interface()->name()) < 0)));
});
const char* separator = "";
// Displays all the protocols one after the other.
for (const auto& protocol : sorted_protocols) {
printer << separator;
if (protocol->interface() == nullptr) {
printer << "unknown interfaces: "
<< ": " << protocol->event_count()
<< ((protocol->event_count() == 1) ? " event" : " events") << '\n';
} else {
printer << protocol->interface()->name() << ": " << protocol->event_count()
<< ((protocol->event_count() == 1) ? " event" : " events") << '\n';
}
fidl_codec::Indent indent(printer);
DisplayProtocolContent(printer, protocol);
separator = "\n";
}
}
void Top::DisplayProtocolContent(FidlcatPrinter& printer, Protocol* protocol) {
std::vector<Method*> sorted_methods;
for (const auto& method : protocol->methods()) {
sorted_methods.emplace_back(method.second.get());
}
std::sort(sorted_methods.begin(), sorted_methods.end(), [](Method* left, Method* right) {
return (left->event_count() > right->event_count()) ||
((left->event_count() == right->event_count()) &&
((left->method() == nullptr) || (right->method() == nullptr) ||
(left->method()->name().compare(right->method()->name()) < 0)));
});
// Displays all the methods one after the other.
for (const auto& method : sorted_methods) {
if (method->method() != nullptr) {
printer << method->method()->name() << ": " << method->event_count()
<< ((method->event_count() == 1) ? " event" : " events") << '\n';
}
fidl_codec::Indent indent(printer);
for (const auto event : method->events()) {
event->Display(printer, /*with_channel=*/true);
}
}
}
} // namespace fidlcat