1#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <inttypes.h>
5#include <string.h>
6#include "trace_reader.h"
7#include "parse_options.h"
8
9typedef TraceReader<> TraceReaderType;
10
11#include "parse_options-inl.h"
12
13// This function is called from quicksort to compare the cpu time
14// of processes and sort into decreasing order.
15int cmp_dec_cpu_time(const void *a, const void *b) {
16  ProcessState *proc1, *proc2;
17
18  proc1 = (ProcessState*)a;
19  proc2 = (ProcessState*)b;
20  if (proc1 == NULL) {
21    if (proc2 == NULL)
22      return 0;
23    return 1;
24  }
25  if (proc2 == NULL)
26    return -1;
27  if (proc1->cpu_time < proc2->cpu_time)
28    return 1;
29  if (proc1->cpu_time > proc2->cpu_time)
30    return -1;
31  // If the cpu_time times are the same, then sort into increasing
32  // order of pid.
33  return proc1->pid - proc2->pid;
34}
35
36void Usage(const char *program)
37{
38  fprintf(stderr, "Usage: %s [options] trace_file\n", program);
39  OptionsUsage();
40}
41
42int main(int argc, char **argv) {
43  // Parse the options
44  ParseOptions(argc, argv);
45  if (argc - optind != 1) {
46    Usage(argv[0]);
47    exit(1);
48  }
49
50  char *trace_filename = argv[optind];
51  TraceReader<> *trace = new TraceReader<>;
52  trace->Open(trace_filename);
53  trace->SetRoot(root);
54
55  while (1) {
56    BBEvent event, ignored;
57    symbol_type *dummy_sym;
58
59    if (GetNextValidEvent(trace, &event, &ignored, &dummy_sym))
60      break;
61  }
62
63  int num_procs;
64  ProcessState *processes = trace->GetProcesses(&num_procs);
65  qsort(processes, num_procs, sizeof(ProcessState), cmp_dec_cpu_time);
66
67  uint64_t total_time = 0;
68  for (int ii = 0; ii < num_procs; ++ii) {
69    total_time += processes[ii].cpu_time;
70  }
71
72  uint64_t sum_time = 0;
73  printf("  pid parent   cpu_time      %%      %% flags argv\n");
74  ProcessState *pstate = &processes[0];
75  for (int ii = 0; ii < num_procs; ++ii, ++pstate) {
76    sum_time += pstate->cpu_time;
77    double per = 100.0 * pstate->cpu_time / total_time;
78    double sum_per = 100.0 * sum_time / total_time;
79    const char *print_flags = "";
80    if ((pstate->flags & ProcessState::kCalledExec) == 0)
81      print_flags = "T";
82    if (pstate->name == NULL)
83      pstate->name = "";
84    printf("%5d  %5d %10llu %6.2f %6.2f %5s %s",
85           pstate->pid, pstate->parent_pid, pstate->cpu_time,
86           per, sum_per, print_flags, pstate->name);
87    for (int jj = 1; jj < pstate->argc; ++jj) {
88      printf(" %s", pstate->argv[jj]);
89    }
90    printf("\n");
91  }
92  delete trace;
93  return 0;
94}
95