diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
| -rw-r--r-- | tools/perf/builtin-stat.c | 48 | 
1 files changed, 28 insertions, 20 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 096ccb25c11f..22547a490e1f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -65,6 +65,7 @@  #include "util/tool.h"  #include "util/string2.h"  #include "util/metricgroup.h" +#include "util/top.h"  #include "asm/bug.h"  #include <linux/time64.h> @@ -144,6 +145,8 @@ static struct target target = {  typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu); +#define METRIC_ONLY_LEN 20 +  static int			run_count			=  1;  static bool			no_inherit			= false;  static volatile pid_t		child_pid			= -1; @@ -173,6 +176,7 @@ static struct cpu_map		*aggr_map;  static aggr_get_id_t		aggr_get_id;  static bool			append_file;  static bool			interval_count; +static bool			interval_clear;  static const char		*output_name;  static int			output_fd;  static int			print_free_counters_hint; @@ -180,6 +184,7 @@ static int			print_mixed_hw_group_error;  static u64			*walltime_run;  static bool			ru_display			= false;  static struct rusage		ru_data; +static unsigned int		metric_only_len			= METRIC_ONLY_LEN;  struct perf_stat {  	bool			 record; @@ -967,8 +972,6 @@ static void print_metric_csv(void *ctx,  	fprintf(out, "%s%s%s%s", csv_sep, vals, csv_sep, unit);  } -#define METRIC_ONLY_LEN 20 -  /* Filter out some columns that don't work well in metrics only mode */  static bool valid_only_metric(const char *unit) @@ -999,22 +1002,20 @@ static void print_metric_only(void *ctx, const char *color, const char *fmt,  {  	struct outstate *os = ctx;  	FILE *out = os->fh; -	int n; -	char buf[1024]; -	unsigned mlen = METRIC_ONLY_LEN; +	char buf[1024], str[1024]; +	unsigned mlen = metric_only_len;  	if (!valid_only_metric(unit))  		return;  	unit = fixunit(buf, os->evsel, unit); -	if (color) -		n = color_fprintf(out, color, fmt, val); -	else -		n = fprintf(out, fmt, val); -	if (n > METRIC_ONLY_LEN) -		n = METRIC_ONLY_LEN;  	if (mlen < strlen(unit))  		mlen = strlen(unit) + 1; -	fprintf(out, "%*s", mlen - n, ""); + +	if (color) +		mlen += strlen(color) + sizeof(PERF_COLOR_RESET) - 1; + +	color_snprintf(str, sizeof(str), color ?: "", fmt, val); +	fprintf(out, "%*s ", mlen, str);  }  static void print_metric_only_csv(void *ctx, const char *color __maybe_unused, @@ -1054,7 +1055,7 @@ static void print_metric_header(void *ctx, const char *color __maybe_unused,  	if (csv_output)  		fprintf(os->fh, "%s%s", unit, csv_sep);  	else -		fprintf(os->fh, "%-*s ", METRIC_ONLY_LEN, unit); +		fprintf(os->fh, "%*s ", metric_only_len, unit);  }  static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) @@ -1704,9 +1705,12 @@ static void print_interval(char *prefix, struct timespec *ts)  	FILE *output = stat_config.output;  	static int num_print_interval; +	if (interval_clear) +		puts(CONSOLE_CLEAR); +  	sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep); -	if (num_print_interval == 0 && !csv_output) { +	if ((num_print_interval == 0 && !csv_output) || interval_clear) {  		switch (stat_config.aggr_mode) {  		case AGGR_SOCKET:  			fprintf(output, "#           time socket cpus"); @@ -1719,7 +1723,7 @@ static void print_interval(char *prefix, struct timespec *ts)  				fprintf(output, "             counts %*s events\n", unit_width, "unit");  			break;  		case AGGR_NONE: -			fprintf(output, "#           time CPU"); +			fprintf(output, "#           time CPU    ");  			if (!metric_only)  				fprintf(output, "                counts %*s events\n", unit_width, "unit");  			break; @@ -1738,7 +1742,7 @@ static void print_interval(char *prefix, struct timespec *ts)  		}  	} -	if (num_print_interval == 0 && metric_only) +	if ((num_print_interval == 0 && metric_only) || interval_clear)  		print_metric_headers(" ", true);  	if (++num_print_interval == 25)  		num_print_interval = 0; @@ -2057,6 +2061,8 @@ static const struct option stat_options[] = {  		    "(overhead is possible for values <= 100ms)"),  	OPT_INTEGER(0, "interval-count", &stat_config.times,  		    "print counts for fixed number of times"), +	OPT_BOOLEAN(0, "interval-clear", &interval_clear, +		    "clear screen in between new interval"),  	OPT_UINTEGER(0, "timeout", &stat_config.timeout,  		    "stop workload and print counts after a timeout period in ms (>= 10ms)"),  	OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode, @@ -2436,14 +2442,13 @@ static int add_default_attributes(void)  	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},  }; +	struct parse_events_error errinfo;  	/* Set attrs if no event is selected and !null_run: */  	if (null_run)  		return 0;  	if (transaction_run) { -		struct parse_events_error errinfo; -  		if (pmu_have_event("cpu", "cycles-ct") &&  		    pmu_have_event("cpu", "el-start"))  			err = parse_events(evsel_list, transaction_attrs, @@ -2454,6 +2459,7 @@ static int add_default_attributes(void)  					   &errinfo);  		if (err) {  			fprintf(stderr, "Cannot set up transaction events\n"); +			parse_events_print_error(&errinfo, transaction_attrs);  			return -1;  		}  		return 0; @@ -2479,10 +2485,11 @@ static int add_default_attributes(void)  		    pmu_have_event("msr", "smi")) {  			if (!force_metric_only)  				metric_only = true; -			err = parse_events(evsel_list, smi_cost_attrs, NULL); +			err = parse_events(evsel_list, smi_cost_attrs, &errinfo);  		} else {  			fprintf(stderr, "To measure SMI cost, it needs "  				"msr/aperf/, msr/smi/ and cpu/cycles/ support\n"); +			parse_events_print_error(&errinfo, smi_cost_attrs);  			return -1;  		}  		if (err) { @@ -2517,12 +2524,13 @@ static int add_default_attributes(void)  		if (topdown_attrs[0] && str) {  			if (warn)  				arch_topdown_group_warn(); -			err = parse_events(evsel_list, str, NULL); +			err = parse_events(evsel_list, str, &errinfo);  			if (err) {  				fprintf(stderr,  					"Cannot set up top down events %s: %d\n",  					str, err);  				free(str); +				parse_events_print_error(&errinfo, str);  				return -1;  			}  		} else {  | 
