summary.c revision 2834f72014dc8b13ba13b9a06da744dd023f3555
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. 4 * Copyright (C) 2003,2008,2009 Juan Cespedes 5 * Copyright (C) 2006 Ian Wienand 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22 23#include "config.h" 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <sys/time.h> 28 29#include "common.h" 30 31struct entry_st { 32 const char *name; 33 unsigned count; 34 struct timeval tv; 35}; 36 37struct fill_struct_data { 38 struct vect entries; 39 unsigned tot_count; 40 unsigned long tot_usecs; 41}; 42 43static enum callback_status 44fill_struct(const char **namep, struct opt_c_struct *st, void *u) 45{ 46 struct fill_struct_data *data = u; 47 struct entry_st entry = { *namep, st->count, st->tv }; 48 if (VECT_PUSHBACK(&data->entries, &entry) < 0) 49 return CBS_STOP; 50 51 data->tot_count += st->count; 52 data->tot_usecs += 1000000 * st->tv.tv_sec; 53 data->tot_usecs += st->tv.tv_usec; 54 return CBS_CONT; 55} 56 57static int 58compar(const struct entry_st *en1, const struct entry_st *en2) 59{ 60 if (en2->tv.tv_sec - en1->tv.tv_sec) 61 return en2->tv.tv_sec - en1->tv.tv_sec; 62 else 63 return en2->tv.tv_usec - en1->tv.tv_usec; 64} 65 66static enum callback_status 67dump_one(struct entry_st *entry, void *u) 68{ 69 struct fill_struct_data *data = u; 70 unsigned long long int c; 71 unsigned long long int p; 72 c = 1000000 * (int)entry->tv.tv_sec + 73 (int)entry->tv.tv_usec; 74 p = 100000 * c / data->tot_usecs + 5; 75 fprintf(options.output, "%3lu.%02lu %4d.%06d %11lu %9d %s\n", 76 (unsigned long int)(p / 1000), 77 (unsigned long int)((p / 10) % 100), 78 (int)entry->tv.tv_sec, (int)entry->tv.tv_usec, 79 (unsigned long int)(c / entry->count), 80 entry->count, 81#ifdef USE_DEMANGLE 82 options.demangle ? my_demangle(entry->name) : 83#endif 84 entry->name); 85 86 return CBS_CONT; 87} 88 89void 90show_summary(void) 91{ 92 struct fill_struct_data cdata = {}; 93 VECT_INIT(&cdata.entries, struct entry_st); 94 95 if (dict_opt_c != NULL) { 96 DICT_EACH(dict_opt_c, const char *, struct opt_c_struct, NULL, 97 fill_struct, &cdata); 98 99 VECT_QSORT(&cdata.entries, struct entry_st, &compar); 100 } 101 102 fprintf(options.output, 103 "%% time seconds usecs/call calls function\n"); 104 fprintf(options.output, 105 "------ ----------- ----------- --------- --------------------\n"); 106 107 VECT_EACH(&cdata.entries, struct entry_st, NULL, dump_one, &cdata); 108 109 fprintf(options.output, 110 "------ ----------- ----------- --------- --------------------\n"); 111 fprintf(options.output, "100.00 %4lu.%06lu %9d total\n", 112 cdata.tot_usecs / 1000000, 113 cdata.tot_usecs % 1000000, cdata.tot_count); 114 115 vect_destroy(&cdata.entries, NULL, NULL); 116} 117