#include <sys/param.h>
#include <sys/cpuset.h>
#include <sys/event.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/ttycom.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <assert.h>
#include <curses.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <kvm.h>
#include <libgen.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include <pmc.h>
#include <pmclog.h>
#include <regex.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "cmd_pmc.h"
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "display.hh"
#include "view.hh"
class info_view : public pmcview
{
public:
virtual void
callchain(struct pmclog_ev_callchain &p)
{
uint64_t eventid = pmcidtoeventid(p.pl_pmcid);
pmcinfo[eventid].count++;
}
virtual void
print()
{
title("PMC Info");
header("System Info");
printf("CPU Model: %s\n", cpumodel.c_str());
printf("OS Release: %s\n", osrelease.c_str());
printf("Build ID: %s\n", buildid.c_str());
printf("\n");
if (arch == PMC_ARCH_AMD64) {
header("CPUID");
for (auto &c : cpuid)
printf("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
c.first, c.second.eax, c.second.ebx,
c.second.ecx, c.second.edx);
printf("\n");
}
header("PMC Info");
for (auto &p : extpmcinfo)
printf("%s\n", p.event.c_str());
printf("\n");
table t = table();
t.addcolumn("Counter", true);
t.addcolumn("Counts", true);
for (auto &p : pmcinfo) {
std::vector<field> r;
r.emplace_back(p.second.name);
r.emplace_back((int64_t)p.second.count);
t.addrow(r);
}
t.print();
}
};
static struct option longopts[] = {
PMCFILTER_LOPTS,
{ NULL, 0, NULL, 0 }
};
static void
usage(void)
{
printf("Usage: pmc info [options] [pmclog]\n\n");
printf("Display a log summary\n\n");
printf("Options:\n");
PMCFILTER_PRINTOPTS();
}
int
cmd_pmc_info(int argc, char **argv)
{
struct pmcfilter filter = pmcfilter();
const char *logfile = "default.log";
int option, logfd;
while ((option = getopt_long(argc, argv, PMCFILTER_SOPTS "s:", longopts, NULL)) != -1) {
switch (option) {
PMCFILTER_CASE(filter);
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc != 0 && argc != 1) {
usage();
exit(EX_USAGE);
}
if (argc == 1)
logfile = argv[0];
setup_screen();
if ((logfd = open(logfile, O_RDONLY)) < 0) {
errx(EX_OSERR, "ERROR: Cannot open \"%s\" for reading: %s.", logfile,
strerror(errno));
return (EX_NOINPUT);
}
info_view s = info_view();
s.setfilter(filter);
s.process(logfd);
s.print();
return (EX_OK);
}