2019-05-29 17:12:25 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-01-31 19:50:39 +03:00
/*
* Copyright ( C ) 2011 , Red Hat Inc , Arnaldo Carvalho de Melo < acme @ redhat . com >
*
* Refactored from builtin - top . c , see that files for further copyright notes .
*/
# include "event.h"
# include "evlist.h"
# include "evsel.h"
# include "parse-events.h"
# include "symbol.h"
# include "top.h"
2019-08-29 21:20:59 +03:00
# include "../perf.h"
2011-01-31 19:50:39 +03:00
# include <inttypes.h>
2011-03-07 23:13:40 +03:00
# define SNPRINTF(buf, size, fmt, args...) \
( { \
size_t r = snprintf ( buf , size , fmt , # # args ) ; \
r > size ? size : r ; \
} )
2011-01-31 19:50:39 +03:00
size_t perf_top__header_snprintf ( struct perf_top * top , char * bf , size_t size )
{
2013-05-14 06:09:00 +04:00
float samples_per_sec ;
float ksamples_per_sec ;
float esamples_percent ;
2013-12-19 21:43:45 +04:00
struct record_opts * opts = & top - > record_opts ;
2013-11-12 23:46:16 +04:00
struct target * target = & opts - > target ;
2011-01-31 19:50:39 +03:00
size_t ret = 0 ;
2013-05-14 06:09:00 +04:00
if ( top - > samples ) {
samples_per_sec = top - > samples / top - > delay_secs ;
ksamples_per_sec = top - > kernel_samples / top - > delay_secs ;
esamples_percent = ( 100.0 * top - > exact_samples ) / top - > samples ;
} else {
samples_per_sec = ksamples_per_sec = esamples_percent = 0.0 ;
}
2011-01-31 19:50:39 +03:00
if ( ! perf_guest ) {
2013-05-14 06:09:00 +04:00
float ksamples_percent = 0.0 ;
if ( samples_per_sec )
ksamples_percent = ( 100.0 * ksamples_per_sec ) /
samples_per_sec ;
2011-03-07 23:13:40 +03:00
ret = SNPRINTF ( bf , size ,
2011-01-31 19:50:39 +03:00
" PerfTop:%8.0f irqs/sec kernel:%4.1f%% "
2018-11-11 22:02:46 +03:00
" exact: %4.1f%% lost: % " PRIu64 " /% " PRIu64 " drop: % " PRIu64 " /% " PRIu64 " [ " ,
samples_per_sec , ksamples_percent , esamples_percent ,
top - > lost , top - > lost_total , top - > drop , top - > drop_total ) ;
2011-01-31 19:50:39 +03:00
} else {
float us_samples_per_sec = top - > us_samples / top - > delay_secs ;
float guest_kernel_samples_per_sec = top - > guest_kernel_samples / top - > delay_secs ;
float guest_us_samples_per_sec = top - > guest_us_samples / top - > delay_secs ;
2011-03-07 23:13:40 +03:00
ret = SNPRINTF ( bf , size ,
2011-01-31 19:50:39 +03:00
" PerfTop:%8.0f irqs/sec kernel:%4.1f%% us:%4.1f%% "
" guest kernel:%4.1f%% guest us:%4.1f%% "
" exact: %4.1f%% [ " , samples_per_sec ,
100.0 - ( 100.0 * ( ( samples_per_sec - ksamples_per_sec ) /
samples_per_sec ) ) ,
100.0 - ( 100.0 * ( ( samples_per_sec - us_samples_per_sec ) /
samples_per_sec ) ) ,
100.0 - ( 100.0 * ( ( samples_per_sec -
guest_kernel_samples_per_sec ) /
samples_per_sec ) ) ,
100.0 - ( 100.0 * ( ( samples_per_sec -
guest_us_samples_per_sec ) /
samples_per_sec ) ) ,
esamples_percent ) ;
}
2019-07-21 14:24:28 +03:00
if ( top - > evlist - > core . nr_entries = = 1 ) {
2019-09-03 11:39:52 +03:00
struct evsel * first = evlist__first ( top - > evlist ) ;
2011-03-07 23:13:40 +03:00
ret + = SNPRINTF ( bf + ret , size - ret , " % " PRIu64 " %s " ,
2019-07-21 14:24:29 +03:00
( uint64_t ) first - > core . attr . sample_period ,
2012-12-11 23:48:41 +04:00
opts - > freq ? " Hz " : " " ) ;
2011-01-31 19:50:39 +03:00
}
2012-06-12 19:34:58 +04:00
ret + = SNPRINTF ( bf + ret , size - ret , " %s " , perf_evsel__name ( top - > sym_evsel ) ) ;
2011-01-31 19:50:39 +03:00
2011-03-07 23:13:40 +03:00
ret + = SNPRINTF ( bf + ret , size - ret , " ], " ) ;
2011-01-31 19:50:39 +03:00
2012-12-11 23:48:41 +04:00
if ( target - > pid )
2012-02-08 20:32:52 +04:00
ret + = SNPRINTF ( bf + ret , size - ret , " (target_pid: %s " ,
2012-12-11 23:48:41 +04:00
target - > pid ) ;
else if ( target - > tid )
2012-02-08 20:32:52 +04:00
ret + = SNPRINTF ( bf + ret , size - ret , " (target_tid: %s " ,
2012-12-11 23:48:41 +04:00
target - > tid ) ;
else if ( target - > uid_str ! = NULL )
2012-01-19 20:08:15 +04:00
ret + = SNPRINTF ( bf + ret , size - ret , " (uid: %s " ,
2012-12-11 23:48:41 +04:00
target - > uid_str ) ;
2011-01-31 19:50:39 +03:00
else
2011-03-07 23:13:40 +03:00
ret + = SNPRINTF ( bf + ret , size - ret , " (all " ) ;
2011-01-31 19:50:39 +03:00
2012-12-11 23:48:41 +04:00
if ( target - > cpu_list )
2011-03-07 23:13:40 +03:00
ret + = SNPRINTF ( bf + ret , size - ret , " , CPU%s: %s) " ,
2019-07-21 14:24:41 +03:00
top - > evlist - > core . cpus - > nr > 1 ? " s " : " " ,
2012-12-11 23:48:41 +04:00
target - > cpu_list ) ;
2011-01-31 19:50:39 +03:00
else {
2012-12-11 23:48:41 +04:00
if ( target - > tid )
2011-03-07 23:13:40 +03:00
ret + = SNPRINTF ( bf + ret , size - ret , " ) " ) ;
2011-01-31 19:50:39 +03:00
else
2011-03-07 23:13:40 +03:00
ret + = SNPRINTF ( bf + ret , size - ret , " , %d CPU%s) " ,
2019-07-21 14:24:41 +03:00
top - > evlist - > core . cpus - > nr ,
top - > evlist - > core . cpus - > nr > 1 ? " s " : " " ) ;
2011-01-31 19:50:39 +03:00
}
2018-11-13 13:15:34 +03:00
perf_top__reset_sample_counters ( top ) ;
2011-01-31 19:50:39 +03:00
return ret ;
}
void perf_top__reset_sample_counters ( struct perf_top * top )
{
top - > samples = top - > us_samples = top - > kernel_samples =
top - > exact_samples = top - > guest_kernel_samples =
2018-11-11 22:02:46 +03:00
top - > guest_us_samples = top - > lost = top - > drop = 0 ;
2011-01-31 19:50:39 +03:00
}