155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <stdio.h> 255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <unistd.h> 355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <stdlib.h> 455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <inttypes.h> 555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <string.h> 655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "trace_reader.h" 755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "parse_options.h" 855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projecttypedef TraceReader<> TraceReaderType; 1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "parse_options-inl.h" 1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project// This function is called from quicksort to compare the cpu time 1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project// of processes and sort into decreasing order. 1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectint cmp_dec_cpu_time(const void *a, const void *b) { 1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ProcessState *proc1, *proc2; 1755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project proc1 = (ProcessState*)a; 1955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project proc2 = (ProcessState*)b; 2055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (proc1 == NULL) { 2155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (proc2 == NULL) 2255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return 0; 2355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return 1; 2455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 2555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (proc2 == NULL) 2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return -1; 2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (proc1->cpu_time < proc2->cpu_time) 2855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return 1; 2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (proc1->cpu_time > proc2->cpu_time) 3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return -1; 3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // If the cpu_time times are the same, then sort into increasing 3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // order of pid. 3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return proc1->pid - proc2->pid; 3455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} 3555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 3655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectvoid Usage(const char *program) 3755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project{ 3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project fprintf(stderr, "Usage: %s [options] trace_file\n", program); 3955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project OptionsUsage(); 4055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} 4155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 4255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectint main(int argc, char **argv) { 4355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Parse the options 4455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ParseOptions(argc, argv); 4555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (argc - optind != 1) { 4655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Usage(argv[0]); 4755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project exit(1); 4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 4955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project char *trace_filename = argv[optind]; 5155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project TraceReader<> *trace = new TraceReader<>; 5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Open(trace_filename); 5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->SetRoot(root); 5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project while (1) { 5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project BBEvent event, ignored; 5755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project symbol_type *dummy_sym; 5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (GetNextValidEvent(trace, &event, &ignored, &dummy_sym)) 6055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project break; 6155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 6255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 6355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int num_procs; 6455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ProcessState *processes = trace->GetProcesses(&num_procs); 6555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project qsort(processes, num_procs, sizeof(ProcessState), cmp_dec_cpu_time); 6655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 6755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint64_t total_time = 0; 6855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project for (int ii = 0; ii < num_procs; ++ii) { 6955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project total_time += processes[ii].cpu_time; 7055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 7155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 7255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint64_t sum_time = 0; 7355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project printf(" pid parent cpu_time %% %% flags argv\n"); 7455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ProcessState *pstate = &processes[0]; 7555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project for (int ii = 0; ii < num_procs; ++ii, ++pstate) { 7655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project sum_time += pstate->cpu_time; 7755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project double per = 100.0 * pstate->cpu_time / total_time; 7855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project double sum_per = 100.0 * sum_time / total_time; 79d4d5b4f63a5760b2212166f539f906edda0bc4deJack Veenstra const char *print_flags = ""; 8055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if ((pstate->flags & ProcessState::kCalledExec) == 0) 8155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project print_flags = "T"; 8255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (pstate->name == NULL) 8355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project pstate->name = ""; 8455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project printf("%5d %5d %10llu %6.2f %6.2f %5s %s", 8555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project pstate->pid, pstate->parent_pid, pstate->cpu_time, 8655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project per, sum_per, print_flags, pstate->name); 87c627baa5fe13370895cb36cbff1300bad8bc96deJack Veenstra for (int jj = 1; jj < pstate->argc; ++jj) { 88c627baa5fe13370895cb36cbff1300bad8bc96deJack Veenstra printf(" %s", pstate->argv[jj]); 8955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 9055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project printf("\n"); 9155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 92c627baa5fe13370895cb36cbff1300bad8bc96deJack Veenstra delete trace; 9355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return 0; 9455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} 95