perf stat: Make some of the stat code generic
Jiri Olsa
reviewercover perf stat: Make some of the stat code generic
hi,
while going for the ability to store/display stat data in perf record/top I ended up with bunch of generic patches that make some of the stat functions standalone and simplify/reduce the builtin-stat.c code.
This patchset mostly separates the display functions into separate object, plus several other functions.
Also available in here:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/fixes
thanks,
jirka
---
Jiri Olsa (43):
perf stat: Use evsel->threads in create_perf_stat_counter
perf stat: Move initial_delay into struct perf_stat_config
perf stat: Move no_inherit into struct perf_stat_config
perf stat: Use local config arg for scale in create_perf_stat_counter perf stat: Add identifier flag into struct stat_opts
perf tools: Switch session argument to evlist in perf_event__synthesize_attrs perf tools: Add perf_evsel__store_ids function
perf stat: Move create_perf_stat_counter into stat.c
perf stat: Rename is_pipe argument to attrs perf_stat_synthesize_config perf stat: Add struct perf_stat_config argument to perf_stat_synthesize_config perf stat: Add struct perf_tool argument to perf_stat_synthesize_config perf stat: Add struct perf_evlist argument to perf_stat_synthesize_config perf stat: Add perf_event__handler_t argument to perf_stat_synthesize_config perf stat: Move perf_stat_synthesize_config into stat.c
perf stat: Add perf_evlist__print_counters function
perf stat: Move STAT_RECORD out of perf_evlist__print_counters perf stat: Add stat_config argument to perf_evlist__print_counters perf stat: Pass stat_config argument to local print functions perf stat: Pass stat_config argument to global print functions perf stat: Move csv_* into struct perf_stat_config
perf stat: Move interval_clear into struct perf_stat_config
perf stat: Move metric_only into struct perf_stat_config
perf stat: Move unit_width into struct perf_stat_config
perf stat: Add target argument to perf_evlist__print_counters perf stat: Pass evlist argument to print functions
perf stat: Use evsel->evlist instead of evsel_list in collect_all_aliases perf stat: Move run_count into struct perf_stat_config
perf stat: Move metric_only_len into struct perf_stat_config perf stat: Pass stat_config to first_shadow_cpu
perf stat: Pass evlist to aggr_update_shadow
perf stat: Add walltime_nsecs_stats pointer into struct perf_stat_config perf stat: Move null_run into struct perf_stat_config
perf stat: Move print_free_counters_hint into struct perf_stat_config perf stat: Move print_mixed_hw_group_error into struct perf_stat_config perf stat: Move ru_* data into struct perf_stat_config
perf stat: Move *_aggr_* data into struct perf_stat_config
perf stat: Do not use glovab evsel_list in print functions
perf stat: Move big_num data into struct perf_stat_config
perf stat: Move no_merge data into struct perf_stat_config
perf stat: Propagate struct target arg to sort_aggr_thread
perf stat: Move walltime_* data into struct perf_stat_config perf stat: Move metric_events into struct perf_stat_config
perf stat: Move display functions into stat-display.c
tools/perf/builtin-record.c | 2 +- tools/perf/builtin-script.c | 8 +- tools/perf/builtin-stat.c | 1440 +++++++++-------------------------------------------------------------------------------------------------------------- tools/perf/util/Build | 1 + tools/perf/util/evsel.c | 29 +++ tools/perf/util/evsel.h | 1 + tools/perf/util/header.c | 6 +- tools/perf/util/header.h | 2 +- tools/perf/util/stat-display.c | 1166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat-shadow.c | 147 +++++++------ tools/perf/util/stat.c | 95 ++++++++ tools/perf/util/stat.h | 72 +++++- 12 files changed, 1545 insertions(+), 1424 deletions(-) create mode 100644 tools/perf/util/stat-display.c
Jiri Olsa
reviewerPATCH 1/43 perf stat: Use evsel->threads in create_perf_stat_counter
Getting rid of the evsel_list dependency, here we can use the evsel->threads copy of the struct thread_map.
--- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
@@ -293,7 +293,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)if (target__has_cpu (&target) && !target__has_per_thread (&target))return perf_evsel__open_per_cpu (evsel,perf_evsel__cpus (evsel)); -return perf_evsel__open_per_thread (evsel, evsel_list->threads); +return perf_evsel__open_per_thread (evsel, evsel->threads); } static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Use evsel->threads in create_perf_stat_counter()
perf stat: Use evsel->threads in create_perf_stat_counter()
Commit-ID: d50ed0ce820414dbe249a6ad5c9830e29cc46fcc Gitweb: https://git.kernel.org/tip/d50ed0ce820414dbe249a6ad5c9830e29cc46fcc Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:10 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf stat: Use evsel->threads in create_perf_stat_counter()
Get rid of the evsel_list dependency, here we can use the evsel->threads copy of the struct thread_map.
--- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
@@ -293,7 +293,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)if (target__has_cpu (&target) && !target__has_per_thread (&target))return perf_evsel__open_per_cpu (evsel,perf_evsel__cpus (evsel)); -return perf_evsel__open_per_thread (evsel, evsel_list->threads); +return perf_evsel__open_per_thread (evsel, evsel->threads); } static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
Jiri Olsa
reviewerPATCH 2/43 perf stat: Move initial_delay into struct perf_stat_config
In reply to Jiri OlsaMoving static initial_delay into struct perf_stat_config, so it can be passed around and used outside stat command.
Adding struct perf_stat_config argument into create_perf_stat_counter function and using its initial_delay instead of static one.
--- tools/perf/builtin-stat.c | 16 ++++++++-------- tools/perf/util/stat.h | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-)
tools/perf/builtin-stat.c +8 -8
@@ -164,7 +164,6 @@ static bool group = false;static const char *pre_cmd =NULL ;static const char *post_cmd =NULL ;static bool sync_run = false; -static unsigned int initial_delay =0 ;static unsigned int unit_width =4 ;/* strlen("unit") */ static bool forever = false;static bool metric_only = false;
@@ -236,7 +235,8 @@ static void perf_stat__reset_stats(void)perf_stat__reset_shadow_per_stat (&stat_config.stats[i]); } -static int create_perf_stat_counter (struct perf_evsel *evsel) +static int create_perf_stat_counter (struct perf_evsel *evsel, +struct perf_stat_config *config) {struct perf_event_attr *attr = &evsel->attr;struct perf_evsel *leader = evsel->leader;
@@ -286,7 +286,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)* In case of initial_delay we enable tracee * events manually. */ -if (target__none (&target) && !initial_delay) +if (target__none (&target) && !config->initial_delay) attr->enable_on_exec =1 ; }
@@ -428,15 +428,15 @@ static void process_interval(void)static void enable_counters (void ) { -if (initial_delay) -usleep (initial_delay *USEC_PER_MSEC ); +if (stat_config.initial_delay) +usleep (stat_config.initial_delay *USEC_PER_MSEC );/* * We need to enable counters only if: * - we don't have tracee (attaching to task or cpu) * - we have initial delay configured */ -if (!target__none (&target) || initial_delay) +if (!target__none (&target) || stat_config.initial_delay)perf_evlist__enable (evsel_list); }
@@ -609,7 +609,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)evlist__for_each_entry (evsel_list, counter) { try_again: -if (create_perf_stat_counter (counter) <0 ) { +if (create_perf_stat_counter (counter, &stat_config) <0 ) {/* Weak group failed. Reset the group. */ if ((errno == EINVAL || errno == EBADF) &&
@@ -2027,7 +2027,7 @@ static const struct option stat_options[] = { "aggregate counts per physical processor core", AGGR_CORE),OPT_SET_UINT (0 ,"per-thread" , &stat_config.aggr_mode,"aggregate counts per thread" ,AGGR_THREAD ), -OPT_UINTEGER ('D' ,"delay" , &initial_delay, +OPT_UINTEGER ('D' ,"delay" , &stat_config.initial_delay,"ms to wait before starting measurement after program start" ),OPT_CALLBACK_NOOPT (0 ,"metric-only" , &metric_only,NULL , "Only print computed metrics. No raw values", enable_metric_only),
tools/perf/util/stat.h +10 -8
@@ -6,6 +6,7 @@#include <stdio.h> #include "xyarray.h" #include "rblist.h" +#include "perf.h" struct stats {double n, mean, M2;
@@ -85,14 +86,15 @@ struct runtime_stat { };struct perf_stat_config { -enum aggr_mode aggr_mode; -bool scale; -FILE *output; -unsigned int interval; -unsigned int timeout; -int times; -struct runtime_stat *stats; -int stats_num; +enum aggr_mode aggr_mode; +bool scale; +FILE *output; +unsigned int interval; +unsigned int timeout; +unsigned int initial_delay; +int times; +struct runtime_stat *stats; +int stats_num; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'initial_delay' to 'struct perf_stat_config'
perf stat: Move 'initial_delay' to 'struct perf_stat_config'
Commit-ID: 728c0ee0a896fcb0957b496afdb78bf195397645 Gitweb: https://git.kernel.org/tip/728c0ee0a896fcb0957b496afdb78bf195397645 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:11 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf stat: Move 'initial_delay' to 'struct perf_stat_config'
Move the static 'initial_delay' variable to 'struct perf_stat_config', so it can be passed around and used outside the 'perf stat' command.
Add 'struct perf_stat_config' argument to create_perf_stat_counter() and use its 'initial_delay' member instead of the static one.
--- tools/perf/builtin-stat.c | 16 ++++++++-------- tools/perf/util/stat.h | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-)
tools/perf/builtin-stat.c +8 -8
@@ -164,7 +164,6 @@ static bool group = false;static const char *pre_cmd =NULL ;static const char *post_cmd =NULL ;static bool sync_run = false; -static unsigned int initial_delay =0 ;static unsigned int unit_width =4 ;/* strlen("unit") */ static bool forever = false;static bool metric_only = false;
@@ -236,7 +235,8 @@ static void perf_stat__reset_stats(void)perf_stat__reset_shadow_per_stat (&stat_config.stats[i]); } -static int create_perf_stat_counter (struct perf_evsel *evsel) +static int create_perf_stat_counter (struct perf_evsel *evsel, +struct perf_stat_config *config) {struct perf_event_attr *attr = &evsel->attr;struct perf_evsel *leader = evsel->leader;
@@ -286,7 +286,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)* In case of initial_delay we enable tracee * events manually. */ -if (target__none (&target) && !initial_delay) +if (target__none (&target) && !config->initial_delay) attr->enable_on_exec =1 ; }
@@ -428,15 +428,15 @@ static void process_interval(void)static void enable_counters (void ) { -if (initial_delay) -usleep (initial_delay *USEC_PER_MSEC ); +if (stat_config.initial_delay) +usleep (stat_config.initial_delay *USEC_PER_MSEC );/* * We need to enable counters only if: * - we don't have tracee (attaching to task or cpu) * - we have initial delay configured */ -if (!target__none (&target) || initial_delay) +if (!target__none (&target) || stat_config.initial_delay)perf_evlist__enable (evsel_list); }
@@ -609,7 +609,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)evlist__for_each_entry (evsel_list, counter) { try_again: -if (create_perf_stat_counter (counter) <0 ) { +if (create_perf_stat_counter (counter, &stat_config) <0 ) {/* Weak group failed. Reset the group. */ if ((errno == EINVAL || errno == EBADF) &&
@@ -2027,7 +2027,7 @@ static const struct option stat_options[] = { "aggregate counts per physical processor core", AGGR_CORE),OPT_SET_UINT (0 ,"per-thread" , &stat_config.aggr_mode,"aggregate counts per thread" ,AGGR_THREAD ), -OPT_UINTEGER ('D' ,"delay" , &initial_delay, +OPT_UINTEGER ('D' ,"delay" , &stat_config.initial_delay,"ms to wait before starting measurement after program start" ),OPT_CALLBACK_NOOPT (0 ,"metric-only" , &metric_only,NULL , "Only print computed metrics. No raw values", enable_metric_only),
tools/perf/util/stat.h +10 -8
@@ -6,6 +6,7 @@#include <stdio.h> #include "xyarray.h" #include "rblist.h" +#include "perf.h" struct stats {double n, mean, M2;
@@ -85,14 +86,15 @@ struct runtime_stat { };struct perf_stat_config { -enum aggr_mode aggr_mode; -bool scale; -FILE *output; -unsigned int interval; -unsigned int timeout; -int times; -struct runtime_stat *stats; -int stats_num; +enum aggr_mode aggr_mode; +bool scale; +FILE *output; +unsigned int interval; +unsigned int timeout; +unsigned int initial_delay; +int times; +struct runtime_stat *stats; +int stats_num; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 3/43 perf stat: Move no_inherit into struct perf_stat_config
In reply to Jiri OlsaMoving static no_inherit into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -148,7 +148,6 @@ typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);#define METRIC_ONLY_LEN 20static int run_count =1 ; -static bool no_inherit = false;static volatile pid_t child_pid =-1 ;static bool null_run = false;static int detailed_run =0 ;
@@ -254,7 +253,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,if (leader->nr_members >1 ) attr->read_format |=PERF_FORMAT_ID |PERF_FORMAT_GROUP ; - attr->inherit = !no_inherit; + attr->inherit = !config->no_inherit;/* * Some events get initialized with sample_(period/type) set,
@@ -1969,7 +1968,7 @@ static const struct option stat_options[] = { parse_events_option),OPT_CALLBACK (0 ,"filter" , &evsel_list,"filter" ,"event filter" , parse_filter), -OPT_BOOLEAN ('i' ,"no-inherit" , &no_inherit, +OPT_BOOLEAN ('i' ,"no-inherit" , &stat_config.no_inherit,"child tasks do not inherit counters" ),OPT_STRING ('p' ,"pid" , &target.pid,"pid" , "stat events on existing process id"),
tools/perf/util/stat.h +1 -0
@@ -88,6 +88,7 @@ struct runtime_stat {struct perf_stat_config {enum aggr_mode aggr_mode;bool scale; +bool no_inherit;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'no_inherit' to 'struct perf_stat_config'
perf stat: Move 'no_inherit' to 'struct perf_stat_config'
Commit-ID: 5698f26b46e4f47f2371418eb92732048fa4fa66 Gitweb: https://git.kernel.org/tip/5698f26b46e4f47f2371418eb92732048fa4fa66 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:12 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf stat: Move 'no_inherit' to 'struct perf_stat_config'
Move the static 'no_inherit' variable to 'struct perf_stat_config', so it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -148,7 +148,6 @@ typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);#define METRIC_ONLY_LEN 20static int run_count =1 ; -static bool no_inherit = false;static volatile pid_t child_pid =-1 ;static bool null_run = false;static int detailed_run =0 ;
@@ -254,7 +253,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,if (leader->nr_members >1 ) attr->read_format |=PERF_FORMAT_ID |PERF_FORMAT_GROUP ; - attr->inherit = !no_inherit; + attr->inherit = !config->no_inherit;/* * Some events get initialized with sample_(period/type) set,
@@ -1969,7 +1968,7 @@ static const struct option stat_options[] = { parse_events_option),OPT_CALLBACK (0 ,"filter" , &evsel_list,"filter" ,"event filter" , parse_filter), -OPT_BOOLEAN ('i' ,"no-inherit" , &no_inherit, +OPT_BOOLEAN ('i' ,"no-inherit" , &stat_config.no_inherit,"child tasks do not inherit counters" ),OPT_STRING ('p' ,"pid" , &target.pid,"pid" , "stat events on existing process id"),
tools/perf/util/stat.h +1 -0
@@ -88,6 +88,7 @@ struct runtime_stat {struct perf_stat_config {enum aggr_mode aggr_mode;bool scale; +bool no_inherit;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 4/43 perf stat: Use local config arg for scale in create_perf_stat_counter
In reply to Jiri OlsaUsing local scale from local 'struct perf_stat_config' argument instead of the global stat_config, to make the function independent.
--- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
@@ -240,7 +240,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,struct perf_event_attr *attr = &evsel->attr;struct perf_evsel *leader = evsel->leader; -if (stat_config.scale) { +if (config->scale) { attr->read_format =PERF_FORMAT_TOTAL_TIME_ENABLED |PERF_FORMAT_TOTAL_TIME_RUNNING ; }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Use local config arg for scale in create_perf_stat_counter()
perf stat: Use local config arg for scale in create_perf_stat_counter()
Commit-ID: 35386233fcf78f20cb8a51199518da9f81eca280 Gitweb: https://git.kernel.org/tip/35386233fcf78f20cb8a51199518da9f81eca280 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:13 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf stat: Use local config arg for scale in create_perf_stat_counter()
Use the local 'scale' member in the 'struct perf_stat_config' argument instead of the global 'stat_config' variable, to make the function independent.
--- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
@@ -240,7 +240,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,struct perf_event_attr *attr = &evsel->attr;struct perf_evsel *leader = evsel->leader; -if (stat_config.scale) { +if (config->scale) { attr->read_format =PERF_FORMAT_TOTAL_TIME_ENABLED |PERF_FORMAT_TOTAL_TIME_RUNNING ; }
Jiri Olsa
reviewerPATCH 5/43 perf stat: Add identifier flag into struct stat_opts
In reply to Jiri OlsaAdding identifier flag into struct stat_opts to carry the info whether to use PERF_SAMPLE_IDENTIFIER for events. It makes the create_perf_stat_counter function independent.
--- tools/perf/builtin-stat.c | 22 ++++++++++++---------- tools/perf/util/stat.h | 1 + 2 files changed, 13 insertions(+), 10 deletions(-)
tools/perf/builtin-stat.c +12 -10
@@ -261,16 +261,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,*/ attr->sample_period =0 ; -/* -* But set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless -* while avoiding that older tools show confusing messages. -* -* However for pipe sessions we need to keep it zero, -* because script's perf_evsel__check_attr is triggered -* by attr->sample_type != 0, and we can't run it on -* stat sessions. -*/ -if (!(STAT_RECORD && perf_stat.data.is_pipe)) +if (config->identifier) attr->sample_type =PERF_SAMPLE_IDENTIFIER ;/*
@@ -3064,6 +3055,17 @@ int cmd_stat(int argc, const char **argv)if (perf_stat_init_aggr_mode ()) goto out; +/* +* Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless +* while avoiding that older tools show confusing messages. +* +* However for pipe sessions we need to keep it zero, +* because script's perf_evsel__check_attr is triggered +* by attr->sample_type != 0, and we can't run it on +* stat sessions. +*/ + stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe); +/* * We dont want to block the signals - that would cause * child tasks to inherit that and Ctrl-C would not work.
tools/perf/util/stat.h +1 -0
@@ -89,6 +89,7 @@ struct perf_stat_config {enum aggr_mode aggr_mode;bool scale;bool no_inherit; +bool identifier;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'identifier' flag to 'struct perf_stat_config'
perf stat: Add 'identifier' flag to 'struct perf_stat_config'
Commit-ID: 7d9ad16afe2bfc73b8967cc2aa2dc30f0170a8e2 Gitweb: https://git.kernel.org/tip/7d9ad16afe2bfc73b8967cc2aa2dc30f0170a8e2 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:14 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf stat: Add 'identifier' flag to 'struct perf_stat_config'
Add 'identifier' flag to 'struct perf_stat_config' to carry the info whether to use PERF_SAMPLE_IDENTIFIER for events.
This makes create_perf_stat_counter() independent.
--- tools/perf/builtin-stat.c | 22 ++++++++++++---------- tools/perf/util/stat.h | 1 + 2 files changed, 13 insertions(+), 10 deletions(-)
tools/perf/builtin-stat.c +12 -10
@@ -261,16 +261,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,*/ attr->sample_period =0 ; -/* -* But set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless -* while avoiding that older tools show confusing messages. -* -* However for pipe sessions we need to keep it zero, -* because script's perf_evsel__check_attr is triggered -* by attr->sample_type != 0, and we can't run it on -* stat sessions. -*/ -if (!(STAT_RECORD && perf_stat.data.is_pipe)) +if (config->identifier) attr->sample_type =PERF_SAMPLE_IDENTIFIER ;/*
@@ -3064,6 +3055,17 @@ int cmd_stat(int argc, const char **argv)if (perf_stat_init_aggr_mode ()) goto out; +/* +* Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless +* while avoiding that older tools show confusing messages. +* +* However for pipe sessions we need to keep it zero, +* because script's perf_evsel__check_attr is triggered +* by attr->sample_type != 0, and we can't run it on +* stat sessions. +*/ + stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe); +/* * We dont want to block the signals - that would cause * child tasks to inherit that and Ctrl-C would not work.
tools/perf/util/stat.h +1 -0
@@ -89,6 +89,7 @@ struct perf_stat_config {enum aggr_mode aggr_mode;bool scale;bool no_inherit; +bool identifier;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 6/43 perf tools: Switch session argument to evlist in perf_event__synthesize_attrs
In reply to Jiri OlsaTo be able to pass in other than session's evlist.
--- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/util/header.c | 6 +++--- tools/perf/util/header.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-)
tools/perf/builtin-record.c +1 -1
@@ -758,7 +758,7 @@ static int record__synthesize(struct record *rec, bool tail)* We need to synthesize events first, because some * features works on top of them (on report side). */ - err =perf_event__synthesize_attrs (tool, session, + err =perf_event__synthesize_attrs (tool, rec->evlist, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
tools/perf/builtin-stat.c +1 -1
@@ -459,7 +459,7 @@ static int perf_stat_synthesize_config(bool is_pipe)int err;if (is_pipe) { - err =perf_event__synthesize_attrs (NULL , perf_stat.session, + err =perf_event__synthesize_attrs (NULL , evsel_list, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
tools/perf/util/header.c +3 -3
@@ -3637,13 +3637,13 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) }int perf_event__synthesize_attrs (struct perf_tool *tool, -struct perf_session *session, -perf_event__handler_t process) +struct perf_evlist *evlist, +perf_event__handler_t process) {struct perf_evsel *evsel;int err =0 ; -evlist__for_each_entry (session->evlist, evsel) { +evlist__for_each_entry (evlist, evsel) { err =perf_event__synthesize_attr (tool, &evsel->attr, evsel->ids, evsel->id, process);if (err) {
tools/perf/util/header.h +1 -1
@@ -124,7 +124,7 @@ int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process);int perf_event__synthesize_attrs (struct perf_tool *tool, -struct perf_session *session, +struct perf_evlist *evlist,perf_event__handler_t process); int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct perf_evsel *evsel,
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Switch 'session' argument to 'evlist' in perf_event__synthesize_attrs()
perf tools: Switch 'session' argument to 'evlist' in perf_event__synthesize_attrs()
Commit-ID: 318ec1841a3f26799fe663d8f979a57623c0c470 Gitweb: https://git.kernel.org/tip/318ec1841a3f26799fe663d8f979a57623c0c470 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:15 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf tools: Switch 'session' argument to 'evlist' in perf_event__synthesize_attrs()
To be able to pass in other than session's evlist.
--- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-stat.c | 2 +- tools/perf/util/header.c | 6 +++--- tools/perf/util/header.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-)
tools/perf/builtin-record.c +1 -1
@@ -758,7 +758,7 @@ static int record__synthesize(struct record *rec, bool tail)* We need to synthesize events first, because some * features works on top of them (on report side). */ - err =perf_event__synthesize_attrs (tool, session, + err =perf_event__synthesize_attrs (tool, rec->evlist, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
tools/perf/builtin-stat.c +1 -1
@@ -459,7 +459,7 @@ static int perf_stat_synthesize_config(bool is_pipe)int err;if (is_pipe) { - err =perf_event__synthesize_attrs (NULL , perf_stat.session, + err =perf_event__synthesize_attrs (NULL , evsel_list, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
tools/perf/util/header.c +3 -3
@@ -3637,13 +3637,13 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) }int perf_event__synthesize_attrs (struct perf_tool *tool, -struct perf_session *session, -perf_event__handler_t process) +struct perf_evlist *evlist, +perf_event__handler_t process) {struct perf_evsel *evsel;int err =0 ; -evlist__for_each_entry (session->evlist, evsel) { +evlist__for_each_entry (evlist, evsel) { err =perf_event__synthesize_attr (tool, &evsel->attr, evsel->ids, evsel->id, process);if (err) {
tools/perf/util/header.h +1 -1
@@ -124,7 +124,7 @@ int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process);int perf_event__synthesize_attrs (struct perf_tool *tool, -struct perf_session *session, +struct perf_evlist *evlist,perf_event__handler_t process); int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct perf_evsel *evsel,
Jiri Olsa
reviewerPATCH 7/43 perf tools: Add perf_evsel__store_ids function
In reply to Jiri OlsaAdding perf_evsel__store_ids function from stat'sstore_counter_ids code into evsel object, so it
could be used globaly.
--- tools/perf/builtin-stat.c | 33 +-------------------------------- tools/perf/util/evsel.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/evsel.h | 1 + 3 files changed, 31 insertions(+), 32 deletions(-)
tools/perf/builtin-stat.c +1 -32
@@ -497,37 +497,6 @@ static int perf_stat_synthesize_config(bool is_pipe)return 0 ; } -#define FD (e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) - -static int __store_counter_ids (struct perf_evsel *counter) -{ -int cpu, thread; - -for (cpu =0 ; cpu <xyarray__max_x (counter->fd); cpu++) { -for (thread =0 ; thread <xyarray__max_y (counter->fd); - thread++) { -int fd =FD (counter, cpu, thread); - -if (perf_evlist__id_add_fd (evsel_list, counter, - cpu, thread, fd) <0 ) -return -1 ; - } - } - -return 0 ; -} - -static int store_counter_ids (struct perf_evsel *counter) -{ -struct cpu_map *cpus = counter->cpus; -struct thread_map *threads = counter->threads; - -if (perf_evsel__alloc_id (counter, cpus->nr, threads->nr)) -return -ENOMEM ; - -return __store_counter_ids (counter); -} -static bool perf_evsel__should_store_id (struct perf_evsel *counter) {return STAT_RECORD || counter->attr.read_format &PERF_FORMAT_ID ;
@@ -658,7 +627,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) unit_width = l;if (perf_evsel__should_store_id (counter) && -store_counter_ids (counter)) +perf_evsel__store_ids (counter, evsel_list))return -1 ; }
tools/perf/util/evsel.c +29 -0
@@ -2940,3 +2940,32 @@ struct perf_env *perf_evsel__env(struct perf_evsel *evsel)return evsel->evlist->env;return NULL ; } + +static int store_evsel_ids (struct perf_evsel *evsel,struct perf_evlist *evlist) +{ +int cpu, thread; + +for (cpu =0 ; cpu <xyarray__max_x (evsel->fd); cpu++) { +for (thread =0 ; thread <xyarray__max_y (evsel->fd); + thread++) { +int fd =FD (evsel, cpu, thread); + +if (perf_evlist__id_add_fd (evlist, evsel, + cpu, thread, fd) <0 ) +return -1 ; + } + } + +return 0 ; +} + +int perf_evsel__store_ids (struct perf_evsel *evsel,struct perf_evlist *evlist) +{ +struct cpu_map *cpus = evsel->cpus; +struct thread_map *threads = evsel->threads; + +if (perf_evsel__alloc_id (evsel, cpus->nr, threads->nr)) +return -ENOMEM ; + +return store_evsel_ids (evsel, evlist); +}
tools/perf/util/evsel.h +1 -0
@@ -481,4 +481,5 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,struct perf_env *perf_evsel__env (struct perf_evsel *evsel); +int perf_evsel__store_ids (struct perf_evsel *evsel,struct perf_evlist *evlist);#endif /* __PERF_EVSEL_H */
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf evsel: Introduce perf_evsel__store_ids()
perf evsel: Introduce perf_evsel__store_ids()
Commit-ID: 650d622046024623e71fea1f28acf1edb7e61a81 Gitweb: https://git.kernel.org/tip/650d622046024623e71fea1f28acf1edb7e61a81 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:16 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:21 -0300
perf evsel: Introduce perf_evsel__store_ids()
Add perf_evsel__store_ids() from stat's store_counter_ids() code to the evsel class, so that it can be used globally.
--- tools/perf/builtin-stat.c | 33 +-------------------------------- tools/perf/util/evsel.c | 29 +++++++++++++++++++++++++++++ tools/perf/util/evsel.h | 1 + 3 files changed, 31 insertions(+), 32 deletions(-)
tools/perf/builtin-stat.c +1 -32
@@ -497,37 +497,6 @@ static int perf_stat_synthesize_config(bool is_pipe)return 0 ; } -#define FD (e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) - -static int __store_counter_ids (struct perf_evsel *counter) -{ -int cpu, thread; - -for (cpu =0 ; cpu <xyarray__max_x (counter->fd); cpu++) { -for (thread =0 ; thread <xyarray__max_y (counter->fd); - thread++) { -int fd =FD (counter, cpu, thread); - -if (perf_evlist__id_add_fd (evsel_list, counter, - cpu, thread, fd) <0 ) -return -1 ; - } - } - -return 0 ; -} - -static int store_counter_ids (struct perf_evsel *counter) -{ -struct cpu_map *cpus = counter->cpus; -struct thread_map *threads = counter->threads; - -if (perf_evsel__alloc_id (counter, cpus->nr, threads->nr)) -return -ENOMEM ; - -return __store_counter_ids (counter); -} -static bool perf_evsel__should_store_id (struct perf_evsel *counter) {return STAT_RECORD || counter->attr.read_format &PERF_FORMAT_ID ;
@@ -658,7 +627,7 @@ try_again: unit_width = l;if (perf_evsel__should_store_id (counter) && -store_counter_ids (counter)) +perf_evsel__store_ids (counter, evsel_list))return -1 ; }
tools/perf/util/evsel.c +29 -0
@@ -2940,3 +2940,32 @@ struct perf_env *perf_evsel__env(struct perf_evsel *evsel)return evsel->evlist->env;return NULL ; } + +static int store_evsel_ids (struct perf_evsel *evsel,struct perf_evlist *evlist) +{ +int cpu, thread; + +for (cpu =0 ; cpu <xyarray__max_x (evsel->fd); cpu++) { +for (thread =0 ; thread <xyarray__max_y (evsel->fd); + thread++) { +int fd =FD (evsel, cpu, thread); + +if (perf_evlist__id_add_fd (evlist, evsel, + cpu, thread, fd) <0 ) +return -1 ; + } + } + +return 0 ; +} + +int perf_evsel__store_ids (struct perf_evsel *evsel,struct perf_evlist *evlist) +{ +struct cpu_map *cpus = evsel->cpus; +struct thread_map *threads = evsel->threads; + +if (perf_evsel__alloc_id (evsel, cpus->nr, threads->nr)) +return -ENOMEM ; + +return store_evsel_ids (evsel, evlist); +}
tools/perf/util/evsel.h +1 -0
@@ -481,4 +481,5 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,struct perf_env *perf_evsel__env (struct perf_evsel *evsel); +int perf_evsel__store_ids (struct perf_evsel *evsel,struct perf_evlist *evlist);#endif /* __PERF_EVSEL_H */
Jiri Olsa
reviewerPATCH 8/43 perf stat: Move create_perf_stat_counter into stat.c
In reply to Jiri OlsaMoving create_perf_stat_counter to stat object,
so we could use it globally.
--- tools/perf/builtin-stat.c | 54 +-------------------------------------- tools/perf/util/stat.c | 53 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 4 +++ 3 files changed, 58 insertions(+), 53 deletions(-)
tools/perf/builtin-stat.c +1 -53
@@ -234,58 +234,6 @@ static void perf_stat__reset_stats(void)perf_stat__reset_shadow_per_stat (&stat_config.stats[i]); } -static int create_perf_stat_counter (struct perf_evsel *evsel, -struct perf_stat_config *config) -{ -struct perf_event_attr *attr = &evsel->attr; -struct perf_evsel *leader = evsel->leader; - -if (config->scale) { - attr->read_format =PERF_FORMAT_TOTAL_TIME_ENABLED | -PERF_FORMAT_TOTAL_TIME_RUNNING ; - } - -/* -* The event is part of non trivial group, let's enable -* the group read (for leader) and ID retrieval for all -* members. -*/ -if (leader->nr_members >1 ) - attr->read_format |=PERF_FORMAT_ID |PERF_FORMAT_GROUP ; - - attr->inherit = !config->no_inherit; - -/* -* Some events get initialized with sample_(period/type) set, -* like tracepoints. Clear it up for counting. -*/ - attr->sample_period =0 ; - -if (config->identifier) - attr->sample_type =PERF_SAMPLE_IDENTIFIER ; - -/* -* Disabling all counters initially, they will be enabled -* either manually by us or by kernel via enable_on_exec -* set later. -*/ -if (perf_evsel__is_group_leader (evsel)) { - attr->disabled =1 ; - -/* -* In case of initial_delay we enable tracee -* events manually. -*/ -if (target__none (&target) && !config->initial_delay) - attr->enable_on_exec =1 ; - } - -if (target__has_cpu (&target) && !target__has_per_thread (&target)) -return perf_evsel__open_per_cpu (evsel,perf_evsel__cpus (evsel)); - -return perf_evsel__open_per_thread (evsel, evsel->threads); -} - static int process_synthesized_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused,
@@ -568,7 +516,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)evlist__for_each_entry (evsel_list, counter) { try_again: -if (create_perf_stat_counter (counter, &stat_config) <0 ) { +if (create_perf_stat_counter (counter, &stat_config, &target) <0 ) {/* Weak group failed. Reset the group. */ if ((errno == EINVAL || errno == EBADF) &&
tools/perf/util/stat.c +53 -0
56 lines not on this page · raw message
tools/perf/util/stat.h +4 -0
@@ -175,4 +175,8 @@ int perf_event__process_stat_event(struct perf_tool *tool,size_t perf_event__fprintf_stat (union perf_event *event,FILE *fp);size_t perf_event__fprintf_stat_round (union perf_event *event,FILE *fp);size_t perf_event__fprintf_stat_config (union perf_event *event,FILE *fp); + +int create_perf_stat_counter (struct perf_evsel *evsel, +struct perf_stat_config *config, +struct target *target);#endif
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move create_perf_stat_counter() to stat.c
perf stat: Move create_perf_stat_counter() to stat.c
Commit-ID: d09cefd2ef9945b4b767bb67f473a0eb2066374f Gitweb: https://git.kernel.org/tip/d09cefd2ef9945b4b767bb67f473a0eb2066374f Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:17 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Move create_perf_stat_counter() to stat.c
Move create_perf_stat_counter() to the 'stat' class, so that we can use it globally.
--- tools/perf/builtin-stat.c | 54 +---------------------------------------------- tools/perf/util/stat.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 4 ++++ 3 files changed, 58 insertions(+), 53 deletions(-)
tools/perf/builtin-stat.c +1 -53
@@ -234,58 +234,6 @@ static void perf_stat__reset_stats(void)perf_stat__reset_shadow_per_stat (&stat_config.stats[i]); } -static int create_perf_stat_counter (struct perf_evsel *evsel, -struct perf_stat_config *config) -{ -struct perf_event_attr *attr = &evsel->attr; -struct perf_evsel *leader = evsel->leader; - -if (config->scale) { - attr->read_format =PERF_FORMAT_TOTAL_TIME_ENABLED | -PERF_FORMAT_TOTAL_TIME_RUNNING ; - } - -/* -* The event is part of non trivial group, let's enable -* the group read (for leader) and ID retrieval for all -* members. -*/ -if (leader->nr_members >1 ) - attr->read_format |=PERF_FORMAT_ID |PERF_FORMAT_GROUP ; - - attr->inherit = !config->no_inherit; - -/* -* Some events get initialized with sample_(period/type) set, -* like tracepoints. Clear it up for counting. -*/ - attr->sample_period =0 ; - -if (config->identifier) - attr->sample_type =PERF_SAMPLE_IDENTIFIER ; - -/* -* Disabling all counters initially, they will be enabled -* either manually by us or by kernel via enable_on_exec -* set later. -*/ -if (perf_evsel__is_group_leader (evsel)) { - attr->disabled =1 ; - -/* -* In case of initial_delay we enable tracee -* events manually. -*/ -if (target__none (&target) && !config->initial_delay) - attr->enable_on_exec =1 ; - } - -if (target__has_cpu (&target) && !target__has_per_thread (&target)) -return perf_evsel__open_per_cpu (evsel,perf_evsel__cpus (evsel)); - -return perf_evsel__open_per_thread (evsel, evsel->threads); -} - static int process_synthesized_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused,
@@ -568,7 +516,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)evlist__for_each_entry (evsel_list, counter) { try_again: -if (create_perf_stat_counter (counter, &stat_config) <0 ) { +if (create_perf_stat_counter (counter, &stat_config, &target) <0 ) {/* Weak group failed. Reset the group. */ if ((errno == EINVAL || errno == EBADF) &&
tools/perf/util/stat.c +53 -0
56 lines not on this page · raw message
tools/perf/util/stat.h +4 -0
@@ -175,4 +175,8 @@ int perf_event__process_stat_event(struct perf_tool *tool,size_t perf_event__fprintf_stat (union perf_event *event,FILE *fp);size_t perf_event__fprintf_stat_round (union perf_event *event,FILE *fp);size_t perf_event__fprintf_stat_config (union perf_event *event,FILE *fp); + +int create_perf_stat_counter (struct perf_evsel *evsel, +struct perf_stat_config *config, +struct target *target);#endif
Jiri Olsa
reviewerPATCH 9/43 perf stat: Rename is_pipe argument to attrs perf_stat_synthesize_config
In reply to Jiri OlsaThe attrs name makes more sense.
--- tools/perf/builtin-stat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
@@ -402,11 +402,11 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (bool is_pipe) +static int perf_stat_synthesize_config (bool attrs) {int err; -if (is_pipe) { +if (attrs) { err =perf_event__synthesize_attrs (NULL , evsel_list, process_synthesized_event);if (err <0 ) {
@@ -418,7 +418,7 @@ static int perf_stat_synthesize_config(bool is_pipe) err =perf_event__synthesize_extra_attr (NULL , evsel_list, process_synthesized_event, - is_pipe); + attrs); err = perf_event__synthesize_thread_map2(NULL, evsel_list->threads, process_synthesized_event,
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Rename 'is_pipe' argument to 'attrs' in perf_stat_synthesize_config()
perf stat: Rename 'is_pipe' argument to 'attrs' in perf_stat_synthesize_config()
Commit-ID: 491073a6126644d3c60b677b777006deb3c0e16b Gitweb: https://git.kernel.org/tip/491073a6126644d3c60b677b777006deb3c0e16b Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:18 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Rename 'is_pipe' argument to 'attrs' in perf_stat_synthesize_config()
The attrs name makes more sense.
--- tools/perf/builtin-stat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
@@ -402,11 +402,11 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (bool is_pipe) +static int perf_stat_synthesize_config (bool attrs) {int err; -if (is_pipe) { +if (attrs) { err =perf_event__synthesize_attrs (NULL , evsel_list, process_synthesized_event);if (err <0 ) {
@@ -418,7 +418,7 @@ static int perf_stat_synthesize_config(bool is_pipe) err =perf_event__synthesize_extra_attr (NULL , evsel_list, process_synthesized_event, - is_pipe); + attrs); err = perf_event__synthesize_thread_map2(NULL, evsel_list->threads, process_synthesized_event,
Jiri Olsa
reviewerPATCH 10/43 perf stat: Add struct perf_stat_config argument to perf_stat_synthesize_config
In reply to Jiri OlsaAdding struct perf_stat_config argument to perf_stat_synthesize_config, so we could synthesize arbitrary config.
--- tools/perf/builtin-stat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +4 -3
@@ -402,7 +402,8 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (bool attrs) +static int perf_stat_synthesize_config (struct perf_stat_config *config, +bool attrs) {int err;
@@ -435,7 +436,7 @@ static int perf_stat_synthesize_config(bool attrs)return err; } - err =perf_event__synthesize_stat_config (NULL , &stat_config, + err =perf_event__synthesize_stat_config (NULL , config, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize config.\n" );
@@ -606,7 +607,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (err <0 )return err; - err =perf_stat_synthesize_config (is_pipe); + err =perf_stat_synthesize_config (&stat_config, is_pipe);if (err <0 )return err; }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'struct perf_stat_config' argument to perf_stat_synthesize_config()
perf stat: Add 'struct perf_stat_config' argument to perf_stat_synthesize_config()
Commit-ID: 73d586c3917d5109bb547c16d90d0eb97203986a Gitweb: https://git.kernel.org/tip/73d586c3917d5109bb547c16d90d0eb97203986a Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:19 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Add 'struct perf_stat_config' argument to perf_stat_synthesize_config()
Add a 'struct perf_stat_config' argument to perf_stat_synthesize_config(), so we could synthesize arbitrary config.
--- tools/perf/builtin-stat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +4 -3
@@ -402,7 +402,8 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (bool attrs) +static int perf_stat_synthesize_config (struct perf_stat_config *config, +bool attrs) {int err;
@@ -435,7 +436,7 @@ static int perf_stat_synthesize_config(bool attrs)return err; } - err =perf_event__synthesize_stat_config (NULL , &stat_config, + err =perf_event__synthesize_stat_config (NULL , config, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize config.\n" );
@@ -606,7 +607,7 @@ try_again:if (err <0 )return err; - err =perf_stat_synthesize_config (is_pipe); + err =perf_stat_synthesize_config (&stat_config, is_pipe);if (err <0 )return err; }
Jiri Olsa
reviewerPATCH 11/43 perf stat: Add struct perf_tool argument to perf_stat_synthesize_config
In reply to Jiri OlsaSo we can use the function outside stat command
with standard synthesize functions, that take
struct perf_tool* argument.
--- tools/perf/builtin-stat.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
tools/perf/builtin-stat.c +7 -6
@@ -403,12 +403,13 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf }static int perf_stat_synthesize_config (struct perf_stat_config *config, +struct perf_tool *tool,bool attrs) {int err;if (attrs) { - err =perf_event__synthesize_attrs (NULL , evsel_list, + err =perf_event__synthesize_attrs (tool, evsel_list, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
@@ -416,12 +417,12 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config, } } - err =perf_event__synthesize_extra_attr (NULL , + err =perf_event__synthesize_extra_attr (tool, evsel_list, process_synthesized_event, attrs); - err =perf_event__synthesize_thread_map2 (NULL , evsel_list->threads, + err =perf_event__synthesize_thread_map2 (tool, evsel_list->threads, process_synthesized_event,NULL );if (err <0 ) {
@@ -429,14 +430,14 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config,return err; } - err =perf_event__synthesize_cpu_map (NULL , evsel_list->cpus, + err =perf_event__synthesize_cpu_map (tool, evsel_list->cpus, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );return err; } - err =perf_event__synthesize_stat_config (NULL , config, + err =perf_event__synthesize_stat_config (tool, config, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize config.\n" );
@@ -607,7 +608,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (err <0 )return err; - err =perf_stat_synthesize_config (&stat_config, is_pipe); + err =perf_stat_synthesize_config (&stat_config,NULL , is_pipe);if (err <0 )return err; }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'struct perf_tool' argument to perf_stat_synthesize_config()
perf stat: Add 'struct perf_tool' argument to perf_stat_synthesize_config()
Commit-ID: 1821f4eb480bdd3c7c2a1863431ba539c7b0c1f8 Gitweb: https://git.kernel.org/tip/1821f4eb480bdd3c7c2a1863431ba539c7b0c1f8 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:20 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Add 'struct perf_tool' argument to perf_stat_synthesize_config()
So that we can use the function outside the 'perf stat' command with standard synthesize functions, that take 'struct perf_tool *' argument.
--- tools/perf/builtin-stat.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
tools/perf/builtin-stat.c +7 -6
@@ -403,12 +403,13 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf }static int perf_stat_synthesize_config (struct perf_stat_config *config, +struct perf_tool *tool,bool attrs) {int err;if (attrs) { - err =perf_event__synthesize_attrs (NULL , evsel_list, + err =perf_event__synthesize_attrs (tool, evsel_list, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
@@ -416,12 +417,12 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config, } } - err =perf_event__synthesize_extra_attr (NULL , + err =perf_event__synthesize_extra_attr (tool, evsel_list, process_synthesized_event, attrs); - err =perf_event__synthesize_thread_map2 (NULL , evsel_list->threads, + err =perf_event__synthesize_thread_map2 (tool, evsel_list->threads, process_synthesized_event,NULL );if (err <0 ) {
@@ -429,14 +430,14 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config,return err; } - err =perf_event__synthesize_cpu_map (NULL , evsel_list->cpus, + err =perf_event__synthesize_cpu_map (tool, evsel_list->cpus, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );return err; } - err =perf_event__synthesize_stat_config (NULL , config, + err =perf_event__synthesize_stat_config (tool, config, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize config.\n" );
@@ -607,7 +608,7 @@ try_again:if (err <0 )return err; - err =perf_stat_synthesize_config (&stat_config, is_pipe); + err =perf_stat_synthesize_config (&stat_config,NULL , is_pipe);if (err <0 )return err; }
Jiri Olsa
reviewerPATCH 12/43 perf stat: Add struct perf_evlist argument to perf_stat_synthesize_config
In reply to Jiri OlsaGetting rid of the evsel_list dependency, here in function perf_stat_synthesize_config we are adding the evlist arg.
--- tools/perf/builtin-stat.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
tools/perf/builtin-stat.c +7 -6
@@ -404,12 +404,13 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *infstatic int perf_stat_synthesize_config (struct perf_stat_config *config,struct perf_tool *tool, +struct perf_evlist *evlist,bool attrs) {int err;if (attrs) { - err =perf_event__synthesize_attrs (tool, evsel_list, + err =perf_event__synthesize_attrs (tool, evlist, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
@@ -417,12 +418,11 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config, } } - err =perf_event__synthesize_extra_attr (tool, - evsel_list, + err =perf_event__synthesize_extra_attr (tool, evlist, process_synthesized_event, attrs); - err =perf_event__synthesize_thread_map2 (tool, evsel_list->threads, + err =perf_event__synthesize_thread_map2 (tool, evlist->threads, process_synthesized_event,NULL );if (err <0 ) {
@@ -430,7 +430,7 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config,return err; } - err =perf_event__synthesize_cpu_map (tool, evsel_list->cpus, + err =perf_event__synthesize_cpu_map (tool, evlist->cpus, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );
@@ -608,7 +608,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (err <0 )return err; - err =perf_stat_synthesize_config (&stat_config,NULL , is_pipe); + err =perf_stat_synthesize_config (&stat_config,NULL , evsel_list, + is_pipe);if (err <0 )return err; }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'struct perf_evlist' argument to perf_stat_synthesize_config()
perf stat: Add 'struct perf_evlist' argument to perf_stat_synthesize_config()
Commit-ID: 1c21e9899d6a9ea72d4d678faa7b0ec22bcf59a9 Gitweb: https://git.kernel.org/tip/1c21e9899d6a9ea72d4d678faa7b0ec22bcf59a9 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:21 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Add 'struct perf_evlist' argument to perf_stat_synthesize_config()
Get rid of the 'evsel_list' global variable dependency, here in perf_stat_synthesize_config() we are adding the 'evlist' arg.
--- tools/perf/builtin-stat.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
tools/perf/builtin-stat.c +7 -6
@@ -404,12 +404,13 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *infstatic int perf_stat_synthesize_config (struct perf_stat_config *config,struct perf_tool *tool, +struct perf_evlist *evlist,bool attrs) {int err;if (attrs) { - err =perf_event__synthesize_attrs (tool, evsel_list, + err =perf_event__synthesize_attrs (tool, evlist, process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );
@@ -417,12 +418,11 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config, } } - err =perf_event__synthesize_extra_attr (tool, - evsel_list, + err =perf_event__synthesize_extra_attr (tool, evlist, process_synthesized_event, attrs); - err =perf_event__synthesize_thread_map2 (tool, evsel_list->threads, + err =perf_event__synthesize_thread_map2 (tool, evlist->threads, process_synthesized_event,NULL );if (err <0 ) {
@@ -430,7 +430,7 @@ static int perf_stat_synthesize_config(struct perf_stat_config *config,return err; } - err =perf_event__synthesize_cpu_map (tool, evsel_list->cpus, + err =perf_event__synthesize_cpu_map (tool, evlist->cpus, process_synthesized_event,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );
@@ -608,7 +608,8 @@ try_again:if (err <0 )return err; - err =perf_stat_synthesize_config (&stat_config,NULL , is_pipe); + err =perf_stat_synthesize_config (&stat_config,NULL , evsel_list, + is_pipe);if (err <0 )return err; }
Jiri Olsa
reviewerPATCH 13/43 perf stat: Add perf_event__handler_t argument to perf_stat_synthesize_config
In reply to Jiri OlsaSo it's completely independent and can be
used outside stat command.
--- tools/perf/builtin-stat.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
tools/perf/builtin-stat.c +7 -10
@@ -405,40 +405,37 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *infstatic int perf_stat_synthesize_config (struct perf_stat_config *config,struct perf_tool *tool,struct perf_evlist *evlist, +perf_event__handler_t process,bool attrs) {int err;if (attrs) { - err =perf_event__synthesize_attrs (tool, evlist, - process_synthesized_event); + err =perf_event__synthesize_attrs (tool, evlist, process);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );return err; } } - err =perf_event__synthesize_extra_attr (tool, evlist, - process_synthesized_event, + err =perf_event__synthesize_extra_attr (tool, evlist, process, attrs); err =perf_event__synthesize_thread_map2 (tool, evlist->threads, - process_synthesized_event, -NULL ); + process,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );return err; } err =perf_event__synthesize_cpu_map (tool, evlist->cpus, - process_synthesized_event,NULL ); + process,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );return err; } - err =perf_event__synthesize_stat_config (tool, config, - process_synthesized_event,NULL ); + err =perf_event__synthesize_stat_config (tool, config, process,NULL );if (err <0 ) {pr_err ("Couldn't synthesize config.\n" );return err;
@@ -609,7 +606,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)return err; err =perf_stat_synthesize_config (&stat_config,NULL , evsel_list, - is_pipe); + process_synthesized_event, is_pipe);if (err <0 )return err; }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'perf_event__handler_t' argument to perf_stat_synthesize_config()
perf stat: Add 'perf_event__handler_t' argument to perf_stat_synthesize_config()
Commit-ID: c2c247f2dd87706961fa16d033f9dbf173145e70 Gitweb: https://git.kernel.org/tip/c2c247f2dd87706961fa16d033f9dbf173145e70 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:22 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Add 'perf_event__handler_t' argument to perf_stat_synthesize_config()
So that it's completely independent and can be used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
tools/perf/builtin-stat.c +7 -10
@@ -405,40 +405,37 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *infstatic int perf_stat_synthesize_config (struct perf_stat_config *config,struct perf_tool *tool,struct perf_evlist *evlist, +perf_event__handler_t process,bool attrs) {int err;if (attrs) { - err =perf_event__synthesize_attrs (tool, evlist, - process_synthesized_event); + err =perf_event__synthesize_attrs (tool, evlist, process);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );return err; } } - err =perf_event__synthesize_extra_attr (tool, evlist, - process_synthesized_event, + err =perf_event__synthesize_extra_attr (tool, evlist, process, attrs); err =perf_event__synthesize_thread_map2 (tool, evlist->threads, - process_synthesized_event, -NULL ); + process,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );return err; } err =perf_event__synthesize_cpu_map (tool, evlist->cpus, - process_synthesized_event,NULL ); + process,NULL );if (err <0 ) {pr_err ("Couldn't synthesize thread map.\n" );return err; } - err =perf_event__synthesize_stat_config (tool, config, - process_synthesized_event,NULL ); + err =perf_event__synthesize_stat_config (tool, config, process,NULL );if (err <0 ) {pr_err ("Couldn't synthesize config.\n" );return err;
@@ -609,7 +606,7 @@ try_again:return err; err =perf_stat_synthesize_config (&stat_config,NULL , evsel_list, - is_pipe); + process_synthesized_event, is_pipe);if (err <0 )return err; }
Jiri Olsa
reviewerPATCH 14/43 perf stat: Move perf_stat_synthesize_config into stat.c
In reply to Jiri OlsaSo it can be used globaly.
--- tools/perf/builtin-stat.c | 42 --------------------------------------- tools/perf/util/stat.c | 42 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 6 ++++++ 3 files changed, 48 insertions(+), 42 deletions(-)
tools/perf/builtin-stat.c +0 -42
@@ -402,48 +402,6 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (struct perf_stat_config *config, -struct perf_tool *tool, -struct perf_evlist *evlist, -perf_event__handler_t process, -bool attrs) -{ -int err; - -if (attrs) { - err =perf_event__synthesize_attrs (tool, evlist, process); -if (err <0 ) { -pr_err ("Couldn't synthesize attrs.\n" ); -return err; - } - } - - err =perf_event__synthesize_extra_attr (tool, evlist, process, - attrs); - - err =perf_event__synthesize_thread_map2 (tool, evlist->threads, - process,NULL ); -if (err <0 ) { -pr_err ("Couldn't synthesize thread map.\n" ); -return err; - } - - err =perf_event__synthesize_cpu_map (tool, evlist->cpus, - process,NULL ); -if (err <0 ) { -pr_err ("Couldn't synthesize thread map.\n" ); -return err; - } - - err =perf_event__synthesize_stat_config (tool, config, process,NULL ); -if (err <0 ) { -pr_err ("Couldn't synthesize config.\n" ); -return err; - } - -return 0 ; -} -static bool perf_evsel__should_store_id (struct perf_evsel *counter) {return STAT_RECORD || counter->attr.read_format &PERF_FORMAT_ID ;
tools/perf/util/stat.c +42 -0
45 lines not on this page · raw message
tools/perf/util/stat.h +6 -0
@@ -7,6 +7,7 @@#include "xyarray.h" #include "rblist.h" #include "perf.h" +#include "event.h" struct stats {double n, mean, M2;
@@ -179,4 +180,9 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp);int create_perf_stat_counter (struct perf_evsel *evsel,struct perf_stat_config *config,struct target *target); +int perf_stat_synthesize_config (struct perf_stat_config *config, +struct perf_tool *tool, +struct perf_evlist *evlist, +perf_event__handler_t process, +bool attrs);#endif
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move perf_stat_synthesize_config() to stat.c
perf stat: Move perf_stat_synthesize_config() to stat.c
Commit-ID: 0a4e64d391a2c771ae33e648cf84d4492369560c Gitweb: https://git.kernel.org/tip/0a4e64d391a2c771ae33e648cf84d4492369560c Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:23 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Move perf_stat_synthesize_config() to stat.c
So that it can be used globally.
--- tools/perf/builtin-stat.c | 42 ------------------------------------------ tools/perf/util/stat.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 6 ++++++ 3 files changed, 48 insertions(+), 42 deletions(-)
tools/perf/builtin-stat.c +0 -42
@@ -402,48 +402,6 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf workload_exec_errno = info->si_value.sival_int; } -static int perf_stat_synthesize_config (struct perf_stat_config *config, -struct perf_tool *tool, -struct perf_evlist *evlist, -perf_event__handler_t process, -bool attrs) -{ -int err; - -if (attrs) { - err =perf_event__synthesize_attrs (tool, evlist, process); -if (err <0 ) { -pr_err ("Couldn't synthesize attrs.\n" ); -return err; - } - } - - err =perf_event__synthesize_extra_attr (tool, evlist, process, - attrs); - - err =perf_event__synthesize_thread_map2 (tool, evlist->threads, - process,NULL ); -if (err <0 ) { -pr_err ("Couldn't synthesize thread map.\n" ); -return err; - } - - err =perf_event__synthesize_cpu_map (tool, evlist->cpus, - process,NULL ); -if (err <0 ) { -pr_err ("Couldn't synthesize thread map.\n" ); -return err; - } - - err =perf_event__synthesize_stat_config (tool, config, process,NULL ); -if (err <0 ) { -pr_err ("Couldn't synthesize config.\n" ); -return err; - } - -return 0 ; -} -static bool perf_evsel__should_store_id (struct perf_evsel *counter) {return STAT_RECORD || counter->attr.read_format &PERF_FORMAT_ID ;
tools/perf/util/stat.c +42 -0
45 lines not on this page · raw message
tools/perf/util/stat.h +6 -0
@@ -7,6 +7,7 @@#include "xyarray.h" #include "rblist.h" #include "perf.h" +#include "event.h" struct stats {double n, mean, M2;
@@ -179,4 +180,9 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp);int create_perf_stat_counter (struct perf_evsel *evsel,struct perf_stat_config *config,struct target *target); +int perf_stat_synthesize_config (struct perf_stat_config *config, +struct perf_tool *tool, +struct perf_evlist *evlist, +perf_event__handler_t process, +bool attrs);#endif
Jiri Olsa
reviewerPATCH 15/43 perf stat: Add perf_evlist__print_counters function
In reply to Jiri OlsaTo be in charge of printing out the stat output. It will be moved out of stat command in following patches.
--- tools/perf/builtin-stat.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +12 -4
@@ -1692,7 +1692,10 @@ static void print_footer(void) "the same PMU. Try reorganizing the group.\n"); } -static void print_counters (struct timespec *ts,int argc,const char **argv) +static void +perf_evlist__print_counters (struct perf_evlist *evlist, +struct timespec *ts, +int argc,const char **argv) {int interval = stat_config.interval;struct perf_evsel *counter;
@@ -1724,14 +1727,14 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)print_aggr (prefix);break ;case AGGR_THREAD : -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;print_aggr_thread (counter, prefix); }break ;case AGGR_GLOBAL : -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;print_counter_aggr (counter, prefix);
@@ -1743,7 +1746,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)if (metric_only)print_no_aggr_metric (prefix);else { -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;print_counter (counter, prefix);
@@ -1761,6 +1764,11 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)fflush (stat_config.output); } +static void print_counters (struct timespec *ts,int argc,const char **argv) +{ +perf_evlist__print_counters (evsel_list, ts, argc, argv); +} +static volatile int signr =-1 ;static void skip_signal (int signo)
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Introduce perf_evlist__print_counters()
perf stat: Introduce perf_evlist__print_counters()
Commit-ID: a5a9eac1a018ad3bfcf9a3ec11eae99fd35f466b Gitweb: https://git.kernel.org/tip/a5a9eac1a018ad3bfcf9a3ec11eae99fd35f466b Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:24 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Introduce perf_evlist__print_counters()
To be in charge of printing out the stat output. It will be moved out of the 'perf stat' command in the following patches.
--- tools/perf/builtin-stat.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +12 -4
@@ -1692,7 +1692,10 @@ static void print_footer(void) "the same PMU. Try reorganizing the group.\n"); } -static void print_counters (struct timespec *ts,int argc,const char **argv) +static void +perf_evlist__print_counters (struct perf_evlist *evlist, +struct timespec *ts, +int argc,const char **argv) {int interval = stat_config.interval;struct perf_evsel *counter;
@@ -1724,14 +1727,14 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)print_aggr (prefix);break ;case AGGR_THREAD : -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;print_aggr_thread (counter, prefix); }break ;case AGGR_GLOBAL : -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;print_counter_aggr (counter, prefix);
@@ -1743,7 +1746,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)if (metric_only)print_no_aggr_metric (prefix);else { -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;print_counter (counter, prefix);
@@ -1761,6 +1764,11 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)fflush (stat_config.output); } +static void print_counters (struct timespec *ts,int argc,const char **argv) +{ +perf_evlist__print_counters (evsel_list, ts, argc, argv); +} +static volatile int signr =-1 ;static void skip_signal (int signo)
Jiri Olsa
reviewerPATCH 16/43 perf stat: Move STAT_RECORD out of perf_evlist__print_counters
In reply to Jiri OlsaIt's stat related and should stay in stat command. The perf_evlist__print_counters function will be moved out in following patches.
--- tools/perf/builtin-stat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +4 -4
@@ -1701,10 +1701,6 @@ perf_evlist__print_counters(struct perf_evlist *evlist,struct perf_evsel *counter;char buf[64 ], *prefix =NULL ; -/* Do not print anything if we record to the pipe. */ -if (STAT_RECORD && perf_stat.data.is_pipe) -return ; -if (interval)print_interval (prefix = buf, ts);else
@@ -1766,6 +1762,10 @@ perf_evlist__print_counters(struct perf_evlist *evlist,static void print_counters (struct timespec *ts,int argc,const char **argv) { +/* Do not print anything if we record to the pipe. */ +if (STAT_RECORD && perf_stat.data.is_pipe) +return ; +perf_evlist__print_counters (evsel_list, ts, argc, argv); }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move STAT_RECORD out of perf_evlist__print_counters()
perf stat: Move STAT_RECORD out of perf_evlist__print_counters()
Commit-ID: 0174820a8ba108f2e72dac5caaea3500c8ca6323 Gitweb: https://git.kernel.org/tip/0174820a8ba108f2e72dac5caaea3500c8ca6323 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:25 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Move STAT_RECORD out of perf_evlist__print_counters()
It's stat related and should stay in the 'perf stat' command. The perf_evlist__print_counters function will be moved out in the following patches.
--- tools/perf/builtin-stat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +4 -4
@@ -1701,10 +1701,6 @@ perf_evlist__print_counters(struct perf_evlist *evlist,struct perf_evsel *counter;char buf[64 ], *prefix =NULL ; -/* Do not print anything if we record to the pipe. */ -if (STAT_RECORD && perf_stat.data.is_pipe) -return ; -if (interval)print_interval (prefix = buf, ts);else
@@ -1766,6 +1762,10 @@ perf_evlist__print_counters(struct perf_evlist *evlist,static void print_counters (struct timespec *ts,int argc,const char **argv) { +/* Do not print anything if we record to the pipe. */ +if (STAT_RECORD && perf_stat.data.is_pipe) +return ; +perf_evlist__print_counters (evsel_list, ts, argc, argv); }
Jiri Olsa
reviewerPATCH 17/43 perf stat: Add stat_config argument to perf_evlist__print_counters
In reply to Jiri OlsaAdding stat_config argument perf_evlist__print_counters, so the function could be moved out of stat command to generic object in following patches.
--- tools/perf/builtin-stat.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +9 -7
@@ -1694,10 +1694,11 @@ static void print_footer(void)static void perf_evlist__print_counters (struct perf_evlist *evlist, +struct perf_stat_config *config,struct timespec *ts,int argc,const char **argv) { -int interval = stat_config.interval; +int interval = config->interval;struct perf_evsel *counter;char buf[64 ], *prefix =NULL ;
@@ -1713,11 +1714,11 @@ perf_evlist__print_counters(struct perf_evlist *evlist,print_metric_headers (prefix, false);if (num_print_iv++ ==25 ) num_print_iv =0 ; -if (stat_config.aggr_mode ==AGGR_GLOBAL && prefix) -fprintf (stat_config.output,"%s" , prefix); +if (config->aggr_mode ==AGGR_GLOBAL && prefix) +fprintf (config->output,"%s" , prefix); } -switch (stat_config.aggr_mode) { +switch (config->aggr_mode) {case AGGR_CORE :case AGGR_SOCKET :print_aggr (prefix);
@@ -1736,7 +1737,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,print_counter_aggr (counter, prefix); }if (metric_only) -fputc ('\n' , stat_config.output); +fputc ('\n' , config->output);break ;case AGGR_NONE :if (metric_only)
@@ -1757,7 +1758,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,if (!interval && !csv_output)print_footer (); -fflush (stat_config.output); +fflush (config->output); }static void print_counters (struct timespec *ts,int argc,const char **argv)
@@ -1766,7 +1767,8 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)if (STAT_RECORD && perf_stat.data.is_pipe)return ; -perf_evlist__print_counters (evsel_list, ts, argc, argv); +perf_evlist__print_counters (evsel_list, &stat_config, + ts, argc, argv); }static volatile int signr =-1 ;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'struct perf_stat_config' argument to perf_evlist__print_counters()
perf stat: Add 'struct perf_stat_config' argument to perf_evlist__print_counters()
Commit-ID: b64df7f33743cd6095b4a007f5f15ff4432fbcf5 Gitweb: https://git.kernel.org/tip/b64df7f33743cd6095b4a007f5f15ff4432fbcf5 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:26 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:22 -0300
perf stat: Add 'struct perf_stat_config' argument to perf_evlist__print_counters()
Add a 'struct perf_stat_config' argument to perf_evlist__print_counters(), so that it can be moved out of the 'perf stat' command to generic object in the following patches.
--- tools/perf/builtin-stat.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +9 -7
@@ -1694,10 +1694,11 @@ static void print_footer(void)static void perf_evlist__print_counters (struct perf_evlist *evlist, +struct perf_stat_config *config,struct timespec *ts,int argc,const char **argv) { -int interval = stat_config.interval; +int interval = config->interval;struct perf_evsel *counter;char buf[64 ], *prefix =NULL ;
@@ -1713,11 +1714,11 @@ perf_evlist__print_counters(struct perf_evlist *evlist,print_metric_headers (prefix, false);if (num_print_iv++ ==25 ) num_print_iv =0 ; -if (stat_config.aggr_mode ==AGGR_GLOBAL && prefix) -fprintf (stat_config.output,"%s" , prefix); +if (config->aggr_mode ==AGGR_GLOBAL && prefix) +fprintf (config->output,"%s" , prefix); } -switch (stat_config.aggr_mode) { +switch (config->aggr_mode) {case AGGR_CORE :case AGGR_SOCKET :print_aggr (prefix);
@@ -1736,7 +1737,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,print_counter_aggr (counter, prefix); }if (metric_only) -fputc ('\n' , stat_config.output); +fputc ('\n' , config->output);break ;case AGGR_NONE :if (metric_only)
@@ -1757,7 +1758,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,if (!interval && !csv_output)print_footer (); -fflush (stat_config.output); +fflush (config->output); }static void print_counters (struct timespec *ts,int argc,const char **argv)
@@ -1766,7 +1767,8 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)if (STAT_RECORD && perf_stat.data.is_pipe)return ; -perf_evlist__print_counters (evsel_list, ts, argc, argv); +perf_evlist__print_counters (evsel_list, &stat_config, + ts, argc, argv); }static volatile int signr =-1 ;
Jiri Olsa
reviewerPATCH 18/43 perf stat: Pass stat_config argument to local print functions
In reply to Jiri OlsaAdding stat_config argument local print functions, so those functions could be moved out of stat command to generic object in following patches.
--- tools/perf/builtin-stat.c | 149 ++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 69 deletions(-)
tools/perf/builtin-stat.c +80 -69
@@ -660,30 +660,33 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)return ret; } -static void print_running (u64 run,u64 ena) +static void print_running (struct perf_stat_config *config, +u64 run,u64 ena) {if (csv_output) { -fprintf (stat_config.output,"%s%" PRIu64"%s%.2f" , +fprintf (config->output,"%s%" PRIu64"%s%.2f" , csv_sep, run, csv_sep, ena ?100.0 * run / ena :100.0 ); }else if (run != ena) { -fprintf (stat_config.output," (%.2f%%)" ,100.0 * run / ena); +fprintf (config->output," (%.2f%%)" ,100.0 * run / ena); } } -static void print_noise_pct (double total,double avg) +static void print_noise_pct (struct perf_stat_config *config, +double total,double avg) {double pct =rel_stddev_stats (total, avg);if (csv_output) -fprintf (stat_config.output,"%s%.2f%%" , csv_sep, pct); +fprintf (config->output,"%s%.2f%%" , csv_sep, pct);else if (pct) -fprintf (stat_config.output," ( +-%6.2f%% )" , pct); +fprintf (config->output," ( +-%6.2f%% )" , pct); } -static void print_noise (struct perf_evsel *evsel,double avg) +static void print_noise (struct perf_stat_config *config, +struct perf_evsel *evsel,double avg) {struct perf_stat_evsel *ps;
@@ -691,7 +694,7 @@ static void print_noise(struct perf_evsel *evsel, double avg)return ; ps = evsel->stats; -print_noise_pct (stddev_stats (&ps->res_stats[0 ]), avg); +print_noise_pct (config,stddev_stats (&ps->res_stats[0 ]), avg); }static void aggr_printout (struct perf_evsel *evsel,int id,int nr)
@@ -987,13 +990,14 @@ static bool is_mixed_hw_group(struct perf_evsel *counter)return false; } -static void printout (int id,int nr,struct perf_evsel *counter,double uval, +static void printout (struct perf_stat_config *config,int id,int nr, +struct perf_evsel *counter,double uval,char *prefix,u64 run,u64 ena,double noise,struct runtime_stat *st) {struct perf_stat_output_ctx out;struct outstate os = { - .fh = stat_config.output, + .fh = config->output, .prefix = prefix ? prefix :"" , .id = id, .nr = nr,
@@ -1023,7 +1027,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, pm = print_metric_csv; nl = new_line_csv; os.nfields =3 ; - os.nfields += aggr_fields[stat_config.aggr_mode]; + os.nfields += aggr_fields[config->aggr_mode];if (counter->cgrp) os.nfields++; }
@@ -1034,7 +1038,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, }aggr_printout (counter, id, nr); -fprintf (stat_config.output,"%*s%s" , +fprintf (config->output,"%*s%s" , csv_output ?0 :18 , counter->supported ?CNTR_NOT_COUNTED :CNTR_NOT_SUPPORTED , csv_sep);
@@ -1045,22 +1049,22 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, print_mixed_hw_group_error =1 ; } -fprintf (stat_config.output,"%-*s%s" , +fprintf (config->output,"%-*s%s" , csv_output ?0 : unit_width, counter->unit, csv_sep); -fprintf (stat_config.output,"%*s" , +fprintf (config->output,"%*s" , csv_output ?0 :-25 ,perf_evsel__name (counter));if (counter->cgrp) -fprintf (stat_config.output,"%s%s" , +fprintf (config->output,"%s%s" , csv_sep, counter->cgrp->name);if (!csv_output)pm (&os,NULL ,NULL ,"" ,0 ); -print_noise (counter, noise); -print_running (run, ena); +print_noise (config, counter, noise); +print_running (config, run, ena);if (csv_output)pm (&os,NULL ,NULL ,"" ,0 );return ;
@@ -1075,16 +1079,16 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, out.force_header = false;if (csv_output && !metric_only) { -print_noise (counter, noise); -print_running (run, ena); +print_noise (config, counter, noise); +print_running (config, run, ena); }perf_stat__print_shadow_stats (counter, uval,first_shadow_cpu (counter, id), &out, &metric_events, st);if (!csv_output && !metric_only) { -print_noise (counter, noise); -print_running (run, ena); +print_noise (config, counter, noise); +print_running (config, run, ena); } }
@@ -1211,9 +1215,10 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first) } } -static void print_aggr (char *prefix) +static void print_aggr (struct perf_stat_config *config, +char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;struct perf_evsel *counter;int s, id, nr;double uval;
@@ -1256,8 +1261,8 @@ static void print_aggr(char *prefix)fprintf (output,"%s" , prefix); uval = val * counter->scale; -printout (id, nr, counter, uval, prefix, run, ena,1.0 , - &rt_stat); +printout (config, id, nr, counter, uval, prefix, + run, ena,1.0 , &rt_stat);if (!metric_only)fputc ('\n' , output); }
@@ -1320,9 +1325,10 @@ static struct perf_aggr_thread_value *sort_aggr_thread(return buf; } -static void print_aggr_thread (struct perf_evsel *counter,char *prefix) +static void print_aggr_thread (struct perf_stat_config *config, +struct perf_evsel *counter,char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;int nthreads =thread_map__nr (counter->threads);int ncpus =cpu_map__nr (counter->cpus);int thread, sorted_threads, id;
@@ -1339,12 +1345,12 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); id = buf[thread].id; -if (stat_config.stats) -printout (id,0 , buf[thread].counter, buf[thread].uval, +if (config->stats) +printout (config, id,0 , buf[thread].counter, buf[thread].uval, prefix, buf[thread].run, buf[thread].ena,1.0 , - &stat_config.stats[id]); + &config->stats[id]);else -printout (id,0 , buf[thread].counter, buf[thread].uval, +printout (config, id,0 , buf[thread].counter, buf[thread].uval, prefix, buf[thread].run, buf[thread].ena,1.0 , &rt_stat);fputc ('\n' , output);
@@ -1372,9 +1378,10 @@ static void counter_aggr_cb(struct perf_evsel *counter, void *data,* Print out the results of a single counter: * aggregated counts in system-wide mode */ -static void print_counter_aggr (struct perf_evsel *counter,char *prefix) +static void print_counter_aggr (struct perf_stat_config *config, +struct perf_evsel *counter,char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;double uval;struct caggr_data cd = { .avg =0.0 };
@@ -1385,7 +1392,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); uval = cd.avg * counter->scale; -printout (-1 ,0 , counter, uval, prefix, cd.avg_running, cd.avg_enabled, +printout (config,-1 ,0 , counter, uval, prefix, cd.avg_running, cd.avg_enabled, cd.avg, &rt_stat);if (!metric_only)fprintf (output,"\n" );
@@ -1405,9 +1412,10 @@ static void counter_cb(struct perf_evsel *counter, void *data,* Print out the results of a single counter: * does not use aggregated count in system-wide */ -static void print_counter (struct perf_evsel *counter,char *prefix) +static void print_counter (struct perf_stat_config *config, +struct perf_evsel *counter,char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;u64 ena, run, val;double uval;int cpu;
@@ -1425,14 +1433,15 @@ static void print_counter(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); uval = val * counter->scale; -printout (cpu,0 , counter, uval, prefix, run, ena,1.0 , +printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , &rt_stat);fputc ('\n' , output); } } -static void print_no_aggr_metric (char *prefix) +static void print_no_aggr_metric (struct perf_stat_config *config, +char *prefix) {int cpu;int nrcpus =0 ;
@@ -1445,7 +1454,7 @@ static void print_no_aggr_metric(char *prefix)bool first = true;if (prefix) -fputs (prefix, stat_config.output); +fputs (prefix, config->output);evlist__for_each_entry (evsel_list, counter) {if (is_duration_time (counter))continue ;
@@ -1458,10 +1467,10 @@ static void print_no_aggr_metric(char *prefix) run =perf_counts (counter->counts, cpu,0 )->run; uval = val * counter->scale; -printout (cpu,0 , counter, uval, prefix, run, ena,1.0 , +printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , &rt_stat); } -fputc ('\n' , stat_config.output); +fputc ('\n' , config->output); } }
@@ -1481,25 +1490,25 @@ static const char *aggr_header_csv[] = { [AGGR_GLOBAL] = "" }; -static void print_metric_headers (const char *prefix,bool no_indent) +static void print_metric_headers (struct perf_stat_config *config, +const char *prefix,bool no_indent) {struct perf_stat_output_ctx out;struct perf_evsel *counter;struct outstate os = { - .fh = stat_config.output + .fh = config->output };if (prefix) -fprintf (stat_config.output,"%s" , prefix); +fprintf (config->output,"%s" , prefix);if (!csv_output && !no_indent) -fprintf (stat_config.output,"%*s" , - aggr_header_lens[stat_config.aggr_mode],"" ); +fprintf (config->output,"%*s" , + aggr_header_lens[config->aggr_mode],"" );if (csv_output) { -if (stat_config.interval) -fputs ("time," , stat_config.output); -fputs (aggr_header_csv[stat_config.aggr_mode], - stat_config.output); +if (config->interval) +fputs ("time," , config->output); +fputs (aggr_header_csv[config->aggr_mode], config->output); }/* Print metrics headers only */
@@ -1518,12 +1527,13 @@ static void print_metric_headers(const char *prefix, bool no_indent) &metric_events, &rt_stat); } -fputc ('\n' , stat_config.output); +fputc ('\n' , config->output); } -static void print_interval (char *prefix,struct timespec *ts) +static void print_interval (struct perf_stat_config *config, +char *prefix,struct timespec *ts) { -FILE *output = stat_config.output; +FILE *output = config->output;static int num_print_interval;if (interval_clear)
@@ -1532,7 +1542,7 @@ static void print_interval(char *prefix, struct timespec *ts)sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, csv_sep);if ((num_print_interval ==0 && !csv_output) || interval_clear) { -switch (stat_config.aggr_mode) { +switch (config->aggr_mode) {case AGGR_SOCKET :fprintf (output,"# time socket cpus" );if (!metric_only)
@@ -1564,14 +1574,15 @@ static void print_interval(char *prefix, struct timespec *ts) }if ((num_print_interval ==0 || interval_clear) && metric_only) -print_metric_headers (" " , true); +print_metric_headers (config," " , true);if (++num_print_interval ==25 ) num_print_interval =0 ; } -static void print_header (int argc,const char **argv) +static void print_header (struct perf_stat_config *config, +int argc,const char **argv) { -FILE *output = stat_config.output; +FILE *output = config->output;int i;fflush (stdout);
@@ -1639,10 +1650,10 @@ static double timeval2double(struct timeval *t)return t->tv_sec + (double ) t->tv_usec/USEC_PER_SEC ; } -static void print_footer (void ) +static void print_footer (struct perf_stat_config *config) {double avg =avg_stats (&walltime_nsecs_stats) /NSEC_PER_SEC ; -FILE *output = stat_config.output; +FILE *output = config->output;int n;if (!null_run)
@@ -1673,7 +1684,7 @@ static void print_footer(void)fprintf (output," %17.*f +- %.*f seconds time elapsed" , precision, avg, precision, sd); -print_noise_pct (sd, avg); +print_noise_pct (config, sd, avg); }fprintf (output,"\n\n" );
@@ -1703,15 +1714,15 @@ perf_evlist__print_counters(struct perf_evlist *evlist,char buf[64 ], *prefix =NULL ;if (interval) -print_interval (prefix = buf, ts); +print_interval (config, prefix = buf, ts);else -print_header (argc, argv); +print_header (config, argc, argv);if (metric_only) {static int num_print_iv;if (num_print_iv ==0 && !interval) -print_metric_headers (prefix, false); +print_metric_headers (config, prefix, false);if (num_print_iv++ ==25 ) num_print_iv =0 ;if (config->aggr_mode ==AGGR_GLOBAL && prefix)
@@ -1721,32 +1732,32 @@ perf_evlist__print_counters(struct perf_evlist *evlist,switch (config->aggr_mode) {case AGGR_CORE :case AGGR_SOCKET : -print_aggr (prefix); +print_aggr (config, prefix);break ;case AGGR_THREAD :evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_aggr_thread (counter, prefix); +print_aggr_thread (config, counter, prefix); }break ;case AGGR_GLOBAL :evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_counter_aggr (counter, prefix); +print_counter_aggr (config, counter, prefix); }if (metric_only)fputc ('\n' , config->output);break ;case AGGR_NONE :if (metric_only) -print_no_aggr_metric (prefix); +print_no_aggr_metric (config, prefix);else {evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_counter (counter, prefix); +print_counter (config, counter, prefix); } }break ;
@@ -1756,7 +1767,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist, }if (!interval && !csv_output) -print_footer (); +print_footer (config);fflush (config->output); }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Pass 'struct perf_stat_config' argument to local print functions
perf stat: Pass 'struct perf_stat_config' argument to local print functions
Commit-ID: f3ca50e61ff4aebfbefc666be2e064d277ad524c Gitweb: https://git.kernel.org/tip/f3ca50e61ff4aebfbefc666be2e064d277ad524c Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:27 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Pass 'struct perf_stat_config' argument to local print functions
Add 'struct perf_stat_config' argument to print functions, so that those functions can be moved out of the 'perf stat' command to a generic class in the following patches.
--- tools/perf/builtin-stat.c | 149 +++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 69 deletions(-)
tools/perf/builtin-stat.c +80 -69
@@ -660,30 +660,33 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)return ret; } -static void print_running (u64 run,u64 ena) +static void print_running (struct perf_stat_config *config, +u64 run,u64 ena) {if (csv_output) { -fprintf (stat_config.output,"%s%" PRIu64"%s%.2f" , +fprintf (config->output,"%s%" PRIu64"%s%.2f" , csv_sep, run, csv_sep, ena ?100.0 * run / ena :100.0 ); }else if (run != ena) { -fprintf (stat_config.output," (%.2f%%)" ,100.0 * run / ena); +fprintf (config->output," (%.2f%%)" ,100.0 * run / ena); } } -static void print_noise_pct (double total,double avg) +static void print_noise_pct (struct perf_stat_config *config, +double total,double avg) {double pct =rel_stddev_stats (total, avg);if (csv_output) -fprintf (stat_config.output,"%s%.2f%%" , csv_sep, pct); +fprintf (config->output,"%s%.2f%%" , csv_sep, pct);else if (pct) -fprintf (stat_config.output," ( +-%6.2f%% )" , pct); +fprintf (config->output," ( +-%6.2f%% )" , pct); } -static void print_noise (struct perf_evsel *evsel,double avg) +static void print_noise (struct perf_stat_config *config, +struct perf_evsel *evsel,double avg) {struct perf_stat_evsel *ps;
@@ -691,7 +694,7 @@ static void print_noise(struct perf_evsel *evsel, double avg)return ; ps = evsel->stats; -print_noise_pct (stddev_stats (&ps->res_stats[0 ]), avg); +print_noise_pct (config,stddev_stats (&ps->res_stats[0 ]), avg); }static void aggr_printout (struct perf_evsel *evsel,int id,int nr)
@@ -987,13 +990,14 @@ static bool is_mixed_hw_group(struct perf_evsel *counter)return false; } -static void printout (int id,int nr,struct perf_evsel *counter,double uval, +static void printout (struct perf_stat_config *config,int id,int nr, +struct perf_evsel *counter,double uval,char *prefix,u64 run,u64 ena,double noise,struct runtime_stat *st) {struct perf_stat_output_ctx out;struct outstate os = { - .fh = stat_config.output, + .fh = config->output, .prefix = prefix ? prefix :"" , .id = id, .nr = nr,
@@ -1023,7 +1027,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, pm = print_metric_csv; nl = new_line_csv; os.nfields =3 ; - os.nfields += aggr_fields[stat_config.aggr_mode]; + os.nfields += aggr_fields[config->aggr_mode];if (counter->cgrp) os.nfields++; }
@@ -1034,7 +1038,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, }aggr_printout (counter, id, nr); -fprintf (stat_config.output,"%*s%s" , +fprintf (config->output,"%*s%s" , csv_output ?0 :18 , counter->supported ?CNTR_NOT_COUNTED :CNTR_NOT_SUPPORTED , csv_sep);
@@ -1045,22 +1049,22 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, print_mixed_hw_group_error =1 ; } -fprintf (stat_config.output,"%-*s%s" , +fprintf (config->output,"%-*s%s" , csv_output ?0 : unit_width, counter->unit, csv_sep); -fprintf (stat_config.output,"%*s" , +fprintf (config->output,"%*s" , csv_output ?0 :-25 ,perf_evsel__name (counter));if (counter->cgrp) -fprintf (stat_config.output,"%s%s" , +fprintf (config->output,"%s%s" , csv_sep, counter->cgrp->name);if (!csv_output)pm (&os,NULL ,NULL ,"" ,0 ); -print_noise (counter, noise); -print_running (run, ena); +print_noise (config, counter, noise); +print_running (config, run, ena);if (csv_output)pm (&os,NULL ,NULL ,"" ,0 );return ;
@@ -1075,16 +1079,16 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, out.force_header = false;if (csv_output && !metric_only) { -print_noise (counter, noise); -print_running (run, ena); +print_noise (config, counter, noise); +print_running (config, run, ena); }perf_stat__print_shadow_stats (counter, uval,first_shadow_cpu (counter, id), &out, &metric_events, st);if (!csv_output && !metric_only) { -print_noise (counter, noise); -print_running (run, ena); +print_noise (config, counter, noise); +print_running (config, run, ena); } }
@@ -1211,9 +1215,10 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first) } } -static void print_aggr (char *prefix) +static void print_aggr (struct perf_stat_config *config, +char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;struct perf_evsel *counter;int s, id, nr;double uval;
@@ -1256,8 +1261,8 @@ static void print_aggr(char *prefix)fprintf (output,"%s" , prefix); uval = val * counter->scale; -printout (id, nr, counter, uval, prefix, run, ena,1.0 , - &rt_stat); +printout (config, id, nr, counter, uval, prefix, + run, ena,1.0 , &rt_stat);if (!metric_only)fputc ('\n' , output); }
@@ -1320,9 +1325,10 @@ static struct perf_aggr_thread_value *sort_aggr_thread(return buf; } -static void print_aggr_thread (struct perf_evsel *counter,char *prefix) +static void print_aggr_thread (struct perf_stat_config *config, +struct perf_evsel *counter,char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;int nthreads =thread_map__nr (counter->threads);int ncpus =cpu_map__nr (counter->cpus);int thread, sorted_threads, id;
@@ -1339,12 +1345,12 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); id = buf[thread].id; -if (stat_config.stats) -printout (id,0 , buf[thread].counter, buf[thread].uval, +if (config->stats) +printout (config, id,0 , buf[thread].counter, buf[thread].uval, prefix, buf[thread].run, buf[thread].ena,1.0 , - &stat_config.stats[id]); + &config->stats[id]);else -printout (id,0 , buf[thread].counter, buf[thread].uval, +printout (config, id,0 , buf[thread].counter, buf[thread].uval, prefix, buf[thread].run, buf[thread].ena,1.0 , &rt_stat);fputc ('\n' , output);
@@ -1372,9 +1378,10 @@ static void counter_aggr_cb(struct perf_evsel *counter, void *data,* Print out the results of a single counter: * aggregated counts in system-wide mode */ -static void print_counter_aggr (struct perf_evsel *counter,char *prefix) +static void print_counter_aggr (struct perf_stat_config *config, +struct perf_evsel *counter,char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;double uval;struct caggr_data cd = { .avg =0.0 };
@@ -1385,7 +1392,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); uval = cd.avg * counter->scale; -printout (-1 ,0 , counter, uval, prefix, cd.avg_running, cd.avg_enabled, +printout (config,-1 ,0 , counter, uval, prefix, cd.avg_running, cd.avg_enabled, cd.avg, &rt_stat);if (!metric_only)fprintf (output,"\n" );
@@ -1405,9 +1412,10 @@ static void counter_cb(struct perf_evsel *counter, void *data,* Print out the results of a single counter: * does not use aggregated count in system-wide */ -static void print_counter (struct perf_evsel *counter,char *prefix) +static void print_counter (struct perf_stat_config *config, +struct perf_evsel *counter,char *prefix) { -FILE *output = stat_config.output; +FILE *output = config->output;u64 ena, run, val;double uval;int cpu;
@@ -1425,14 +1433,15 @@ static void print_counter(struct perf_evsel *counter, char *prefix)fprintf (output,"%s" , prefix); uval = val * counter->scale; -printout (cpu,0 , counter, uval, prefix, run, ena,1.0 , +printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , &rt_stat);fputc ('\n' , output); } } -static void print_no_aggr_metric (char *prefix) +static void print_no_aggr_metric (struct perf_stat_config *config, +char *prefix) {int cpu;int nrcpus =0 ;
@@ -1445,7 +1454,7 @@ static void print_no_aggr_metric(char *prefix)bool first = true;if (prefix) -fputs (prefix, stat_config.output); +fputs (prefix, config->output);evlist__for_each_entry (evsel_list, counter) {if (is_duration_time (counter))continue ;
@@ -1458,10 +1467,10 @@ static void print_no_aggr_metric(char *prefix) run =perf_counts (counter->counts, cpu,0 )->run; uval = val * counter->scale; -printout (cpu,0 , counter, uval, prefix, run, ena,1.0 , +printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , &rt_stat); } -fputc ('\n' , stat_config.output); +fputc ('\n' , config->output); } }
@@ -1481,25 +1490,25 @@ static const char *aggr_header_csv[] = { [AGGR_GLOBAL] = "" }; -static void print_metric_headers (const char *prefix,bool no_indent) +static void print_metric_headers (struct perf_stat_config *config, +const char *prefix,bool no_indent) {struct perf_stat_output_ctx out;struct perf_evsel *counter;struct outstate os = { - .fh = stat_config.output + .fh = config->output };if (prefix) -fprintf (stat_config.output,"%s" , prefix); +fprintf (config->output,"%s" , prefix);if (!csv_output && !no_indent) -fprintf (stat_config.output,"%*s" , - aggr_header_lens[stat_config.aggr_mode],"" ); +fprintf (config->output,"%*s" , + aggr_header_lens[config->aggr_mode],"" );if (csv_output) { -if (stat_config.interval) -fputs ("time," , stat_config.output); -fputs (aggr_header_csv[stat_config.aggr_mode], - stat_config.output); +if (config->interval) +fputs ("time," , config->output); +fputs (aggr_header_csv[config->aggr_mode], config->output); }/* Print metrics headers only */
@@ -1518,12 +1527,13 @@ static void print_metric_headers(const char *prefix, bool no_indent) &metric_events, &rt_stat); } -fputc ('\n' , stat_config.output); +fputc ('\n' , config->output); } -static void print_interval (char *prefix,struct timespec *ts) +static void print_interval (struct perf_stat_config *config, +char *prefix,struct timespec *ts) { -FILE *output = stat_config.output; +FILE *output = config->output;static int num_print_interval;if (interval_clear)
@@ -1532,7 +1542,7 @@ static void print_interval(char *prefix, struct timespec *ts)sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, csv_sep);if ((num_print_interval ==0 && !csv_output) || interval_clear) { -switch (stat_config.aggr_mode) { +switch (config->aggr_mode) {case AGGR_SOCKET :fprintf (output,"# time socket cpus" );if (!metric_only)
@@ -1564,14 +1574,15 @@ static void print_interval(char *prefix, struct timespec *ts) }if ((num_print_interval ==0 || interval_clear) && metric_only) -print_metric_headers (" " , true); +print_metric_headers (config," " , true);if (++num_print_interval ==25 ) num_print_interval =0 ; } -static void print_header (int argc,const char **argv) +static void print_header (struct perf_stat_config *config, +int argc,const char **argv) { -FILE *output = stat_config.output; +FILE *output = config->output;int i;fflush (stdout);
@@ -1639,10 +1650,10 @@ static double timeval2double(struct timeval *t)return t->tv_sec + (double ) t->tv_usec/USEC_PER_SEC ; } -static void print_footer (void ) +static void print_footer (struct perf_stat_config *config) {double avg =avg_stats (&walltime_nsecs_stats) /NSEC_PER_SEC ; -FILE *output = stat_config.output; +FILE *output = config->output;int n;if (!null_run)
@@ -1673,7 +1684,7 @@ static void print_footer(void)fprintf (output," %17.*f +- %.*f seconds time elapsed" , precision, avg, precision, sd); -print_noise_pct (sd, avg); +print_noise_pct (config, sd, avg); }fprintf (output,"\n\n" );
@@ -1703,15 +1714,15 @@ perf_evlist__print_counters(struct perf_evlist *evlist,char buf[64 ], *prefix =NULL ;if (interval) -print_interval (prefix = buf, ts); +print_interval (config, prefix = buf, ts);else -print_header (argc, argv); +print_header (config, argc, argv);if (metric_only) {static int num_print_iv;if (num_print_iv ==0 && !interval) -print_metric_headers (prefix, false); +print_metric_headers (config, prefix, false);if (num_print_iv++ ==25 ) num_print_iv =0 ;if (config->aggr_mode ==AGGR_GLOBAL && prefix)
@@ -1721,32 +1732,32 @@ perf_evlist__print_counters(struct perf_evlist *evlist,switch (config->aggr_mode) {case AGGR_CORE :case AGGR_SOCKET : -print_aggr (prefix); +print_aggr (config, prefix);break ;case AGGR_THREAD :evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_aggr_thread (counter, prefix); +print_aggr_thread (config, counter, prefix); }break ;case AGGR_GLOBAL :evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_counter_aggr (counter, prefix); +print_counter_aggr (config, counter, prefix); }if (metric_only)fputc ('\n' , config->output);break ;case AGGR_NONE :if (metric_only) -print_no_aggr_metric (prefix); +print_no_aggr_metric (config, prefix);else {evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_counter (counter, prefix); +print_counter (config, counter, prefix); } }break ;
@@ -1756,7 +1767,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist, }if (!interval && !csv_output) -print_footer (); +print_footer (config);fflush (config->output); }
Jiri Olsa
reviewerPATCH 19/43 perf stat: Pass stat_config argument to global print functions
In reply to Jiri OlsaAdding stat_config argument global print functions, so those functions could be used out of the stat command code.
--- tools/perf/builtin-script.c | 8 +- tools/perf/builtin-stat.c | 74 +++++++++-------- tools/perf/util/stat-shadow.c | 147 ++++++++++++++++++---------------- tools/perf/util/stat.h | 8 +- 4 files changed, 131 insertions(+), 106 deletions(-)
tools/perf/builtin-script.c +5 -3
@@ -1544,7 +1544,8 @@ struct metric_ctx {FILE *fp; }; -static void script_print_metric (void *ctx,const char *color, +static void script_print_metric (struct perf_stat_config *config__maybe_unused , +void *ctx,const char *color,const char *fmt,const char *unit,double val) {
@@ -1562,7 +1563,8 @@ static void script_print_metric(void *ctx, const char *color,fprintf (mctx->fp," %s\n" , unit); } -static void script_new_line (void *ctx) +static void script_new_line (struct perf_stat_config *config__maybe_unused , +void *ctx) {struct metric_ctx *mctx = ctx;
@@ -1608,7 +1610,7 @@ static void perf_sample__fprint_metric(struct perf_script *script,evsel_script (evsel)->val = val;if (evsel_script (evsel->leader)->gnum == evsel->leader->nr_members) { for_each_group_member (ev2, evsel->leader) { - perf_stat__print_shadow_stats(ev2, + perf_stat__print_shadow_stats(&stat_config, ev2, evsel_script(ev2)->val, sample->cpu, &ctx,
tools/perf/builtin-stat.c +42 -32
224 lines not on this page · raw message
tools/perf/util/stat-shadow.c +79 -68
397 lines not on this page · raw message
tools/perf/util/stat.h +5 -3
@@ -135,9 +135,10 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,extern struct runtime_stat rt_stat;extern struct stats walltime_nsecs_stats; -typedef void (*print_metric_t )(void *ctx,const char *color,const char *unit, +typedef void (*print_metric_t )(struct perf_stat_config *config, +void *ctx,const char *color,const char *unit,const char *fmt,double val); -typedef void (*new_line_t )(void *ctx); +typedef void (*new_line_t )(struct perf_stat_config *config,void *ctx);void runtime_stat__init (struct runtime_stat *st);void runtime_stat__exit (struct runtime_stat *st);
@@ -153,7 +154,8 @@ struct perf_stat_output_ctx {bool force_header; }; -void perf_stat__print_shadow_stats(struct perf_evsel *evsel, +void perf_stat__print_shadow_stats(struct perf_stat_config *config, + struct perf_evsel *evsel, double avg, int cpu, struct perf_stat_output_ctx *out, struct rblist *metric_events,
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Pass a 'struct perf_stat_config' argument to global print functions
perf stat: Pass a 'struct perf_stat_config' argument to global print functions
Commit-ID: 6ca9a082b1908ff7f8adedf08166043b83b266f6 Gitweb: https://git.kernel.org/tip/6ca9a082b1908ff7f8adedf08166043b83b266f6 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:28 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Pass a 'struct perf_stat_config' argument to global print functions
Add 'struct perf_stat_config' argument to the global print functions, so that these functions can be used out of the 'perf stat' command code.
--- tools/perf/builtin-script.c | 8 ++- tools/perf/builtin-stat.c | 74 ++++++++++++--------- tools/perf/util/stat-shadow.c | 147 +++++++++++++++++++++++------------------- tools/perf/util/stat.h | 8 ++- 4 files changed, 131 insertions(+), 106 deletions(-)
tools/perf/builtin-script.c +5 -3
@@ -1544,7 +1544,8 @@ struct metric_ctx {FILE *fp; }; -static void script_print_metric (void *ctx,const char *color, +static void script_print_metric (struct perf_stat_config *config__maybe_unused , +void *ctx,const char *color,const char *fmt,const char *unit,double val) {
@@ -1562,7 +1563,8 @@ static void script_print_metric(void *ctx, const char *color,fprintf (mctx->fp," %s\n" , unit); } -static void script_new_line (void *ctx) +static void script_new_line (struct perf_stat_config *config__maybe_unused , +void *ctx) {struct metric_ctx *mctx = ctx;
@@ -1608,7 +1610,7 @@ static void perf_sample__fprint_metric(struct perf_script *script,evsel_script (evsel)->val = val;if (evsel_script (evsel->leader)->gnum == evsel->leader->nr_members) { for_each_group_member (ev2, evsel->leader) { - perf_stat__print_shadow_stats(ev2, + perf_stat__print_shadow_stats(&stat_config, ev2, evsel_script(ev2)->val, sample->cpu, &ctx,
tools/perf/builtin-stat.c +42 -32
224 lines not on this page · raw message
tools/perf/util/stat-shadow.c +79 -68
397 lines not on this page · raw message
tools/perf/util/stat.h +5 -3
@@ -135,9 +135,10 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,extern struct runtime_stat rt_stat;extern struct stats walltime_nsecs_stats; -typedef void (*print_metric_t )(void *ctx,const char *color,const char *unit, +typedef void (*print_metric_t )(struct perf_stat_config *config, +void *ctx,const char *color,const char *unit,const char *fmt,double val); -typedef void (*new_line_t )(void *ctx); +typedef void (*new_line_t )(struct perf_stat_config *config,void *ctx);void runtime_stat__init (struct runtime_stat *st);void runtime_stat__exit (struct runtime_stat *st);
@@ -153,7 +154,8 @@ struct perf_stat_output_ctx {bool force_header; }; -void perf_stat__print_shadow_stats(struct perf_evsel *evsel, +void perf_stat__print_shadow_stats(struct perf_stat_config *config, + struct perf_evsel *evsel, double avg, int cpu, struct perf_stat_output_ctx *out, struct rblist *metric_events,
Jiri Olsa
reviewerPATCH 20/43 perf stat: Move csv_* into struct perf_stat_config
In reply to Jiri OlsaMoving static csv_* fields into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 114 +++++++++++++++++++------------------- tools/perf/util/stat.h | 2 + 2 files changed, 58 insertions(+), 58 deletions(-)
tools/perf/builtin-stat.c +56 -58
@@ -157,8 +157,6 @@ static bool smi_cost = false;static bool smi_reset = false;static bool big_num = true;static int big_num_opt =-1 ; -static const char *csv_sep =NULL ; -static bool csv_output = false;static bool group = false;static const char *pre_cmd =NULL ;static const char *post_cmd =NULL ;
@@ -663,11 +661,11 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)static void print_running (struct perf_stat_config *config,u64 run,u64 ena) { -if (csv_output) { +if (config->csv_output) {fprintf (config->output,"%s%" PRIu64"%s%.2f" , - csv_sep, + config->csv_sep, run, - csv_sep, + config->csv_sep, ena ?100.0 * run / ena :100.0 ); }else if (run != ena) {fprintf (config->output," (%.2f%%)" ,100.0 * run / ena);
@@ -679,8 +677,8 @@ static void print_noise_pct(struct perf_stat_config *config, {double pct =rel_stddev_stats (total, avg); -if (csv_output) -fprintf (config->output,"%s%.2f%%" , csv_sep, pct); +if (config->csv_output) +fprintf (config->output,"%s%.2f%%" , config->csv_sep, pct);else if (pct)fprintf (config->output," ( +-%6.2f%% )" , pct); }
@@ -704,34 +702,34 @@ static void aggr_printout(struct perf_stat_config *config,case AGGR_CORE :fprintf (config->output,"S%d-C%*d%s%*d%s" ,cpu_map__id_to_socket (id), - csv_output ?0 :-8 , + config->csv_output ?0 :-8 ,cpu_map__id_to_cpu (id), - csv_sep, - csv_output ?0 :4 , + config->csv_sep, + config->csv_output ?0 :4 , nr, - csv_sep); + config->csv_sep);break ;case AGGR_SOCKET :fprintf (config->output,"S%*d%s%*d%s" , - csv_output ?0 :-5 , + config->csv_output ?0 :-5 , id, - csv_sep, - csv_output ?0 :4 , + config->csv_sep, + config->csv_output ?0 :4 , nr, - csv_sep); + config->csv_sep);break ;case AGGR_NONE :fprintf (config->output,"CPU%*d%s" , - csv_output ?0 :-4 , -perf_evsel__cpus (evsel)->map[id], csv_sep); + config->csv_output ?0 :-4 , +perf_evsel__cpus (evsel)->map[id], config->csv_sep);break ;case AGGR_THREAD :fprintf (config->output,"%*s-%*d%s" , - csv_output ?0 :16 , + config->csv_output ?0 :16 ,thread_map__comm (evsel->threads, id), - csv_output ?0 :-8 , + config->csv_output ?0 :-8 ,thread_map__pid (evsel->threads, id), - csv_sep); + config->csv_sep);break ;case AGGR_GLOBAL :case AGGR_UNSET :
@@ -804,10 +802,10 @@ static void new_line_csv(struct perf_stat_config *config, void *ctx)fputc ('\n' , os->fh);if (os->prefix) -fprintf (os->fh,"%s%s" , os->prefix, csv_sep); +fprintf (os->fh,"%s%s" , os->prefix, config->csv_sep);aggr_printout (config, os->evsel, os->id, os->nr);for (i =0 ; i < os->nfields; i++) -fputs (csv_sep, os->fh); +fputs (config->csv_sep, os->fh); } static void print_metric_csv(struct perf_stat_config *config __maybe_unused,
@@ -820,7 +818,7 @@ static void print_metric_csv(struct perf_stat_config *config __maybe_unused,char buf[64 ], *vals, *ends;if (unit ==NULL || fmt ==NULL ) { -fprintf (out,"%s%s" , csv_sep, csv_sep); +fprintf (out,"%s%s" , config->csv_sep, config->csv_sep);return ; }snprintf (buf,sizeof (buf), fmt, val);
@@ -830,7 +828,7 @@ static void print_metric_csv(struct perf_stat_config *config __maybe_unused, *ends =0 ;while (isspace (*unit)) unit++; -fprintf (out,"%s%s%s%s" , csv_sep, vals, csv_sep, unit); +fprintf (out,"%s%s%s%s" , config->csv_sep, vals, config->csv_sep, unit); }/* Filter out some columns that don't work well in metrics only mode */
@@ -898,7 +896,7 @@ static void print_metric_only_csv(struct perf_stat_config *config __maybe_unusedwhile (isdigit (*ends) || *ends =='.' ) ends++; *ends =0 ; -fprintf (out,"%s%s" , vals, csv_sep); +fprintf (out,"%s%s" , vals, config->csv_sep); } static void new_line_metric(struct perf_stat_config *config __maybe_unused,
@@ -917,8 +915,8 @@ static void print_metric_header(struct perf_stat_config *config __maybe_unused,if (!valid_only_metric (unit))return ; unit =fixunit (tbuf, os->evsel, unit); -if (csv_output) -fprintf (os->fh,"%s%s" , unit, csv_sep); +if (config->csv_output) +fprintf (os->fh,"%s%s" , unit, config->csv_sep);else fprintf (os->fh,"%*s " , metric_only_len, unit); }
@@ -952,7 +950,7 @@ static void abs_printout(struct perf_stat_config *config,double sc = evsel->scale;const char *fmt; -if (csv_output) { +if (config->csv_output) { fmt =floor (sc) != sc ?"%.2f%s" :"%.0f%s" ; }else {if (big_num)
@@ -963,17 +961,17 @@ static void abs_printout(struct perf_stat_config *config,aggr_printout (config, evsel, id, nr); -fprintf (output, fmt, avg, csv_sep); +fprintf (output, fmt, avg, config->csv_sep);if (evsel->unit)fprintf (output,"%-*s%s" , - csv_output ?0 : unit_width, - evsel->unit, csv_sep); + config->csv_output ?0 : unit_width, + evsel->unit, config->csv_sep); -fprintf (output,"%-*s" , csv_output ?0 :25 ,perf_evsel__name (evsel)); +fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel));if (evsel->cgrp) -fprintf (output,"%s%s" , csv_sep, evsel->cgrp->name); +fprintf (output,"%s%s" , config->csv_sep, evsel->cgrp->name); }static bool is_mixed_hw_group (struct perf_evsel *counter)
@@ -1018,14 +1016,14 @@ static void printout(struct perf_stat_config *config, int id, int nr,if (metric_only) { nl = new_line_metric; -if (csv_output) +if (config->csv_output) pm = print_metric_only_csv;else pm = print_metric_only; }else nl = new_line_std; -if (csv_output && !metric_only) { +if (config->csv_output && !metric_only) {static int aggr_fields[] = { [AGGR_GLOBAL ] =0 , [AGGR_THREAD ] =1 ,
@@ -1049,9 +1047,9 @@ static void printout(struct perf_stat_config *config, int id, int nr,aggr_printout (config, counter, id, nr);fprintf (config->output,"%*s%s" , - csv_output ?0 :18 , + config->csv_output ?0 :18 , counter->supported ?CNTR_NOT_COUNTED :CNTR_NOT_SUPPORTED , - csv_sep); + config->csv_sep);if (counter->supported) { print_free_counters_hint =1 ;
@@ -1060,22 +1058,22 @@ static void printout(struct perf_stat_config *config, int id, int nr, }fprintf (config->output,"%-*s%s" , - csv_output ?0 : unit_width, - counter->unit, csv_sep); + config->csv_output ?0 : unit_width, + counter->unit, config->csv_sep);fprintf (config->output,"%*s" , - csv_output ?0 :-25 , + config->csv_output ?0 :-25 ,perf_evsel__name (counter));if (counter->cgrp)fprintf (config->output,"%s%s" , - csv_sep, counter->cgrp->name); + config->csv_sep, counter->cgrp->name); -if (!csv_output) +if (!config->csv_output)pm (config, &os,NULL ,NULL ,"" ,0 );print_noise (config, counter, noise);print_running (config, run, ena); -if (csv_output) +if (config->csv_output)pm (config, &os,NULL ,NULL ,"" ,0 );return ; }
@@ -1088,7 +1086,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, out.ctx = &os; out.force_header = false; -if (csv_output && !metric_only) { +if (config->csv_output && !metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1096,7 +1094,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,perf_stat__print_shadow_stats (config, counter, uval,first_shadow_cpu (counter, id), &out, &metric_events, st); -if (!csv_output && !metric_only) { +if (!config->csv_output && !metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1512,10 +1510,10 @@ static void print_metric_headers(struct perf_stat_config *config,if (prefix)fprintf (config->output,"%s" , prefix); -if (!csv_output && !no_indent) +if (!config->csv_output && !no_indent)fprintf (config->output,"%*s" , aggr_header_lens[config->aggr_mode],"" ); -if (csv_output) { +if (config->csv_output) {if (config->interval)fputs ("time," , config->output);fputs (aggr_header_csv[config->aggr_mode], config->output);
@@ -1549,9 +1547,9 @@ static void print_interval(struct perf_stat_config *config,if (interval_clear)puts (CONSOLE_CLEAR ); -sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, csv_sep); +sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, config->csv_sep); -if ((num_print_interval ==0 && !csv_output) || interval_clear) { +if ((num_print_interval ==0 && !config->csv_output) || interval_clear) {switch (config->aggr_mode) {case AGGR_SOCKET :fprintf (output,"# time socket cpus" );
@@ -1597,7 +1595,7 @@ static void print_header(struct perf_stat_config *config,fflush (stdout); -if (!csv_output) { +if (!config->csv_output) {fprintf (output,"\n" );fprintf (output," Performance counter stats for " );if (target.system_wide)
@@ -1776,7 +1774,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,break ; } -if (!interval && !csv_output) +if (!interval && !config->csv_output)print_footer (config);fflush (config->output);
@@ -1896,7 +1894,7 @@ static const struct option stat_options[] = {OPT_SET_UINT ('A' ,"no-aggr" , &stat_config.aggr_mode,"disable CPU count aggregation" ,AGGR_NONE ),OPT_BOOLEAN (0 ,"no-merge" , &no_merge,"Do not merge identical named events" ), -OPT_STRING ('x' ,"field-separator" , &csv_sep,"separator" , +OPT_STRING ('x' ,"field-separator" , &stat_config.csv_sep,"separator" ,"print counts with custom separator" ),OPT_CALLBACK ('G' ,"cgroup" , &evsel_list,"name" , "monitor event in cgroup name only", parse_cgroups),
@@ -2749,12 +2747,12 @@ int cmd_stat(int argc, const char **argv)perf_stat__collect_metric_expr (evsel_list);perf_stat__init_shadow_stats (); -if (csv_sep) { - csv_output = true; -if (!strcmp (csv_sep,"\\t" )) - csv_sep ="\t" ; +if (stat_config.csv_sep) { + stat_config.csv_output = true; +if (!strcmp (stat_config.csv_sep,"\\t" )) + stat_config.csv_sep ="\t" ; }else - csv_sep =DEFAULT_SEPARATOR ; + stat_config.csv_sep =DEFAULT_SEPARATOR ;if (argc && !strncmp (argv[0 ],"rec" ,3 )) { argc =__cmd_record (argc, argv);
@@ -2827,7 +2825,7 @@ int cmd_stat(int argc, const char **argv)/* * let the spreadsheet do the pretty-printing */ -if (csv_output) { +if (stat_config.csv_output) {/* User explicitly passed -B? */ if (big_num_opt ==1 ) {fprintf (stderr,"-B option not supported with -x\n" );
tools/perf/util/stat.h +2 -0
@@ -91,6 +91,7 @@ struct perf_stat_config {bool scale;bool no_inherit;bool identifier; +bool csv_output;FILE *output;unsigned int interval;unsigned int timeout;
@@ -98,6 +99,7 @@ struct perf_stat_config {int times;struct runtime_stat *stats;int stats_num; +const char *csv_sep; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move csv_* to 'struct perf_stat_config'
perf stat: Move csv_* to 'struct perf_stat_config'
Commit-ID: fa7070a38676d660c0a71ab6981bfdca3b340ccd Gitweb: https://git.kernel.org/tip/fa7070a38676d660c0a71ab6981bfdca3b340ccd Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:29 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Move csv_* to 'struct perf_stat_config'
Move the static csv_* variables to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 114 +++++++++++++++++++++++----------------------- tools/perf/util/stat.h | 2 + 2 files changed, 58 insertions(+), 58 deletions(-)
tools/perf/builtin-stat.c +56 -58
@@ -157,8 +157,6 @@ static bool smi_cost = false;static bool smi_reset = false;static bool big_num = true;static int big_num_opt =-1 ; -static const char *csv_sep =NULL ; -static bool csv_output = false;static bool group = false;static const char *pre_cmd =NULL ;static const char *post_cmd =NULL ;
@@ -663,11 +661,11 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)static void print_running (struct perf_stat_config *config,u64 run,u64 ena) { -if (csv_output) { +if (config->csv_output) {fprintf (config->output,"%s%" PRIu64"%s%.2f" , - csv_sep, + config->csv_sep, run, - csv_sep, + config->csv_sep, ena ?100.0 * run / ena :100.0 ); }else if (run != ena) {fprintf (config->output," (%.2f%%)" ,100.0 * run / ena);
@@ -679,8 +677,8 @@ static void print_noise_pct(struct perf_stat_config *config, {double pct =rel_stddev_stats (total, avg); -if (csv_output) -fprintf (config->output,"%s%.2f%%" , csv_sep, pct); +if (config->csv_output) +fprintf (config->output,"%s%.2f%%" , config->csv_sep, pct);else if (pct)fprintf (config->output," ( +-%6.2f%% )" , pct); }
@@ -704,34 +702,34 @@ static void aggr_printout(struct perf_stat_config *config,case AGGR_CORE :fprintf (config->output,"S%d-C%*d%s%*d%s" ,cpu_map__id_to_socket (id), - csv_output ?0 :-8 , + config->csv_output ?0 :-8 ,cpu_map__id_to_cpu (id), - csv_sep, - csv_output ?0 :4 , + config->csv_sep, + config->csv_output ?0 :4 , nr, - csv_sep); + config->csv_sep);break ;case AGGR_SOCKET :fprintf (config->output,"S%*d%s%*d%s" , - csv_output ?0 :-5 , + config->csv_output ?0 :-5 , id, - csv_sep, - csv_output ?0 :4 , + config->csv_sep, + config->csv_output ?0 :4 , nr, - csv_sep); + config->csv_sep);break ;case AGGR_NONE :fprintf (config->output,"CPU%*d%s" , - csv_output ?0 :-4 , -perf_evsel__cpus (evsel)->map[id], csv_sep); + config->csv_output ?0 :-4 , +perf_evsel__cpus (evsel)->map[id], config->csv_sep);break ;case AGGR_THREAD :fprintf (config->output,"%*s-%*d%s" , - csv_output ?0 :16 , + config->csv_output ?0 :16 ,thread_map__comm (evsel->threads, id), - csv_output ?0 :-8 , + config->csv_output ?0 :-8 ,thread_map__pid (evsel->threads, id), - csv_sep); + config->csv_sep);break ;case AGGR_GLOBAL :case AGGR_UNSET :
@@ -804,10 +802,10 @@ static void new_line_csv(struct perf_stat_config *config, void *ctx)fputc ('\n' , os->fh);if (os->prefix) -fprintf (os->fh,"%s%s" , os->prefix, csv_sep); +fprintf (os->fh,"%s%s" , os->prefix, config->csv_sep);aggr_printout (config, os->evsel, os->id, os->nr);for (i =0 ; i < os->nfields; i++) -fputs (csv_sep, os->fh); +fputs (config->csv_sep, os->fh); } static void print_metric_csv(struct perf_stat_config *config __maybe_unused,
@@ -820,7 +818,7 @@ static void print_metric_csv(struct perf_stat_config *config __maybe_unused,char buf[64 ], *vals, *ends;if (unit ==NULL || fmt ==NULL ) { -fprintf (out,"%s%s" , csv_sep, csv_sep); +fprintf (out,"%s%s" , config->csv_sep, config->csv_sep);return ; }snprintf (buf,sizeof (buf), fmt, val);
@@ -830,7 +828,7 @@ static void print_metric_csv(struct perf_stat_config *config __maybe_unused, *ends =0 ;while (isspace (*unit)) unit++; -fprintf (out,"%s%s%s%s" , csv_sep, vals, csv_sep, unit); +fprintf (out,"%s%s%s%s" , config->csv_sep, vals, config->csv_sep, unit); }/* Filter out some columns that don't work well in metrics only mode */
@@ -898,7 +896,7 @@ static void print_metric_only_csv(struct perf_stat_config *config __maybe_unusedwhile (isdigit (*ends) || *ends =='.' ) ends++; *ends =0 ; -fprintf (out,"%s%s" , vals, csv_sep); +fprintf (out,"%s%s" , vals, config->csv_sep); } static void new_line_metric(struct perf_stat_config *config __maybe_unused,
@@ -917,8 +915,8 @@ static void print_metric_header(struct perf_stat_config *config __maybe_unused,if (!valid_only_metric (unit))return ; unit =fixunit (tbuf, os->evsel, unit); -if (csv_output) -fprintf (os->fh,"%s%s" , unit, csv_sep); +if (config->csv_output) +fprintf (os->fh,"%s%s" , unit, config->csv_sep);else fprintf (os->fh,"%*s " , metric_only_len, unit); }
@@ -952,7 +950,7 @@ static void abs_printout(struct perf_stat_config *config,double sc = evsel->scale;const char *fmt; -if (csv_output) { +if (config->csv_output) { fmt =floor (sc) != sc ?"%.2f%s" :"%.0f%s" ; }else {if (big_num)
@@ -963,17 +961,17 @@ static void abs_printout(struct perf_stat_config *config,aggr_printout (config, evsel, id, nr); -fprintf (output, fmt, avg, csv_sep); +fprintf (output, fmt, avg, config->csv_sep);if (evsel->unit)fprintf (output,"%-*s%s" , - csv_output ?0 : unit_width, - evsel->unit, csv_sep); + config->csv_output ?0 : unit_width, + evsel->unit, config->csv_sep); -fprintf (output,"%-*s" , csv_output ?0 :25 ,perf_evsel__name (evsel)); +fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel));if (evsel->cgrp) -fprintf (output,"%s%s" , csv_sep, evsel->cgrp->name); +fprintf (output,"%s%s" , config->csv_sep, evsel->cgrp->name); }static bool is_mixed_hw_group (struct perf_evsel *counter)
@@ -1018,14 +1016,14 @@ static void printout(struct perf_stat_config *config, int id, int nr,if (metric_only) { nl = new_line_metric; -if (csv_output) +if (config->csv_output) pm = print_metric_only_csv;else pm = print_metric_only; }else nl = new_line_std; -if (csv_output && !metric_only) { +if (config->csv_output && !metric_only) {static int aggr_fields[] = { [AGGR_GLOBAL ] =0 , [AGGR_THREAD ] =1 ,
@@ -1049,9 +1047,9 @@ static void printout(struct perf_stat_config *config, int id, int nr,aggr_printout (config, counter, id, nr);fprintf (config->output,"%*s%s" , - csv_output ?0 :18 , + config->csv_output ?0 :18 , counter->supported ?CNTR_NOT_COUNTED :CNTR_NOT_SUPPORTED , - csv_sep); + config->csv_sep);if (counter->supported) { print_free_counters_hint =1 ;
@@ -1060,22 +1058,22 @@ static void printout(struct perf_stat_config *config, int id, int nr, }fprintf (config->output,"%-*s%s" , - csv_output ?0 : unit_width, - counter->unit, csv_sep); + config->csv_output ?0 : unit_width, + counter->unit, config->csv_sep);fprintf (config->output,"%*s" , - csv_output ?0 :-25 , + config->csv_output ?0 :-25 ,perf_evsel__name (counter));if (counter->cgrp)fprintf (config->output,"%s%s" , - csv_sep, counter->cgrp->name); + config->csv_sep, counter->cgrp->name); -if (!csv_output) +if (!config->csv_output)pm (config, &os,NULL ,NULL ,"" ,0 );print_noise (config, counter, noise);print_running (config, run, ena); -if (csv_output) +if (config->csv_output)pm (config, &os,NULL ,NULL ,"" ,0 );return ; }
@@ -1088,7 +1086,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, out.ctx = &os; out.force_header = false; -if (csv_output && !metric_only) { +if (config->csv_output && !metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1096,7 +1094,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,perf_stat__print_shadow_stats (config, counter, uval,first_shadow_cpu (counter, id), &out, &metric_events, st); -if (!csv_output && !metric_only) { +if (!config->csv_output && !metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1512,10 +1510,10 @@ static void print_metric_headers(struct perf_stat_config *config,if (prefix)fprintf (config->output,"%s" , prefix); -if (!csv_output && !no_indent) +if (!config->csv_output && !no_indent)fprintf (config->output,"%*s" , aggr_header_lens[config->aggr_mode],"" ); -if (csv_output) { +if (config->csv_output) {if (config->interval)fputs ("time," , config->output);fputs (aggr_header_csv[config->aggr_mode], config->output);
@@ -1549,9 +1547,9 @@ static void print_interval(struct perf_stat_config *config,if (interval_clear)puts (CONSOLE_CLEAR ); -sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, csv_sep); +sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, config->csv_sep); -if ((num_print_interval ==0 && !csv_output) || interval_clear) { +if ((num_print_interval ==0 && !config->csv_output) || interval_clear) {switch (config->aggr_mode) {case AGGR_SOCKET :fprintf (output,"# time socket cpus" );
@@ -1597,7 +1595,7 @@ static void print_header(struct perf_stat_config *config,fflush (stdout); -if (!csv_output) { +if (!config->csv_output) {fprintf (output,"\n" );fprintf (output," Performance counter stats for " );if (target.system_wide)
@@ -1776,7 +1774,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,break ; } -if (!interval && !csv_output) +if (!interval && !config->csv_output)print_footer (config);fflush (config->output);
@@ -1896,7 +1894,7 @@ static const struct option stat_options[] = {OPT_SET_UINT ('A' ,"no-aggr" , &stat_config.aggr_mode,"disable CPU count aggregation" ,AGGR_NONE ),OPT_BOOLEAN (0 ,"no-merge" , &no_merge,"Do not merge identical named events" ), -OPT_STRING ('x' ,"field-separator" , &csv_sep,"separator" , +OPT_STRING ('x' ,"field-separator" , &stat_config.csv_sep,"separator" ,"print counts with custom separator" ),OPT_CALLBACK ('G' ,"cgroup" , &evsel_list,"name" , "monitor event in cgroup name only", parse_cgroups),
@@ -2749,12 +2747,12 @@ int cmd_stat(int argc, const char **argv)perf_stat__collect_metric_expr (evsel_list);perf_stat__init_shadow_stats (); -if (csv_sep) { - csv_output = true; -if (!strcmp (csv_sep,"\\t" )) - csv_sep ="\t" ; +if (stat_config.csv_sep) { + stat_config.csv_output = true; +if (!strcmp (stat_config.csv_sep,"\\t" )) + stat_config.csv_sep ="\t" ; }else - csv_sep =DEFAULT_SEPARATOR ; + stat_config.csv_sep =DEFAULT_SEPARATOR ;if (argc && !strncmp (argv[0 ],"rec" ,3 )) { argc =__cmd_record (argc, argv);
@@ -2827,7 +2825,7 @@ int cmd_stat(int argc, const char **argv)/* * let the spreadsheet do the pretty-printing */ -if (csv_output) { +if (stat_config.csv_output) {/* User explicitly passed -B? */ if (big_num_opt ==1 ) {fprintf (stderr,"-B option not supported with -x\n" );
tools/perf/util/stat.h +2 -0
@@ -91,6 +91,7 @@ struct perf_stat_config {bool scale;bool no_inherit;bool identifier; +bool csv_output;FILE *output;unsigned int interval;unsigned int timeout;
@@ -98,6 +99,7 @@ struct perf_stat_config {int times;struct runtime_stat *stats;int stats_num; +const char *csv_sep; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 21/43 perf stat: Move interval_clear into struct perf_stat_config
In reply to Jiri OlsaMoving static interval_clear into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 9 ++++----- tools/perf/util/stat.h | 1 + 2 files changed, 5 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +4 -5
@@ -172,7 +172,6 @@ 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;
@@ -1544,12 +1543,12 @@ static void print_interval(struct perf_stat_config *config,FILE *output = config->output;static int num_print_interval; -if (interval_clear) +if (config->interval_clear)puts (CONSOLE_CLEAR );sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, config->csv_sep); -if ((num_print_interval ==0 && !config->csv_output) || interval_clear) { +if ((num_print_interval ==0 && !config->csv_output) || config->interval_clear) {switch (config->aggr_mode) {case AGGR_SOCKET :fprintf (output,"# time socket cpus" );
@@ -1581,7 +1580,7 @@ static void print_interval(struct perf_stat_config *config, } } -if ((num_print_interval ==0 || interval_clear) && metric_only) +if ((num_print_interval ==0 || config->interval_clear) && metric_only)print_metric_headers (config," " , true);if (++num_print_interval ==25 ) num_print_interval =0 ;
@@ -1911,7 +1910,7 @@ 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, +OPT_BOOLEAN (0 ,"interval-clear" , &stat_config.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)"),
tools/perf/util/stat.h +1 -0
@@ -92,6 +92,7 @@ struct perf_stat_config {bool no_inherit;bool identifier;bool csv_output; +bool interval_clear;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'interval_clear' to 'struct perf_stat_config'
perf stat: Move 'interval_clear' to 'struct perf_stat_config'
Commit-ID: 132c6ba3c440fd21a45ff7f9d7a1f53813f4d0e3 Gitweb: https://git.kernel.org/tip/132c6ba3c440fd21a45ff7f9d7a1f53813f4d0e3 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:30 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Move 'interval_clear' to 'struct perf_stat_config'
Move the static 'interval_clear' variable to 'struct perf_stat_config', so it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 9 ++++----- tools/perf/util/stat.h | 1 + 2 files changed, 5 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +4 -5
@@ -172,7 +172,6 @@ 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;
@@ -1544,12 +1543,12 @@ static void print_interval(struct perf_stat_config *config,FILE *output = config->output;static int num_print_interval; -if (interval_clear) +if (config->interval_clear)puts (CONSOLE_CLEAR );sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, config->csv_sep); -if ((num_print_interval ==0 && !config->csv_output) || interval_clear) { +if ((num_print_interval ==0 && !config->csv_output) || config->interval_clear) {switch (config->aggr_mode) {case AGGR_SOCKET :fprintf (output,"# time socket cpus" );
@@ -1581,7 +1580,7 @@ static void print_interval(struct perf_stat_config *config, } } -if ((num_print_interval ==0 || interval_clear) && metric_only) +if ((num_print_interval ==0 || config->interval_clear) && metric_only)print_metric_headers (config," " , true);if (++num_print_interval ==25 ) num_print_interval =0 ;
@@ -1911,7 +1910,7 @@ 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, +OPT_BOOLEAN (0 ,"interval-clear" , &stat_config.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)"),
tools/perf/util/stat.h +1 -0
@@ -92,6 +92,7 @@ struct perf_stat_config {bool no_inherit;bool identifier;bool csv_output; +bool interval_clear;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 22/43 perf stat: Move metric_only into struct perf_stat_config
In reply to Jiri OlsaMoving static metric_only into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 29 ++++++++++++++++------------- tools/perf/util/stat.h | 1 + 2 files changed, 17 insertions(+), 13 deletions(-)
tools/perf/builtin-stat.c +16 -13
@@ -163,7 +163,6 @@ static const char *post_cmd = NULL;static bool sync_run = false;static unsigned int unit_width =4 ;/* strlen("unit") */ static bool forever = false; -static bool metric_only = false;static bool force_metric_only = false;static bool no_merge = false;static bool walltime_run_table = false;
@@ -1013,7 +1012,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,print_metric_t pm = print_metric_std;new_line_t nl; -if (metric_only) { +if (config->metric_only) { nl = new_line_metric;if (config->csv_output) pm = print_metric_only_csv;
@@ -1022,7 +1021,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, } else nl = new_line_std; -if (config->csv_output && !metric_only) { +if (config->csv_output && !config->metric_only) {static int aggr_fields[] = { [AGGR_GLOBAL ] =0 , [AGGR_THREAD ] =1 ,
@@ -1039,7 +1038,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, os.nfields++; }if (run ==0 || ena ==0 || counter->counts->scaled ==-1 ) { -if (metric_only) { +if (config->metric_only) {pm (config, &os,NULL ,"" ,"" ,0 );return ; }
@@ -1077,7 +1076,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,return ; } -if (!metric_only) +if (!config->metric_only)abs_printout (config, id, nr, counter, uval); out.print_metric = pm;
@@ -1085,7 +1084,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, out.ctx = &os; out.force_header = false; -if (config->csv_output && !metric_only) { +if (config->csv_output && !config->metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1093,7 +1092,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,perf_stat__print_shadow_stats (config, counter, uval,first_shadow_cpu (counter, id), &out, &metric_events, st); -if (!config->csv_output && !metric_only) { +if (!config->csv_output && !config->metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1225,6 +1224,7 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first)static void print_aggr (struct perf_stat_config *config,char *prefix) { +bool metric_only = config->metric_only;FILE *output = config->output;struct perf_evsel *counter;int s, id, nr;
@@ -1388,6 +1388,7 @@ static void counter_aggr_cb(struct perf_evsel *counter, void *data,static void print_counter_aggr (struct perf_stat_config *config,struct perf_evsel *counter,char *prefix) { +bool metric_only = config->metric_only;FILE *output = config->output;double uval;struct caggr_data cd = { .avg =0.0 };
@@ -1540,6 +1541,7 @@ static void print_metric_headers(struct perf_stat_config *config,static void print_interval (struct perf_stat_config *config,char *prefix,struct timespec *ts) { +bool metric_only = config->metric_only;FILE *output = config->output;static int num_print_interval;
@@ -1716,6 +1718,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,struct timespec *ts, int argc, const char **argv) { + bool metric_only = config->metric_only;int interval = config->interval;struct perf_evsel *counter;char buf[64 ], *prefix =NULL ;
@@ -1843,7 +1846,7 @@ static int enable_metric_only(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset) { force_metric_only = true; - metric_only = !unset; + stat_config.metric_only = !unset;return 0 ; }
@@ -1922,7 +1925,7 @@ static const struct option stat_options[] = { "aggregate counts per thread", AGGR_THREAD),OPT_UINTEGER ('D' ,"delay" , &stat_config.initial_delay,"ms to wait before starting measurement after program start" ), -OPT_CALLBACK_NOOPT (0 ,"metric-only" , &metric_only,NULL , +OPT_CALLBACK_NOOPT (0 ,"metric-only" , &stat_config.metric_only,NULL ,"Only print computed metrics. No raw values" , enable_metric_only),OPT_BOOLEAN (0 ,"topdown" , &topdown_run, "measure topdown level 1 statistics"),
@@ -2345,7 +2348,7 @@ static int add_default_attributes(void)if (pmu_have_event ("msr" ,"aperf" ) &&pmu_have_event ("msr" ,"smi" )) {if (!force_metric_only) - metric_only = true; + stat_config.metric_only = true; err =parse_events (evsel_list, smi_cost_attrs, &errinfo); }else { fprintf(stderr, "To measure SMI cost, it needs "
@@ -2376,7 +2379,7 @@ static int add_default_attributes(void) }if (!force_metric_only) - metric_only = true; + stat_config.metric_only = true;if (topdown_filter_events (topdown_attrs, &str,arch_topdown_check_group (&warn)) <0 ) {pr_err ("Out of memory\n" );
@@ -2776,12 +2779,12 @@ int cmd_stat(int argc, const char **argv) goto out; } -if (metric_only && stat_config.aggr_mode ==AGGR_THREAD ) { +if (stat_config.metric_only && stat_config.aggr_mode ==AGGR_THREAD ) {fprintf (stderr,"--metric-only is not supported with --per-thread\n" ); goto out; } -if (metric_only && run_count >1 ) { +if (stat_config.metric_only && run_count >1 ) {fprintf (stderr,"--metric-only is not supported with -r\n" ); goto out; }
tools/perf/util/stat.h +1 -0
@@ -93,6 +93,7 @@ struct perf_stat_config {bool identifier;bool csv_output;bool interval_clear; +bool metric_only;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'metric_only' to 'struct perf_stat_config'
perf stat: Move 'metric_only' to 'struct perf_stat_config'
Commit-ID: 0ce5aa0266604c77ee64882b70c980e843629177 Gitweb: https://git.kernel.org/tip/0ce5aa0266604c77ee64882b70c980e843629177 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:31 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Move 'metric_only' to 'struct perf_stat_config'
Move the static 'metric_only' variable to 'struct perf_stat_config', so it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 29 ++++++++++++++++------------- tools/perf/util/stat.h | 1 + 2 files changed, 17 insertions(+), 13 deletions(-)
tools/perf/builtin-stat.c +16 -13
@@ -163,7 +163,6 @@ static const char *post_cmd = NULL;static bool sync_run = false;static unsigned int unit_width =4 ;/* strlen("unit") */ static bool forever = false; -static bool metric_only = false;static bool force_metric_only = false;static bool no_merge = false;static bool walltime_run_table = false;
@@ -1013,7 +1012,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,print_metric_t pm = print_metric_std;new_line_t nl; -if (metric_only) { +if (config->metric_only) { nl = new_line_metric;if (config->csv_output) pm = print_metric_only_csv;
@@ -1022,7 +1021,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, } else nl = new_line_std; -if (config->csv_output && !metric_only) { +if (config->csv_output && !config->metric_only) {static int aggr_fields[] = { [AGGR_GLOBAL ] =0 , [AGGR_THREAD ] =1 ,
@@ -1039,7 +1038,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, os.nfields++; }if (run ==0 || ena ==0 || counter->counts->scaled ==-1 ) { -if (metric_only) { +if (config->metric_only) {pm (config, &os,NULL ,"" ,"" ,0 );return ; }
@@ -1077,7 +1076,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,return ; } -if (!metric_only) +if (!config->metric_only)abs_printout (config, id, nr, counter, uval); out.print_metric = pm;
@@ -1085,7 +1084,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, out.ctx = &os; out.force_header = false; -if (config->csv_output && !metric_only) { +if (config->csv_output && !config->metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1093,7 +1092,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,perf_stat__print_shadow_stats (config, counter, uval,first_shadow_cpu (counter, id), &out, &metric_events, st); -if (!config->csv_output && !metric_only) { +if (!config->csv_output && !config->metric_only) {print_noise (config, counter, noise);print_running (config, run, ena); }
@@ -1225,6 +1224,7 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first)static void print_aggr (struct perf_stat_config *config,char *prefix) { +bool metric_only = config->metric_only;FILE *output = config->output;struct perf_evsel *counter;int s, id, nr;
@@ -1388,6 +1388,7 @@ static void counter_aggr_cb(struct perf_evsel *counter, void *data,static void print_counter_aggr (struct perf_stat_config *config,struct perf_evsel *counter,char *prefix) { +bool metric_only = config->metric_only;FILE *output = config->output;double uval;struct caggr_data cd = { .avg =0.0 };
@@ -1540,6 +1541,7 @@ static void print_metric_headers(struct perf_stat_config *config,static void print_interval (struct perf_stat_config *config,char *prefix,struct timespec *ts) { +bool metric_only = config->metric_only;FILE *output = config->output;static int num_print_interval;
@@ -1716,6 +1718,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,struct timespec *ts, int argc, const char **argv) { + bool metric_only = config->metric_only;int interval = config->interval;struct perf_evsel *counter;char buf[64 ], *prefix =NULL ;
@@ -1843,7 +1846,7 @@ static int enable_metric_only(const struct option *opt __maybe_unused, const char *s __maybe_unused, int unset) { force_metric_only = true; - metric_only = !unset; + stat_config.metric_only = !unset;return 0 ; }
@@ -1922,7 +1925,7 @@ static const struct option stat_options[] = { "aggregate counts per thread", AGGR_THREAD),OPT_UINTEGER ('D' ,"delay" , &stat_config.initial_delay,"ms to wait before starting measurement after program start" ), -OPT_CALLBACK_NOOPT (0 ,"metric-only" , &metric_only,NULL , +OPT_CALLBACK_NOOPT (0 ,"metric-only" , &stat_config.metric_only,NULL ,"Only print computed metrics. No raw values" , enable_metric_only),OPT_BOOLEAN (0 ,"topdown" , &topdown_run, "measure topdown level 1 statistics"),
@@ -2345,7 +2348,7 @@ static int add_default_attributes(void)if (pmu_have_event ("msr" ,"aperf" ) &&pmu_have_event ("msr" ,"smi" )) {if (!force_metric_only) - metric_only = true; + stat_config.metric_only = true; err =parse_events (evsel_list, smi_cost_attrs, &errinfo); }else { fprintf(stderr, "To measure SMI cost, it needs "
@@ -2376,7 +2379,7 @@ static int add_default_attributes(void) }if (!force_metric_only) - metric_only = true; + stat_config.metric_only = true;if (topdown_filter_events (topdown_attrs, &str,arch_topdown_check_group (&warn)) <0 ) {pr_err ("Out of memory\n" );
@@ -2776,12 +2779,12 @@ int cmd_stat(int argc, const char **argv) goto out; } -if (metric_only && stat_config.aggr_mode ==AGGR_THREAD ) { +if (stat_config.metric_only && stat_config.aggr_mode ==AGGR_THREAD ) {fprintf (stderr,"--metric-only is not supported with --per-thread\n" ); goto out; } -if (metric_only && run_count >1 ) { +if (stat_config.metric_only && run_count >1 ) {fprintf (stderr,"--metric-only is not supported with -r\n" ); goto out; }
tools/perf/util/stat.h +1 -0
@@ -93,6 +93,7 @@ struct perf_stat_config {bool identifier;bool csv_output;bool interval_clear; +bool metric_only;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 23/43 perf stat: Move unit_width into struct perf_stat_config
In reply to Jiri OlsaMoving static unit_width into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 11 ++++++----- tools/perf/util/stat.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +6 -5
@@ -161,7 +161,6 @@ static bool group = false;static const char *pre_cmd =NULL ;static const char *post_cmd =NULL ;static bool sync_run = false; -static unsigned int unit_width =4 ;/* strlen("unit") */ static bool forever = false;static bool force_metric_only = false;static bool no_merge = false;
@@ -200,6 +199,7 @@ static volatile int done = 0;static struct perf_stat_config stat_config = { .aggr_mode =AGGR_GLOBAL , .scale = true, + .unit_width =4 ,/* strlen("unit") */ };static bool is_duration_time (struct perf_evsel *evsel)
@@ -524,8 +524,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) counter->supported = true; l =strlen (counter->unit); -if (l > unit_width) - unit_width = l; +if (l > stat_config.unit_width) + stat_config.unit_width = l;if (perf_evsel__should_store_id (counter) &&perf_evsel__store_ids (counter, evsel_list))
@@ -963,7 +963,7 @@ static void abs_printout(struct perf_stat_config *config,if (evsel->unit)fprintf (output,"%-*s%s" , - config->csv_output ?0 : unit_width, + config->csv_output ?0 : config->unit_width, evsel->unit, config->csv_sep);fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel));
@@ -1056,7 +1056,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, }fprintf (config->output,"%-*s%s" , - config->csv_output ?0 : unit_width, + config->csv_output ?0 : config->unit_width, counter->unit, config->csv_sep); fprintf(config->output, "%*s",
@@ -1542,6 +1542,7 @@ static void print_interval(struct perf_stat_config *config, char *prefix, struct timespec *ts) { bool metric_only = config->metric_only; +unsigned int unit_width = config->unit_width;FILE *output = config->output;static int num_print_interval;
tools/perf/util/stat.h +1 -0
@@ -98,6 +98,7 @@ struct perf_stat_config {unsigned int interval;unsigned int timeout;unsigned int initial_delay; +unsigned int unit_width;int times;struct runtime_stat *stats;int stats_num;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'unit_width' to 'struct perf_stat_config'
perf stat: Move 'unit_width' to 'struct perf_stat_config'
Commit-ID: df4f7b4d4b1e61e6b16ac2e3760be46bac86e4f4 Gitweb: https://git.kernel.org/tip/df4f7b4d4b1e61e6b16ac2e3760be46bac86e4f4 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:32 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Move 'unit_width' to 'struct perf_stat_config'
Move the static 'unit_width' variable to 'struct perf_stat_config', so it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 11 ++++++----- tools/perf/util/stat.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +6 -5
@@ -161,7 +161,6 @@ static bool group = false;static const char *pre_cmd =NULL ;static const char *post_cmd =NULL ;static bool sync_run = false; -static unsigned int unit_width =4 ;/* strlen("unit") */ static bool forever = false;static bool force_metric_only = false;static bool no_merge = false;
@@ -200,6 +199,7 @@ static volatile int done = 0;static struct perf_stat_config stat_config = { .aggr_mode =AGGR_GLOBAL , .scale = true, + .unit_width =4 ,/* strlen("unit") */ };static bool is_duration_time (struct perf_evsel *evsel)
@@ -524,8 +524,8 @@ try_again: counter->supported = true; l =strlen (counter->unit); -if (l > unit_width) - unit_width = l; +if (l > stat_config.unit_width) + stat_config.unit_width = l;if (perf_evsel__should_store_id (counter) &&perf_evsel__store_ids (counter, evsel_list))
@@ -963,7 +963,7 @@ static void abs_printout(struct perf_stat_config *config,if (evsel->unit)fprintf (output,"%-*s%s" , - config->csv_output ?0 : unit_width, + config->csv_output ?0 : config->unit_width, evsel->unit, config->csv_sep);fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel));
@@ -1056,7 +1056,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, }fprintf (config->output,"%-*s%s" , - config->csv_output ?0 : unit_width, + config->csv_output ?0 : config->unit_width, counter->unit, config->csv_sep); fprintf(config->output, "%*s",
@@ -1542,6 +1542,7 @@ static void print_interval(struct perf_stat_config *config, char *prefix, struct timespec *ts) { bool metric_only = config->metric_only; +unsigned int unit_width = config->unit_width;FILE *output = config->output;static int num_print_interval;
tools/perf/util/stat.h +1 -0
@@ -98,6 +98,7 @@ struct perf_stat_config {unsigned int interval;unsigned int timeout;unsigned int initial_delay; +unsigned int unit_width;int times;struct runtime_stat *stats;int stats_num;
Jiri Olsa
reviewerPATCH 24/43 perf stat: Add target argument to perf_evlist__print_counters
In reply to Jiri OlsaAdding 'struct target' argument to perf_evlist__print_counters, so the function does not depend on stat command object local target and can be moved out.
--- tools/perf/builtin-stat.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
tools/perf/builtin-stat.c +11 -9
@@ -1590,6 +1590,7 @@ static void print_interval(struct perf_stat_config *config, }static void print_header (struct perf_stat_config *config, +struct target *_target,int argc,const char **argv) {FILE *output = config->output;
@@ -1600,18 +1601,18 @@ static void print_header(struct perf_stat_config *config,if (!config->csv_output) {fprintf (output,"\n" );fprintf (output," Performance counter stats for " ); -if (target.system_wide) +if (_target->system_wide)fprintf (output,"\'system wide" ); -else if (target.cpu_list) -fprintf (output,"\'CPU(s) %s" , target.cpu_list); -else if (!target__has_task (&target)) { +else if (_target->cpu_list) +fprintf (output,"\'CPU(s) %s" , _target->cpu_list); +else if (!target__has_task (_target)) {fprintf (output,"\'%s" , argv ? argv[0 ] :"pipe" );for (i =1 ; argv && (i < argc); i++)fprintf (output," %s" , argv[i]); - }else if (target.pid) -fprintf (output,"process id \'%s" , target.pid); + }else if (_target->pid) +fprintf (output,"process id \'%s" , _target->pid);else -fprintf (output,"thread id \'%s" , target.tid); +fprintf (output,"thread id \'%s" , _target->tid);fprintf (output,"\'" );if (run_count >1 )
@@ -1716,6 +1717,7 @@ static void print_footer(struct perf_stat_config *config)static void perf_evlist__print_counters (struct perf_evlist *evlist,struct perf_stat_config *config, +struct target *_target,struct timespec *ts,int argc,const char **argv) {
@@ -1727,7 +1729,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,if (interval)print_interval (config, prefix = buf, ts);else -print_header (config, argc, argv); +print_header (config, _target, argc, argv);if (metric_only) {static int num_print_iv;
@@ -1789,7 +1791,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)if (STAT_RECORD && perf_stat.data.is_pipe)return ; -perf_evlist__print_counters (evsel_list, &stat_config, +perf_evlist__print_counters (evsel_list, &stat_config, &target, ts, argc, argv); }
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'target' argument to perf_evlist__print_counters()
perf stat: Add 'target' argument to perf_evlist__print_counters()
Commit-ID: c512e0eae4c63be8c5964c3942b2e9c04dcd459e Gitweb: https://git.kernel.org/tip/c512e0eae4c63be8c5964c3942b2e9c04dcd459e Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:33 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Add 'target' argument to perf_evlist__print_counters()
Add 'struct target' argument to perf_evlist__print_counters(), so the function does not depend on the 'perf stat' command object local target and can be moved out.
--- tools/perf/builtin-stat.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
tools/perf/builtin-stat.c +11 -9
@@ -1590,6 +1590,7 @@ static void print_interval(struct perf_stat_config *config, }static void print_header (struct perf_stat_config *config, +struct target *_target,int argc,const char **argv) {FILE *output = config->output;
@@ -1600,18 +1601,18 @@ static void print_header(struct perf_stat_config *config,if (!config->csv_output) {fprintf (output,"\n" );fprintf (output," Performance counter stats for " ); -if (target.system_wide) +if (_target->system_wide)fprintf (output,"\'system wide" ); -else if (target.cpu_list) -fprintf (output,"\'CPU(s) %s" , target.cpu_list); -else if (!target__has_task (&target)) { +else if (_target->cpu_list) +fprintf (output,"\'CPU(s) %s" , _target->cpu_list); +else if (!target__has_task (_target)) {fprintf (output,"\'%s" , argv ? argv[0 ] :"pipe" );for (i =1 ; argv && (i < argc); i++)fprintf (output," %s" , argv[i]); - }else if (target.pid) -fprintf (output,"process id \'%s" , target.pid); + }else if (_target->pid) +fprintf (output,"process id \'%s" , _target->pid);else -fprintf (output,"thread id \'%s" , target.tid); +fprintf (output,"thread id \'%s" , _target->tid);fprintf (output,"\'" );if (run_count >1 )
@@ -1716,6 +1717,7 @@ static void print_footer(struct perf_stat_config *config)static void perf_evlist__print_counters (struct perf_evlist *evlist,struct perf_stat_config *config, +struct target *_target,struct timespec *ts,int argc,const char **argv) {
@@ -1727,7 +1729,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,if (interval)print_interval (config, prefix = buf, ts);else -print_header (config, argc, argv); +print_header (config, _target, argc, argv);if (metric_only) {static int num_print_iv;
@@ -1789,7 +1791,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)if (STAT_RECORD && perf_stat.data.is_pipe)return ; -perf_evlist__print_counters (evsel_list, &stat_config, +perf_evlist__print_counters (evsel_list, &stat_config, &target, ts, argc, argv); }
Jiri Olsa
reviewerPATCH 25/43 perf stat: Pass evlist argument to print functions
In reply to Jiri OlsaAdding evlist argument to print functions to get
rid of the evsel_list dependency.
--- tools/perf/builtin-stat.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
tools/perf/builtin-stat.c +13 -9
@@ -1222,6 +1222,7 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first) }static void print_aggr (struct perf_stat_config *config, +struct perf_evlist *evlist,char *prefix) {bool metric_only = config->metric_only;
@@ -1248,7 +1249,7 @@ static void print_aggr(struct perf_stat_config *config, ad.id = id = aggr_map->map[s]; first = true; -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;
@@ -1449,6 +1450,7 @@ static void print_counter(struct perf_stat_config *config, }static void print_no_aggr_metric (struct perf_stat_config *config, +struct perf_evlist *evlist,char *prefix) {int cpu;
@@ -1457,13 +1459,13 @@ static void print_no_aggr_metric(struct perf_stat_config *config,u64 ena, run, val;double uval; - nrcpus = evsel_list->cpus->nr; + nrcpus = evlist->cpus->nr;for (cpu =0 ; cpu < nrcpus; cpu++) {bool first = true;if (prefix)fputs (prefix, config->output); -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;if (first) {
@@ -1499,6 +1501,7 @@ static const char *aggr_header_csv[] = { };static void print_metric_headers (struct perf_stat_config *config, +struct perf_evlist *evlist,const char *prefix,bool no_indent) {struct perf_stat_output_ctx out;
@@ -1520,7 +1523,7 @@ static void print_metric_headers(struct perf_stat_config *config, }/* Print metrics headers only */ -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; os.evsel = counter;
@@ -1539,6 +1542,7 @@ static void print_metric_headers(struct perf_stat_config *config, }static void print_interval (struct perf_stat_config *config, +struct perf_evlist *evlist,char *prefix,struct timespec *ts) {bool metric_only = config->metric_only;
@@ -1584,7 +1588,7 @@ static void print_interval(struct perf_stat_config *config, }if ((num_print_interval ==0 || config->interval_clear) && metric_only) -print_metric_headers (config," " , true); +print_metric_headers (config, evlist," " , true);if (++num_print_interval ==25 ) num_print_interval =0 ; }
@@ -1727,7 +1731,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,char buf[64 ], *prefix =NULL ;if (interval) -print_interval (config, prefix = buf, ts); +print_interval (config, evlist, prefix = buf, ts);else print_header (config, _target, argc, argv);
@@ -1735,7 +1739,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,static int num_print_iv;if (num_print_iv ==0 && !interval) -print_metric_headers (config, prefix, false); +print_metric_headers (config, evlist, prefix, false);if (num_print_iv++ ==25 ) num_print_iv =0 ;if (config->aggr_mode ==AGGR_GLOBAL && prefix)
@@ -1745,7 +1749,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,switch (config->aggr_mode) {case AGGR_CORE :case AGGR_SOCKET : -print_aggr (config, prefix); +print_aggr (config, evlist, prefix);break ;case AGGR_THREAD :evlist__for_each_entry (evlist, counter) {
@@ -1765,7 +1769,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,break ;case AGGR_NONE :if (metric_only) -print_no_aggr_metric (config, prefix); +print_no_aggr_metric (config, evlist, prefix);else {evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Pass 'evlist' argument to print functions
perf stat: Pass 'evlist' argument to print functions
Commit-ID: bc0bcda201e87d62f0922fa664376355b0fc77ff Gitweb: https://git.kernel.org/tip/bc0bcda201e87d62f0922fa664376355b0fc77ff Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:34 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Pass 'evlist' argument to print functions
Add 'evlist' argument to print functions to get rid of the global 'evsel_list' variable dependency.
--- tools/perf/builtin-stat.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
tools/perf/builtin-stat.c +13 -9
@@ -1222,6 +1222,7 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first) }static void print_aggr (struct perf_stat_config *config, +struct perf_evlist *evlist,char *prefix) {bool metric_only = config->metric_only;
@@ -1248,7 +1249,7 @@ static void print_aggr(struct perf_stat_config *config, ad.id = id = aggr_map->map[s]; first = true; -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;
@@ -1449,6 +1450,7 @@ static void print_counter(struct perf_stat_config *config, }static void print_no_aggr_metric (struct perf_stat_config *config, +struct perf_evlist *evlist,char *prefix) {int cpu;
@@ -1457,13 +1459,13 @@ static void print_no_aggr_metric(struct perf_stat_config *config,u64 ena, run, val;double uval; - nrcpus = evsel_list->cpus->nr; + nrcpus = evlist->cpus->nr;for (cpu =0 ; cpu < nrcpus; cpu++) {bool first = true;if (prefix)fputs (prefix, config->output); -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ;if (first) {
@@ -1499,6 +1501,7 @@ static const char *aggr_header_csv[] = { };static void print_metric_headers (struct perf_stat_config *config, +struct perf_evlist *evlist,const char *prefix,bool no_indent) {struct perf_stat_output_ctx out;
@@ -1520,7 +1523,7 @@ static void print_metric_headers(struct perf_stat_config *config, }/* Print metrics headers only */ -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; os.evsel = counter;
@@ -1539,6 +1542,7 @@ static void print_metric_headers(struct perf_stat_config *config, }static void print_interval (struct perf_stat_config *config, +struct perf_evlist *evlist,char *prefix,struct timespec *ts) {bool metric_only = config->metric_only;
@@ -1584,7 +1588,7 @@ static void print_interval(struct perf_stat_config *config, }if ((num_print_interval ==0 || config->interval_clear) && metric_only) -print_metric_headers (config," " , true); +print_metric_headers (config, evlist," " , true);if (++num_print_interval ==25 ) num_print_interval =0 ; }
@@ -1727,7 +1731,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,char buf[64 ], *prefix =NULL ;if (interval) -print_interval (config, prefix = buf, ts); +print_interval (config, evlist, prefix = buf, ts);else print_header (config, _target, argc, argv);
@@ -1735,7 +1739,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,static int num_print_iv;if (num_print_iv ==0 && !interval) -print_metric_headers (config, prefix, false); +print_metric_headers (config, evlist, prefix, false);if (num_print_iv++ ==25 ) num_print_iv =0 ;if (config->aggr_mode ==AGGR_GLOBAL && prefix)
@@ -1745,7 +1749,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,switch (config->aggr_mode) {case AGGR_CORE :case AGGR_SOCKET : -print_aggr (config, prefix); +print_aggr (config, evlist, prefix);break ;case AGGR_THREAD :evlist__for_each_entry (evlist, counter) {
@@ -1765,7 +1769,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,break ;case AGGR_NONE :if (metric_only) -print_no_aggr_metric (config, prefix); +print_no_aggr_metric (config, evlist, prefix);else {evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))
Jiri Olsa
reviewerPATCH 26/43 perf stat: Use evsel->evlist instead of evsel_list in collect_all_aliases
In reply to Jiri OlsaUsing evsel->evlist instead of evsel_list in collect_all_aliases, to rid of the evsel_list dependency.
--- tools/perf/builtin-stat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +3 -2
@@ -1154,10 +1154,11 @@ static void collect_all_aliases(struct perf_evsel *counter, bool first), void *data) { + struct perf_evlist *evlist = counter->evlist;struct perf_evsel *alias; - alias =list_prepare_entry (counter, &(evsel_list->entries), node); - list_for_each_entry_continue (alias, &evsel_list->entries, node) { + alias =list_prepare_entry (counter, &(evlist->entries), node); + list_for_each_entry_continue (alias, &evlist->entries, node) { if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) || alias->scale != counter->scale || alias->cgrp != counter->cgrp ||
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Use 'evsel->evlist' instead of 'evsel_list' in collect_all_aliases()
perf stat: Use 'evsel->evlist' instead of 'evsel_list' in collect_all_aliases()
Commit-ID: 0c538a9462953dfcde2fe961aca2cf75c2747040 Gitweb: https://git.kernel.org/tip/0c538a9462953dfcde2fe961aca2cf75c2747040 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:35 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Use 'evsel->evlist' instead of 'evsel_list' in collect_all_aliases()
Use 'evsel->evlist' instead of 'evsel_list' in collect_all_aliases(), to get rid of the global 'evsel_list' variable dependency.
--- tools/perf/builtin-stat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +3 -2
@@ -1154,10 +1154,11 @@ static void collect_all_aliases(struct perf_evsel *counter, bool first), void *data) { + struct perf_evlist *evlist = counter->evlist;struct perf_evsel *alias; - alias =list_prepare_entry (counter, &(evsel_list->entries), node); - list_for_each_entry_continue (alias, &evsel_list->entries, node) { + alias =list_prepare_entry (counter, &(evlist->entries), node); + list_for_each_entry_continue (alias, &evlist->entries, node) { if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) || alias->scale != counter->scale || alias->cgrp != counter->cgrp ||
Jiri Olsa
reviewerPATCH 27/43 perf stat: Move run_count into struct perf_stat_config
In reply to Jiri OlsaMoving static run_count into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 39 ++++++++++++++++++++------------------- tools/perf/util/stat.h | 1 + 2 files changed, 21 insertions(+), 19 deletions(-)
tools/perf/builtin-stat.c +20 -19
@@ -147,7 +147,6 @@ typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);#define METRIC_ONLY_LEN 20 -static int run_count =1 ;static volatile pid_t child_pid =-1 ;static bool null_run = false;static int detailed_run =0 ;
@@ -200,6 +199,7 @@ static struct perf_stat_config stat_config = { .aggr_mode = AGGR_GLOBAL, .scale = true, .unit_width = 4, /* strlen("unit") */ + .run_count = 1, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -686,7 +686,7 @@ static void print_noise(struct perf_stat_config *config, {struct perf_stat_evsel *ps; -if (run_count ==1 ) +if (config->run_count ==1 )return ; ps = evsel->stats;
@@ -1620,8 +1620,8 @@ static void print_header(struct perf_stat_config *config,fprintf (output,"thread id \'%s" , _target->tid);fprintf (output,"\'" ); -if (run_count >1 ) -fprintf (output," (%d runs)" , run_count); +if (config->run_count >1 ) +fprintf (output," (%d runs)" , config->run_count);fprintf (output,":\n\n" ); } }
@@ -1634,7 +1634,8 @@ static int get_precision(double num)return lround (ceil (-log10 (num))); } -static void print_table (FILE *output,int precision,double avg) +static void print_table (struct perf_stat_config *config, +FILE *output,int precision,double avg) {char tmp[64 ];int idx, indent =0 ;
@@ -1645,7 +1646,7 @@ static void print_table(FILE *output, int precision, double avg)fprintf (output,"%*s# Table of individual measurements:\n" , indent,"" ); -for (idx =0 ; idx < run_count; idx++) { +for (idx =0 ; idx < config->run_count; idx++) {double run = (double ) walltime_run[idx] /NSEC_PER_SEC ;int h, n =1 +abs ((int ) (100.0 * (run - avg)/run) /5 );
@@ -1675,7 +1676,7 @@ static void print_footer(struct perf_stat_config *config)if (!null_run)fprintf (output,"\n" ); -if (run_count ==1 ) { +if (config->run_count ==1 ) {fprintf (output," %17.9f seconds time elapsed" , avg);if (ru_display) {
@@ -1695,7 +1696,7 @@ static void print_footer(struct perf_stat_config *config)int precision =get_precision (sd) +2 ;if (walltime_run_table) -print_table (output, precision, avg); +print_table (config, output, precision, avg);fprintf (output," %17.*f +- %.*f seconds time elapsed" , precision, avg, precision, sd);
@@ -1886,7 +1887,7 @@ static const struct option stat_options[] = {OPT_BOOLEAN ('c' ,"scale" , &stat_config.scale,"scale/normalize counters" ),OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose (show counter open errors, etc)" ), -OPT_INTEGER ('r' ,"repeat" , &run_count, +OPT_INTEGER ('r' ,"repeat" , &stat_config.run_count,"repeat command and print average + stddev (max: 100, forever: 0)" ),OPT_BOOLEAN (0 ,"table" , &walltime_run_table, "display details about each run (only with -r option)"),
@@ -2484,7 +2485,7 @@ static int __cmd_record(int argc, const char **argv)if (output_name) data->file.path = output_name; -if (run_count !=1 || forever) { +if (stat_config.run_count !=1 || forever) {pr_err ("Cannot use -r option with perf stat record.\n" );return -1 ; }
@@ -2792,12 +2793,12 @@ int cmd_stat(int argc, const char **argv) goto out; } -if (stat_config.metric_only && run_count >1 ) { +if (stat_config.metric_only && stat_config.run_count >1 ) {fprintf (stderr,"--metric-only is not supported with -r\n" ); goto out; } -if (walltime_run_table && run_count <=1 ) { +if (walltime_run_table && stat_config.run_count <=1 ) {fprintf (stderr,"--table is only supported with -r\n" );parse_options_usage (stat_usage, stat_options,"r" ,1 );parse_options_usage (NULL , stat_options,"table" ,0 );
@@ -2853,20 +2854,20 @@ int cmd_stat(int argc, const char **argv)* Display user/system times only for single * run and when there's specified tracee. */ -if ((run_count ==1 ) &&target__none (&target)) +if ((stat_config.run_count ==1 ) &&target__none (&target)) ru_display = true; -if (run_count <0 ) { +if (stat_config.run_count <0 ) {pr_err ("Run count must be a positive number\n" );parse_options_usage (stat_usage, stat_options,"r" ,1 ); goto out; - }else if (run_count ==0 ) { + }else if (stat_config.run_count ==0 ) { forever = true; - run_count =1 ; + stat_config.run_count =1 ; }if (walltime_run_table) { - walltime_run =zalloc (run_count *sizeof (walltime_run[0 ])); + walltime_run =zalloc (stat_config.run_count *sizeof (walltime_run[0 ]));if (!walltime_run) {pr_err ("failed to setup -r option" ); goto out;
@@ -2994,8 +2995,8 @@ int cmd_stat(int argc, const char **argv)signal (SIGABRT , skip_signal); status =0 ; -for (run_idx =0 ; forever || run_idx < run_count; run_idx++) { -if (run_count !=1 && verbose >0 ) +for (run_idx =0 ; forever || run_idx < stat_config.run_count; run_idx++) { +if (stat_config.run_count !=1 && verbose >0 )fprintf (output,"[ perf stat: executing run #%d ... ]\n" , run_idx +1 );
tools/perf/util/stat.h +1 -0
@@ -100,6 +100,7 @@ struct perf_stat_config {unsigned int initial_delay;unsigned int unit_width;int times; +int run_count;struct runtime_stat *stats;int stats_num;const char *csv_sep;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'run_count' to 'struct perf_stat_config'
perf stat: Move 'run_count' to 'struct perf_stat_config'
Commit-ID: d97ae04b3d5263be242a6a9f9eef6422fc86326a Gitweb: https://git.kernel.org/tip/d97ae04b3d5263be242a6a9f9eef6422fc86326a Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:36 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Move 'run_count' to 'struct perf_stat_config'
Move the static 'run_count' variable to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 39 ++++++++++++++++++++------------------- tools/perf/util/stat.h | 1 + 2 files changed, 21 insertions(+), 19 deletions(-)
tools/perf/builtin-stat.c +20 -19
@@ -147,7 +147,6 @@ typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);#define METRIC_ONLY_LEN 20 -static int run_count =1 ;static volatile pid_t child_pid =-1 ;static bool null_run = false;static int detailed_run =0 ;
@@ -200,6 +199,7 @@ static struct perf_stat_config stat_config = { .aggr_mode = AGGR_GLOBAL, .scale = true, .unit_width = 4, /* strlen("unit") */ + .run_count = 1, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -686,7 +686,7 @@ static void print_noise(struct perf_stat_config *config, {struct perf_stat_evsel *ps; -if (run_count ==1 ) +if (config->run_count ==1 )return ; ps = evsel->stats;
@@ -1620,8 +1620,8 @@ static void print_header(struct perf_stat_config *config,fprintf (output,"thread id \'%s" , _target->tid);fprintf (output,"\'" ); -if (run_count >1 ) -fprintf (output," (%d runs)" , run_count); +if (config->run_count >1 ) +fprintf (output," (%d runs)" , config->run_count);fprintf (output,":\n\n" ); } }
@@ -1634,7 +1634,8 @@ static int get_precision(double num)return lround (ceil (-log10 (num))); } -static void print_table (FILE *output,int precision,double avg) +static void print_table (struct perf_stat_config *config, +FILE *output,int precision,double avg) {char tmp[64 ];int idx, indent =0 ;
@@ -1645,7 +1646,7 @@ static void print_table(FILE *output, int precision, double avg)fprintf (output,"%*s# Table of individual measurements:\n" , indent,"" ); -for (idx =0 ; idx < run_count; idx++) { +for (idx =0 ; idx < config->run_count; idx++) {double run = (double ) walltime_run[idx] /NSEC_PER_SEC ;int h, n =1 +abs ((int ) (100.0 * (run - avg)/run) /5 );
@@ -1675,7 +1676,7 @@ static void print_footer(struct perf_stat_config *config)if (!null_run)fprintf (output,"\n" ); -if (run_count ==1 ) { +if (config->run_count ==1 ) {fprintf (output," %17.9f seconds time elapsed" , avg);if (ru_display) {
@@ -1695,7 +1696,7 @@ static void print_footer(struct perf_stat_config *config)int precision =get_precision (sd) +2 ;if (walltime_run_table) -print_table (output, precision, avg); +print_table (config, output, precision, avg);fprintf (output," %17.*f +- %.*f seconds time elapsed" , precision, avg, precision, sd);
@@ -1886,7 +1887,7 @@ static const struct option stat_options[] = {OPT_BOOLEAN ('c' ,"scale" , &stat_config.scale,"scale/normalize counters" ),OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose (show counter open errors, etc)" ), -OPT_INTEGER ('r' ,"repeat" , &run_count, +OPT_INTEGER ('r' ,"repeat" , &stat_config.run_count,"repeat command and print average + stddev (max: 100, forever: 0)" ),OPT_BOOLEAN (0 ,"table" , &walltime_run_table, "display details about each run (only with -r option)"),
@@ -2484,7 +2485,7 @@ static int __cmd_record(int argc, const char **argv)if (output_name) data->file.path = output_name; -if (run_count !=1 || forever) { +if (stat_config.run_count !=1 || forever) {pr_err ("Cannot use -r option with perf stat record.\n" );return -1 ; }
@@ -2792,12 +2793,12 @@ int cmd_stat(int argc, const char **argv) goto out; } -if (stat_config.metric_only && run_count >1 ) { +if (stat_config.metric_only && stat_config.run_count >1 ) {fprintf (stderr,"--metric-only is not supported with -r\n" ); goto out; } -if (walltime_run_table && run_count <=1 ) { +if (walltime_run_table && stat_config.run_count <=1 ) {fprintf (stderr,"--table is only supported with -r\n" );parse_options_usage (stat_usage, stat_options,"r" ,1 );parse_options_usage (NULL , stat_options,"table" ,0 );
@@ -2853,20 +2854,20 @@ int cmd_stat(int argc, const char **argv)* Display user/system times only for single * run and when there's specified tracee. */ -if ((run_count ==1 ) &&target__none (&target)) +if ((stat_config.run_count ==1 ) &&target__none (&target)) ru_display = true; -if (run_count <0 ) { +if (stat_config.run_count <0 ) {pr_err ("Run count must be a positive number\n" );parse_options_usage (stat_usage, stat_options,"r" ,1 ); goto out; - }else if (run_count ==0 ) { + }else if (stat_config.run_count ==0 ) { forever = true; - run_count =1 ; + stat_config.run_count =1 ; }if (walltime_run_table) { - walltime_run =zalloc (run_count *sizeof (walltime_run[0 ])); + walltime_run =zalloc (stat_config.run_count *sizeof (walltime_run[0 ]));if (!walltime_run) {pr_err ("failed to setup -r option" ); goto out;
@@ -2994,8 +2995,8 @@ int cmd_stat(int argc, const char **argv)signal (SIGABRT , skip_signal); status =0 ; -for (run_idx =0 ; forever || run_idx < run_count; run_idx++) { -if (run_count !=1 && verbose >0 ) +for (run_idx =0 ; forever || run_idx < stat_config.run_count; run_idx++) { +if (stat_config.run_count !=1 && verbose >0 )fprintf (output,"[ perf stat: executing run #%d ... ]\n" , run_idx +1 );
tools/perf/util/stat.h +1 -0
@@ -100,6 +100,7 @@ struct perf_stat_config {unsigned int initial_delay;unsigned int unit_width;int times; +int run_count;struct runtime_stat *stats;int stats_num;const char *csv_sep;
Jiri Olsa
reviewerPATCH 28/43 perf stat: Move metric_only_len into struct perf_stat_config
In reply to Jiri OlsaMoving static metric_only_len into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 10 +++++----- tools/perf/util/stat.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +5 -5
@@ -176,7 +176,6 @@ 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;
@@ -200,6 +199,7 @@ static struct perf_stat_config stat_config = { .scale = true, .unit_width = 4, /* strlen("unit") */ .run_count = 1, + .metric_only_len = METRIC_ONLY_LEN, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -854,14 +854,14 @@ static const char *fixunit(char *buf, struct perf_evsel *evsel,return unit; } -static void print_metric_only (struct perf_stat_config *config__maybe_unused , +static void print_metric_only (struct perf_stat_config *config,void *ctx,const char *color,const char *fmt,const char *unit,double val) {struct outstate *os = ctx;FILE *out = os->fh;char buf[1024 ], str[1024 ]; -unsigned mlen = metric_only_len; +unsigned mlen = config->metric_only_len;if (!valid_only_metric (unit))return ;
@@ -902,7 +902,7 @@ static void new_line_metric(struct perf_stat_config *config __maybe_unused, { } -static void print_metric_header (struct perf_stat_config *config__maybe_unused , +static void print_metric_header (struct perf_stat_config *config,void *ctx,const char *color__maybe_unused ,const char *fmt__maybe_unused ,const char *unit,double val__maybe_unused )
@@ -916,7 +916,7 @@ static void print_metric_header(struct perf_stat_config *config __maybe_unused,if (config->csv_output)fprintf (os->fh,"%s%s" , unit, config->csv_sep);else -fprintf (os->fh,"%*s " , metric_only_len, unit); +fprintf (os->fh,"%*s " , config->metric_only_len, unit); }static int first_shadow_cpu (struct perf_evsel *evsel,int id)
tools/perf/util/stat.h +1 -0
@@ -99,6 +99,7 @@ struct perf_stat_config {unsigned int timeout;unsigned int initial_delay;unsigned int unit_width; +unsigned int metric_only_len;int times;int run_count;struct runtime_stat *stats;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'metric_only_len' to 'struct perf_stat_config'
perf stat: Move 'metric_only_len' to 'struct perf_stat_config'
Commit-ID: ee1760e2cf623bc6834fc3e4e89c6ad030a25dfd Gitweb: https://git.kernel.org/tip/ee1760e2cf623bc6834fc3e4e89c6ad030a25dfd Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:37 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:23 -0300
perf stat: Move 'metric_only_len' to 'struct perf_stat_config'
Move the static 'metric_only_len' variable to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 10 +++++----- tools/perf/util/stat.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-)
tools/perf/builtin-stat.c +5 -5
@@ -176,7 +176,6 @@ 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;
@@ -200,6 +199,7 @@ static struct perf_stat_config stat_config = { .scale = true, .unit_width = 4, /* strlen("unit") */ .run_count = 1, + .metric_only_len = METRIC_ONLY_LEN, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -854,14 +854,14 @@ static const char *fixunit(char *buf, struct perf_evsel *evsel,return unit; } -static void print_metric_only (struct perf_stat_config *config__maybe_unused , +static void print_metric_only (struct perf_stat_config *config,void *ctx,const char *color,const char *fmt,const char *unit,double val) {struct outstate *os = ctx;FILE *out = os->fh;char buf[1024 ], str[1024 ]; -unsigned mlen = metric_only_len; +unsigned mlen = config->metric_only_len;if (!valid_only_metric (unit))return ;
@@ -902,7 +902,7 @@ static void new_line_metric(struct perf_stat_config *config __maybe_unused, { } -static void print_metric_header (struct perf_stat_config *config__maybe_unused , +static void print_metric_header (struct perf_stat_config *config,void *ctx,const char *color__maybe_unused ,const char *fmt__maybe_unused ,const char *unit,double val__maybe_unused )
@@ -916,7 +916,7 @@ static void print_metric_header(struct perf_stat_config *config __maybe_unused,if (config->csv_output)fprintf (os->fh,"%s%s" , unit, config->csv_sep);else -fprintf (os->fh,"%*s " , metric_only_len, unit); +fprintf (os->fh,"%*s " , config->metric_only_len, unit); }static int first_shadow_cpu (struct perf_evsel *evsel,int id)
tools/perf/util/stat.h +1 -0
@@ -99,6 +99,7 @@ struct perf_stat_config {unsigned int timeout;unsigned int initial_delay;unsigned int unit_width; +unsigned int metric_only_len;int times;int run_count;struct runtime_stat *stats;
Jiri Olsa
reviewerPATCH 29/43 perf stat: Pass stat_config to first_shadow_cpu
In reply to Jiri OlsaPassing stat_config to first_shadow_cpu, so the function does not depend on stat command object local stat_config and can be moved out.
--- tools/perf/builtin-stat.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +8 -7
@@ -919,17 +919,18 @@ static void print_metric_header(struct perf_stat_config *config,fprintf (os->fh,"%*s " , config->metric_only_len, unit); } -static int first_shadow_cpu (struct perf_evsel *evsel,int id) +static int first_shadow_cpu (struct perf_stat_config *config, +struct perf_evsel *evsel,int id) {int i;if (!aggr_get_id)return 0 ; -if (stat_config.aggr_mode ==AGGR_NONE ) +if (config->aggr_mode ==AGGR_NONE )return id; -if (stat_config.aggr_mode ==AGGR_GLOBAL ) +if (config->aggr_mode ==AGGR_GLOBAL )return 0 ;for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) {
@@ -1090,7 +1091,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, }perf_stat__print_shadow_stats (config, counter, uval, -first_shadow_cpu (counter, id), +first_shadow_cpu (config, counter, id), &out, &metric_events, st);if (!config->csv_output && !config->metric_only) {print_noise (config, counter, noise);
@@ -1098,7 +1099,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, } } -static void aggr_update_shadow (void ) +static void aggr_update_shadow (struct perf_stat_config *config) {int cpu, s2, id, s;u64 val;
@@ -1115,7 +1116,7 @@ static void aggr_update_shadow(void) val +=perf_counts (counter->counts, cpu,0 )->val; }perf_stat__update_shadow_stats (counter, val, -first_shadow_cpu (counter, id), +first_shadow_cpu (config, counter, id), &rt_stat); } }
@@ -1237,7 +1238,7 @@ static void print_aggr(struct perf_stat_config *config,if (!(aggr_map || aggr_get_id))return ; -aggr_update_shadow (); +aggr_update_shadow (config);/* * With metric_only everything is on a single line.
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Pass 'struct perf_stat_config' to first_shadow_cpu()
perf stat: Pass 'struct perf_stat_config' to first_shadow_cpu()
Commit-ID: ae2d7da554f0dda837b6639d247665f6df90e41f Gitweb: https://git.kernel.org/tip/ae2d7da554f0dda837b6639d247665f6df90e41f Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:38 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Pass 'struct perf_stat_config' to first_shadow_cpu()
Pass a 'struct perf_stat_config' arg to first_shadow_cpu(), so that the function does not depend on the 'perf stat' command object local 'stat_config' variable and can then be moved out.
--- tools/perf/builtin-stat.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +8 -7
@@ -919,17 +919,18 @@ static void print_metric_header(struct perf_stat_config *config,fprintf (os->fh,"%*s " , config->metric_only_len, unit); } -static int first_shadow_cpu (struct perf_evsel *evsel,int id) +static int first_shadow_cpu (struct perf_stat_config *config, +struct perf_evsel *evsel,int id) {int i;if (!aggr_get_id)return 0 ; -if (stat_config.aggr_mode ==AGGR_NONE ) +if (config->aggr_mode ==AGGR_NONE )return id; -if (stat_config.aggr_mode ==AGGR_GLOBAL ) +if (config->aggr_mode ==AGGR_GLOBAL )return 0 ;for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) {
@@ -1090,7 +1091,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, }perf_stat__print_shadow_stats (config, counter, uval, -first_shadow_cpu (counter, id), +first_shadow_cpu (config, counter, id), &out, &metric_events, st);if (!config->csv_output && !config->metric_only) {print_noise (config, counter, noise);
@@ -1098,7 +1099,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, } } -static void aggr_update_shadow (void ) +static void aggr_update_shadow (struct perf_stat_config *config) {int cpu, s2, id, s;u64 val;
@@ -1115,7 +1116,7 @@ static void aggr_update_shadow(void) val +=perf_counts (counter->counts, cpu,0 )->val; }perf_stat__update_shadow_stats (counter, val, -first_shadow_cpu (counter, id), +first_shadow_cpu (config, counter, id), &rt_stat); } }
@@ -1237,7 +1238,7 @@ static void print_aggr(struct perf_stat_config *config,if (!(aggr_map || aggr_get_id))return ; -aggr_update_shadow (); +aggr_update_shadow (config);/* * With metric_only everything is on a single line.
Jiri Olsa
reviewerPATCH 30/43 perf stat: Pass evlist to aggr_update_shadow
In reply to Jiri OlsaPassing evlist to aggr_update_shadow,
to rid of the evsel_list dependency.
--- tools/perf/builtin-stat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +4 -3
@@ -1099,7 +1099,8 @@ static void printout(struct perf_stat_config *config, int id, int nr, } } -static void aggr_update_shadow (struct perf_stat_config *config) +static void aggr_update_shadow (struct perf_stat_config *config, +struct perf_evlist *evlist) {int cpu, s2, id, s;u64 val;
@@ -1107,7 +1108,7 @@ static void aggr_update_shadow(struct perf_stat_config *config)for (s =0 ; s < aggr_map->nr; s++) { id = aggr_map->map[s]; -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) { val =0 ;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { s2 =aggr_get_id (evsel_list->cpus, cpu);
@@ -1238,7 +1239,7 @@ static void print_aggr(struct perf_stat_config *config,if (!(aggr_map || aggr_get_id))return ; -aggr_update_shadow (config); +aggr_update_shadow (config, evlist);/* * With metric_only everything is on a single line.
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Pass 'evlist' to aggr_update_shadow()
perf stat: Pass 'evlist' to aggr_update_shadow()
Commit-ID: 77e0faf8552c9329d58a4de460928e03252647c6 Gitweb: https://git.kernel.org/tip/77e0faf8552c9329d58a4de460928e03252647c6 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:39 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Pass 'evlist' to aggr_update_shadow()
Pass a 'evlist' argument to aggr_update_shadow(), to get rid of the global 'evsel_list' variable dependency.
--- tools/perf/builtin-stat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +4 -3
@@ -1099,7 +1099,8 @@ static void printout(struct perf_stat_config *config, int id, int nr, } } -static void aggr_update_shadow (struct perf_stat_config *config) +static void aggr_update_shadow (struct perf_stat_config *config, +struct perf_evlist *evlist) {int cpu, s2, id, s;u64 val;
@@ -1107,7 +1108,7 @@ static void aggr_update_shadow(struct perf_stat_config *config)for (s =0 ; s < aggr_map->nr; s++) { id = aggr_map->map[s]; -evlist__for_each_entry (evsel_list, counter) { +evlist__for_each_entry (evlist, counter) { val =0 ;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { s2 =aggr_get_id (evsel_list->cpus, cpu);
@@ -1238,7 +1239,7 @@ static void print_aggr(struct perf_stat_config *config,if (!(aggr_map || aggr_get_id))return ; -aggr_update_shadow (config); +aggr_update_shadow (config, evlist);/* * With metric_only everything is on a single line.
Jiri Olsa
reviewerPATCH 31/43 perf stat: Add walltime_nsecs_stats pointer into struct perf_stat_config
In reply to Jiri OlsaAdding walltime_nsecs_stats pointer into struct perf_stat_config, so it can be passed around and used outside stat command.
It's initialized to point to stat's walltime_nsecs_stats value.
--- tools/perf/builtin-stat.c | 15 ++++++++------- tools/perf/util/stat.h | 1 + 2 files changed, 9 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +8 -7
@@ -195,11 +195,12 @@ static struct perf_stat perf_stat;static volatile int done =0 ;static struct perf_stat_config stat_config = { - .aggr_mode =AGGR_GLOBAL , - .scale = true, - .unit_width =4 ,/* strlen("unit") */ - .run_count =1 , - .metric_only_len =METRIC_ONLY_LEN , + .aggr_mode =AGGR_GLOBAL , + .scale = true, + .unit_width =4 ,/* strlen("unit") */ + .run_count =1 , + .metric_only_len =METRIC_ONLY_LEN , + .walltime_nsecs_stats = &walltime_nsecs_stats, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -1671,7 +1672,7 @@ static double timeval2double(struct timeval *t)static void print_footer (struct perf_stat_config *config) { -double avg =avg_stats (&walltime_nsecs_stats) /NSEC_PER_SEC ; +double avg =avg_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ;FILE *output = config->output;int n;
@@ -1690,7 +1691,7 @@ static void print_footer(struct perf_stat_config *config)fprintf (output," %17.9f seconds sys\n" , ru_stime); } }else { -double sd =stddev_stats (&walltime_nsecs_stats) /NSEC_PER_SEC ; +double sd =stddev_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ;/* * Display at most 2 more significant * digits than the stddev inaccuracy.
tools/perf/util/stat.h +1 -0
@@ -105,6 +105,7 @@ struct perf_stat_config {struct runtime_stat *stats;int stats_num;const char *csv_sep; +struct stats *walltime_nsecs_stats; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Add 'walltime_nsecs_stats' pointer to 'struct perf_stat_config'
perf stat: Add 'walltime_nsecs_stats' pointer to 'struct perf_stat_config'
Commit-ID: 26893a6018f88779c0aded934e99e0ebb6859a58 Gitweb: https://git.kernel.org/tip/26893a6018f88779c0aded934e99e0ebb6859a58 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:40 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Add 'walltime_nsecs_stats' pointer to 'struct perf_stat_config'
Add 'walltime_nsecs_stats' pointer to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
It's initialized to point to stat's walltime_nsecs_stats value.
--- tools/perf/builtin-stat.c | 15 ++++++++------- tools/perf/util/stat.h | 1 + 2 files changed, 9 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +8 -7
@@ -195,11 +195,12 @@ static struct perf_stat perf_stat;static volatile int done =0 ;static struct perf_stat_config stat_config = { - .aggr_mode =AGGR_GLOBAL , - .scale = true, - .unit_width =4 ,/* strlen("unit") */ - .run_count =1 , - .metric_only_len =METRIC_ONLY_LEN , + .aggr_mode =AGGR_GLOBAL , + .scale = true, + .unit_width =4 ,/* strlen("unit") */ + .run_count =1 , + .metric_only_len =METRIC_ONLY_LEN , + .walltime_nsecs_stats = &walltime_nsecs_stats, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -1671,7 +1672,7 @@ static double timeval2double(struct timeval *t)static void print_footer (struct perf_stat_config *config) { -double avg =avg_stats (&walltime_nsecs_stats) /NSEC_PER_SEC ; +double avg =avg_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ;FILE *output = config->output;int n;
@@ -1690,7 +1691,7 @@ static void print_footer(struct perf_stat_config *config)fprintf (output," %17.9f seconds sys\n" , ru_stime); } }else { -double sd =stddev_stats (&walltime_nsecs_stats) /NSEC_PER_SEC ; +double sd =stddev_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ;/* * Display at most 2 more significant * digits than the stddev inaccuracy.
tools/perf/util/stat.h +1 -0
@@ -105,6 +105,7 @@ struct perf_stat_config {struct runtime_stat *stats;int stats_num;const char *csv_sep; +struct stats *walltime_nsecs_stats; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 32/43 perf stat: Move null_run into struct perf_stat_config
In reply to Jiri OlsaMove static null_run into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 7 +++---- tools/perf/util/stat.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +3 -4
@@ -148,7 +148,6 @@ typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);#define METRIC_ONLY_LEN 20static volatile pid_t child_pid =-1 ; -static bool null_run = false;static int detailed_run =0 ;static bool transaction_run;static bool topdown_run = false;
@@ -1676,7 +1675,7 @@ static void print_footer(struct perf_stat_config *config)FILE *output = config->output;int n; -if (!null_run) +if (!config->null_run)fprintf (output,"\n" );if (config->run_count ==1 ) {
@@ -1894,7 +1893,7 @@ static const struct option stat_options[] = { "repeat command and print average + stddev (max: 100, forever: 0)"),OPT_BOOLEAN (0 ,"table" , &walltime_run_table,"display details about each run (only with -r option)" ), -OPT_BOOLEAN ('n' ,"null" , &null_run, +OPT_BOOLEAN ('n' ,"null" , &stat_config.null_run,"null run - dont start any counters" ),OPT_INCR ('d' ,"detailed" , &detailed_run, "detailed run - start a lot of events"),
@@ -2309,7 +2308,7 @@ static int add_default_attributes(void)struct parse_events_error errinfo;/* Set attrs if no event is selected and !null_run: */ -if (null_run) +if (stat_config.null_run)return 0 ;if (transaction_run) {
tools/perf/util/stat.h +1 -0
@@ -94,6 +94,7 @@ struct perf_stat_config {bool csv_output;bool interval_clear;bool metric_only; +bool null_run;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'null_run' to 'struct perf_stat_config'
perf stat: Move 'null_run' to 'struct perf_stat_config'
Commit-ID: aea0dca1629c72128cf7174d1d3f3807f7297005 Gitweb: https://git.kernel.org/tip/aea0dca1629c72128cf7174d1d3f3807f7297005 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:41 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move 'null_run' to 'struct perf_stat_config'
Move the static 'null_run' variable to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 7 +++---- tools/perf/util/stat.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +3 -4
@@ -148,7 +148,6 @@ typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);#define METRIC_ONLY_LEN 20static volatile pid_t child_pid =-1 ; -static bool null_run = false;static int detailed_run =0 ;static bool transaction_run;static bool topdown_run = false;
@@ -1676,7 +1675,7 @@ static void print_footer(struct perf_stat_config *config)FILE *output = config->output;int n; -if (!null_run) +if (!config->null_run)fprintf (output,"\n" );if (config->run_count ==1 ) {
@@ -1894,7 +1893,7 @@ static const struct option stat_options[] = { "repeat command and print average + stddev (max: 100, forever: 0)"),OPT_BOOLEAN (0 ,"table" , &walltime_run_table,"display details about each run (only with -r option)" ), -OPT_BOOLEAN ('n' ,"null" , &null_run, +OPT_BOOLEAN ('n' ,"null" , &stat_config.null_run,"null run - dont start any counters" ),OPT_INCR ('d' ,"detailed" , &detailed_run, "detailed run - start a lot of events"),
@@ -2309,7 +2308,7 @@ static int add_default_attributes(void)struct parse_events_error errinfo;/* Set attrs if no event is selected and !null_run: */ -if (null_run) +if (stat_config.null_run)return 0 ;if (transaction_run) {
tools/perf/util/stat.h +1 -0
@@ -94,6 +94,7 @@ struct perf_stat_config {bool csv_output;bool interval_clear;bool metric_only; +bool null_run;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 33/43 perf stat: Move print_free_counters_hint into struct perf_stat_config
In reply to Jiri OlsaMoving print_free_counters_hint into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -170,7 +170,6 @@ static bool append_file;static bool interval_count;static const char *output_name;static int output_fd; -static int print_free_counters_hint;static int print_mixed_hw_group_error;static u64 *walltime_run;static bool ru_display = false;
@@ -1051,7 +1050,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, config->csv_sep);if (counter->supported) { - print_free_counters_hint =1 ; + config->print_free_counters_hint =1 ;if (is_mixed_hw_group (counter)) print_mixed_hw_group_error =1 ; }
@@ -1707,7 +1706,7 @@ static void print_footer(struct perf_stat_config *config) }fprintf (output,"\n\n" ); -if (print_free_counters_hint && +if (config->print_free_counters_hint &&sysctl__read_int ("kernel/nmi_watchdog" , &n) >=0 && n >0 ) fprintf(output,
tools/perf/util/stat.h +1 -0
@@ -103,6 +103,7 @@ struct perf_stat_config {unsigned int metric_only_len;int times;int run_count; +int print_free_counters_hint;struct runtime_stat *stats;int stats_num;const char *csv_sep;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'print_free_counters_hint' to 'struct perf_stat_config'
perf stat: Move 'print_free_counters_hint' to 'struct perf_stat_config'
Commit-ID: 31084123c1962dd4235655c1839a50c9cf6c709b Gitweb: https://git.kernel.org/tip/31084123c1962dd4235655c1839a50c9cf6c709b Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:42 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move 'print_free_counters_hint' to 'struct perf_stat_config'
Move the 'print_free_counters_hint' variable to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -170,7 +170,6 @@ static bool append_file;static bool interval_count;static const char *output_name;static int output_fd; -static int print_free_counters_hint;static int print_mixed_hw_group_error;static u64 *walltime_run;static bool ru_display = false;
@@ -1051,7 +1050,7 @@ static void printout(struct perf_stat_config *config, int id, int nr, config->csv_sep);if (counter->supported) { - print_free_counters_hint =1 ; + config->print_free_counters_hint =1 ;if (is_mixed_hw_group (counter)) print_mixed_hw_group_error =1 ; }
@@ -1707,7 +1706,7 @@ static void print_footer(struct perf_stat_config *config) }fprintf (output,"\n\n" ); -if (print_free_counters_hint && +if (config->print_free_counters_hint &&sysctl__read_int ("kernel/nmi_watchdog" , &n) >=0 && n >0 ) fprintf(output,
tools/perf/util/stat.h +1 -0
@@ -103,6 +103,7 @@ struct perf_stat_config {unsigned int metric_only_len;int times;int run_count; +int print_free_counters_hint;struct runtime_stat *stats;int stats_num;const char *csv_sep;
Jiri Olsa
reviewerPATCH 34/43 perf stat: Move print_mixed_hw_group_error into struct perf_stat_config
In reply to Jiri OlsaMoving print_mixed_hw_group_error into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -170,7 +170,6 @@ static bool append_file;static bool interval_count;static const char *output_name;static int output_fd; -static int print_mixed_hw_group_error;static u64 *walltime_run;static bool ru_display = false;static struct rusage ru_data;
@@ -1052,7 +1051,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,if (counter->supported) { config->print_free_counters_hint =1 ;if (is_mixed_hw_group (counter)) - print_mixed_hw_group_error =1 ; + config->print_mixed_hw_group_error =1 ; } fprintf(config->output, "%-*s%s",
@@ -1715,7 +1714,7 @@ static void print_footer(struct perf_stat_config *config)" perf stat ...\n" " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); -if (print_mixed_hw_group_error) +if (config->print_mixed_hw_group_error)fprintf (output,"The events in group usually have to be from " "the same PMU. Try reorganizing the group.\n" );
tools/perf/util/stat.h +1 -0
@@ -104,6 +104,7 @@ struct perf_stat_config {int times;int run_count;int print_free_counters_hint; +int print_mixed_hw_group_error;struct runtime_stat *stats;int stats_num;const char *csv_sep;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'print_mixed_hw_group_error' to 'struct perf_stat_config'
perf stat: Move 'print_mixed_hw_group_error' to 'struct perf_stat_config'
Commit-ID: 3b3cd9a41c2b5d97309099ba6eae69b2d3177226 Gitweb: https://git.kernel.org/tip/3b3cd9a41c2b5d97309099ba6eae69b2d3177226 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:43 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move 'print_mixed_hw_group_error' to 'struct perf_stat_config'
Move the 'print_mixed_hw_group_error' global variable to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -170,7 +170,6 @@ static bool append_file;static bool interval_count;static const char *output_name;static int output_fd; -static int print_mixed_hw_group_error;static u64 *walltime_run;static bool ru_display = false;static struct rusage ru_data;
@@ -1052,7 +1051,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,if (counter->supported) { config->print_free_counters_hint =1 ;if (is_mixed_hw_group (counter)) - print_mixed_hw_group_error =1 ; + config->print_mixed_hw_group_error =1 ; } fprintf(config->output, "%-*s%s",
@@ -1715,7 +1714,7 @@ static void print_footer(struct perf_stat_config *config)" perf stat ...\n" " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); -if (print_mixed_hw_group_error) +if (config->print_mixed_hw_group_error)fprintf (output,"The events in group usually have to be from " "the same PMU. Try reorganizing the group.\n" );
tools/perf/util/stat.h +1 -0
@@ -104,6 +104,7 @@ struct perf_stat_config {int times;int run_count;int print_free_counters_hint; +int print_mixed_hw_group_error;struct runtime_stat *stats;int stats_num;const char *csv_sep;
Jiri Olsa
reviewerPATCH 35/43 perf stat: Move ru_* data into struct perf_stat_config
In reply to Jiri OlsaMoving ru_* data into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 12 +++++------- tools/perf/util/stat.h | 6 ++++++ 2 files changed, 11 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +5 -7
@@ -171,8 +171,6 @@ static bool interval_count;static const char *output_name;static int output_fd;static u64 *walltime_run; -static bool ru_display = false; -static struct rusage ru_data;struct perf_stat {bool record;
@@ -583,7 +581,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)break ; } } -wait4 (child_pid, &status,0 , &ru_data); +wait4 (child_pid, &status,0 , &stat_config.ru_data);if (workload_exec_errno) {const char *emsg =str_error_r (workload_exec_errno, msg,sizeof (msg));
@@ -1679,9 +1677,9 @@ static void print_footer(struct perf_stat_config *config)if (config->run_count ==1 ) {fprintf (output," %17.9f seconds time elapsed" , avg); -if (ru_display) { -double ru_utime =timeval2double (&ru_data.ru_utime); -double ru_stime =timeval2double (&ru_data.ru_stime); +if (config->ru_display) { +double ru_utime =timeval2double (&config->ru_data.ru_utime); +double ru_stime =timeval2double (&config->ru_data.ru_stime);fprintf (output,"\n\n" );fprintf (output," %17.9f seconds user\n" , ru_utime);
@@ -2855,7 +2853,7 @@ int cmd_stat(int argc, const char **argv)* run and when there's specified tracee. */ if ((stat_config.run_count ==1 ) &&target__none (&target)) - ru_display = true; + stat_config.ru_display = true;if (stat_config.run_count <0 ) {pr_err ("Run count must be a positive number\n" );
tools/perf/util/stat.h +6 -0
@@ -4,6 +4,10 @@#include <linux/types.h> #include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> #include "xyarray.h" #include "rblist.h" #include "perf.h"
@@ -95,6 +99,7 @@ struct perf_stat_config {bool interval_clear;bool metric_only;bool null_run; +bool ru_display;FILE *output;unsigned int interval;unsigned int timeout;
@@ -109,6 +114,7 @@ struct perf_stat_config {int stats_num;const char *csv_sep;struct stats *walltime_nsecs_stats; +struct rusage ru_data; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move ru_* data to 'struct perf_stat_config'
perf stat: Move ru_* data to 'struct perf_stat_config'
Commit-ID: 8897a8916efb29fa8bbe9e5f6e5d56362aedf64e Gitweb: https://git.kernel.org/tip/8897a8916efb29fa8bbe9e5f6e5d56362aedf64e Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:44 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move ru_* data to 'struct perf_stat_config'
Move the 'ru_*' global variables to 'struct perf_stat_config', so that it can be passed around and used outside the 'perf stat' command.
--- tools/perf/builtin-stat.c | 12 +++++------- tools/perf/util/stat.h | 6 ++++++ 2 files changed, 11 insertions(+), 7 deletions(-)
tools/perf/builtin-stat.c +5 -7
@@ -171,8 +171,6 @@ static bool interval_count;static const char *output_name;static int output_fd;static u64 *walltime_run; -static bool ru_display = false; -static struct rusage ru_data;struct perf_stat {bool record;
@@ -583,7 +581,7 @@ try_again:break ; } } -wait4 (child_pid, &status,0 , &ru_data); +wait4 (child_pid, &status,0 , &stat_config.ru_data);if (workload_exec_errno) {const char *emsg =str_error_r (workload_exec_errno, msg,sizeof (msg));
@@ -1679,9 +1677,9 @@ static void print_footer(struct perf_stat_config *config)if (config->run_count ==1 ) {fprintf (output," %17.9f seconds time elapsed" , avg); -if (ru_display) { -double ru_utime =timeval2double (&ru_data.ru_utime); -double ru_stime =timeval2double (&ru_data.ru_stime); +if (config->ru_display) { +double ru_utime =timeval2double (&config->ru_data.ru_utime); +double ru_stime =timeval2double (&config->ru_data.ru_stime);fprintf (output,"\n\n" );fprintf (output," %17.9f seconds user\n" , ru_utime);
@@ -2855,7 +2853,7 @@ int cmd_stat(int argc, const char **argv)* run and when there's specified tracee. */ if ((stat_config.run_count ==1 ) &&target__none (&target)) - ru_display = true; + stat_config.ru_display = true;if (stat_config.run_count <0 ) {pr_err ("Run count must be a positive number\n" );
tools/perf/util/stat.h +6 -0
@@ -4,6 +4,10 @@#include <linux/types.h> #include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> #include "xyarray.h" #include "rblist.h" #include "perf.h"
@@ -95,6 +99,7 @@ struct perf_stat_config {bool interval_clear;bool metric_only;bool null_run; +bool ru_display;FILE *output;unsigned int interval;unsigned int timeout;
@@ -109,6 +114,7 @@ struct perf_stat_config {int stats_num;const char *csv_sep;struct stats *walltime_nsecs_stats; +struct rusage ru_data; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 36/43 perf stat: Move *_aggr_* data into struct perf_stat_config
In reply to Jiri OlsaMoving *_aggr_* data into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 112 ++++++++++++++++++++------------------ tools/perf/util/stat.h | 6 ++ 2 files changed, 64 insertions(+), 54 deletions(-)
tools/perf/builtin-stat.c +58 -54
@@ -143,8 +143,6 @@ static struct target target = { .uid = UINT_MAX, }; -typedef int (*aggr_get_id_t )(struct cpu_map *m,int cpu); -#define METRIC_ONLY_LEN 20static volatile pid_t child_pid =-1 ;
@@ -164,8 +162,6 @@ static bool force_metric_only = false;static bool no_merge = false;static bool walltime_run_table = false;static struct timespec ref_time; -static struct cpu_map *aggr_map; -static aggr_get_id_t aggr_get_id;static bool append_file;static bool interval_count;static const char *output_name;
@@ -920,7 +916,7 @@ static int first_shadow_cpu(struct perf_stat_config *config, {int i; -if (!aggr_get_id) +if (!config->aggr_get_id)return 0 ;if (config->aggr_mode ==AGGR_NONE )
@@ -932,7 +928,7 @@ static int first_shadow_cpu(struct perf_stat_config *config,for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) {int cpu2 =perf_evsel__cpus (evsel)->map[i]; -if (aggr_get_id (evsel_list->cpus, cpu2) == id) +if (config->aggr_get_id (config, evsel_list->cpus, cpu2) == id)return cpu2; }return 0 ;
@@ -1102,12 +1098,12 @@ static void aggr_update_shadow(struct perf_stat_config *config,u64 val;struct perf_evsel *counter; -for (s =0 ; s < aggr_map->nr; s++) { - id = aggr_map->map[s]; +for (s =0 ; s < config->aggr_map->nr; s++) { + id = config->aggr_map->map[s];evlist__for_each_entry (evlist, counter) { val =0 ;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - s2 =aggr_get_id (evsel_list->cpus, cpu); + s2 = config->aggr_get_id (config, evsel_list->cpus, cpu);if (s2 != id)continue ; val +=perf_counts (counter->counts, cpu,0 )->val;
@@ -1147,8 +1143,8 @@ static void uniquify_event_name(struct perf_evsel *counter) counter->uniquified_name = true; } -static void collect_all_aliases (struct perf_evsel *counter, -void (*cb)(struct perf_evsel *counter,void *data, +static void collect_all_aliases (struct perf_stat_config *config,struct perf_evsel *counter, +void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data,bool first),void *data) {
@@ -1164,22 +1160,22 @@ static void collect_all_aliases(struct perf_evsel *counter, perf_evsel__is_clock(alias) != perf_evsel__is_clock(counter)) break; alias->merged_stat = true; -cb (alias, data, false); +cb (config, alias, data, false); } } -static bool collect_data (struct perf_evsel *counter, -void (*cb)(struct perf_evsel *counter,void *data, +static bool collect_data (struct perf_stat_config *config,struct perf_evsel *counter, +void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data,bool first),void *data) {if (counter->merged_stat)return false; -cb (counter, data, true); +cb (config, counter, data, true);if (no_merge)uniquify_event_name (counter);else if (counter->auto_merge_stats) -collect_all_aliases (counter, cb, data); +collect_all_aliases (config, counter, cb, data);return true; }
@@ -1190,7 +1186,8 @@ struct aggr_data {int cpu; }; -static void aggr_cb (struct perf_evsel *counter,void *data,bool first) +static void aggr_cb (struct perf_stat_config *config, +struct perf_evsel *counter,void *data,bool first) {struct aggr_data *ad = data;int cpu, s2;
@@ -1198,7 +1195,7 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first)for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) {struct perf_counts_values *counts; - s2 =aggr_get_id (perf_evsel__cpus (counter), cpu); + s2 = config->aggr_get_id (config,perf_evsel__cpus (counter), cpu);if (s2 != ad->id)continue ;if (first)
@@ -1232,7 +1229,7 @@ static void print_aggr(struct perf_stat_config *config,u64 ena, run, val;bool first; -if (!(aggr_map || aggr_get_id)) +if (!(config->aggr_map || config->aggr_get_id))return ;aggr_update_shadow (config, evlist);
@@ -1241,12 +1238,12 @@ static void print_aggr(struct perf_stat_config *config,* With metric_only everything is on a single line. * Without each counter has its own line. */ -for (s =0 ; s < aggr_map->nr; s++) { +for (s =0 ; s < config->aggr_map->nr; s++) {struct aggr_data ad;if (prefix && metric_only)fprintf (output,"%s" , prefix); - ad.id = id = aggr_map->map[s]; + ad.id = id = config->aggr_map->map[s]; first = true;evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))
@@ -1254,7 +1251,7 @@ static void print_aggr(struct perf_stat_config *config, ad.val = ad.ena = ad.run =0 ; ad.nr =0 ; -if (!collect_data (counter, aggr_cb, &ad)) +if (!collect_data (config, counter, aggr_cb, &ad))continue ; nr = ad.nr; ena = ad.ena;
@@ -1370,7 +1367,8 @@ struct caggr_data {double avg, avg_enabled, avg_running; }; -static void counter_aggr_cb (struct perf_evsel *counter,void *data, +static void counter_aggr_cb (struct perf_stat_config *config__maybe_unused , +struct perf_evsel *counter,void *data,bool first__maybe_unused ) {struct caggr_data *cd = data;
@@ -1393,7 +1391,7 @@ static void print_counter_aggr(struct perf_stat_config *config,double uval;struct caggr_data cd = { .avg =0.0 }; -if (!collect_data (counter, counter_aggr_cb, &cd)) +if (!collect_data (config, counter, counter_aggr_cb, &cd))return ;if (prefix && !metric_only)
@@ -1406,7 +1404,8 @@ static void print_counter_aggr(struct perf_stat_config *config,fprintf (output,"\n" ); } -static void counter_cb (struct perf_evsel *counter,void *data, +static void counter_cb (struct perf_stat_config *config__maybe_unused , +struct perf_evsel *counter,void *data,bool first__maybe_unused ) {struct aggr_data *ad = data;
@@ -1431,7 +1430,7 @@ static void print_counter(struct perf_stat_config *config,for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) {struct aggr_data ad = { .cpu = cpu }; -if (!collect_data (counter, counter_cb, &ad)) +if (!collect_data (config, counter, counter_cb, &ad))return ; val = ad.val; ena = ad.ena;
@@ -1944,12 +1943,14 @@ static const struct option stat_options[] = { OPT_END() }; -static int perf_stat__get_socket (struct cpu_map *map,int cpu) +static int perf_stat__get_socket (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int cpu) {return cpu_map__get_socket (map, cpu,NULL ); } -static int perf_stat__get_core (struct cpu_map *map,int cpu) +static int perf_stat__get_core (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int cpu) {return cpu_map__get_core (map, cpu,NULL ); }
@@ -1966,9 +1967,8 @@ static int cpu_map__get_max(struct cpu_map *map)return max; } -static struct cpu_map *cpus_aggr_map; - -static int perf_stat__get_aggr (aggr_get_id_t get_id,struct cpu_map *map,int idx) +static int perf_stat__get_aggr (struct perf_stat_config *config, +aggr_get_id_t get_id,struct cpu_map *map,int idx) {int cpu;
@@ -1977,20 +1977,22 @@ static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int id cpu = map->map[idx]; -if (cpus_aggr_map->map[cpu] ==-1 ) - cpus_aggr_map->map[cpu] =get_id (map, idx); +if (config->cpus_aggr_map->map[cpu] ==-1 ) + config->cpus_aggr_map->map[cpu] =get_id (config, map, idx); -return cpus_aggr_map->map[cpu]; +return config->cpus_aggr_map->map[cpu]; } -static int perf_stat__get_socket_cached (struct cpu_map *map,int idx) +static int perf_stat__get_socket_cached (struct perf_stat_config *config, +struct cpu_map *map,int idx) { -return perf_stat__get_aggr (perf_stat__get_socket, map, idx); +return perf_stat__get_aggr (config, perf_stat__get_socket, map, idx); } -static int perf_stat__get_core_cached (struct cpu_map *map,int idx) +static int perf_stat__get_core_cached (struct perf_stat_config *config, +struct cpu_map *map,int idx) { -return perf_stat__get_aggr (perf_stat__get_core, map, idx); +return perf_stat__get_aggr (config, perf_stat__get_core, map, idx); }static int perf_stat_init_aggr_mode (void )
@@ -1999,18 +2001,18 @@ static int perf_stat_init_aggr_mode(void)switch (stat_config.aggr_mode) {case AGGR_SOCKET : -if (cpu_map__build_socket_map (evsel_list->cpus, &aggr_map)) { +if (cpu_map__build_socket_map (evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build socket map" );return -1 ; } - aggr_get_id = perf_stat__get_socket_cached; + stat_config.aggr_get_id = perf_stat__get_socket_cached;break ;case AGGR_CORE : -if (cpu_map__build_core_map (evsel_list->cpus, &aggr_map)) { +if (cpu_map__build_core_map (evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = perf_stat__get_core_cached; + stat_config.aggr_get_id = perf_stat__get_core_cached;break ;case AGGR_NONE :case AGGR_GLOBAL :
@@ -2026,16 +2028,16 @@ static int perf_stat_init_aggr_mode(void)* the aggregation translate cpumap. */ nr =cpu_map__get_max (evsel_list->cpus); - cpus_aggr_map =cpu_map__empty_new (nr +1 ); -return cpus_aggr_map ?0 : -ENOMEM ; + stat_config.cpus_aggr_map =cpu_map__empty_new (nr +1 ); +return stat_config.cpus_aggr_map ?0 : -ENOMEM ; }static void perf_stat__exit_aggr_mode (void ) { -cpu_map__put (aggr_map); -cpu_map__put (cpus_aggr_map); - aggr_map =NULL ; - cpus_aggr_map =NULL ; +cpu_map__put (stat_config.aggr_map); +cpu_map__put (stat_config.cpus_aggr_map); + stat_config.aggr_map =NULL ; + stat_config.cpus_aggr_map =NULL ; }static inline int perf_env__get_cpu (struct perf_env *env,struct cpu_map *map,int idx)
@@ -2093,12 +2095,14 @@ static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus,return cpu_map__build_map (cpus, corep, perf_env__get_core, env); } -static int perf_stat__get_socket_file (struct cpu_map *map,int idx) +static int perf_stat__get_socket_file (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int idx) {return perf_env__get_socket (map, idx, &perf_stat.session->header.env); } -static int perf_stat__get_core_file (struct cpu_map *map,int idx) +static int perf_stat__get_core_file (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int idx) {return perf_env__get_core (map, idx, &perf_stat.session->header.env); }
@@ -2109,18 +2113,18 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st)switch (stat_config.aggr_mode) {case AGGR_SOCKET : -if (perf_env__build_socket_map (env, evsel_list->cpus, &aggr_map)) { +if (perf_env__build_socket_map (env, evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build socket map" );return -1 ; } - aggr_get_id = perf_stat__get_socket_file; + stat_config.aggr_get_id = perf_stat__get_socket_file;break ;case AGGR_CORE : -if (perf_env__build_core_map (env, evsel_list->cpus, &aggr_map)) { +if (perf_env__build_core_map (env, evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = perf_stat__get_core_file; + stat_config.aggr_get_id = perf_stat__get_core_file;break ;case AGGR_NONE :case AGGR_GLOBAL :
tools/perf/util/stat.h +6 -0
@@ -90,6 +90,9 @@ struct runtime_stat {struct rblist value_list; }; +typedef int (*aggr_get_id_t )(struct perf_stat_config *config, +struct cpu_map *m,int cpu); +struct perf_stat_config {enum aggr_mode aggr_mode;bool scale;
@@ -115,6 +118,9 @@ struct perf_stat_config {const char *csv_sep;struct stats *walltime_nsecs_stats;struct rusage ru_data; +struct cpu_map *aggr_map; +aggr_get_id_t aggr_get_id; +struct cpu_map *cpus_aggr_map; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move *_aggr_* data to 'struct perf_stat_config'
perf stat: Move *_aggr_* data to 'struct perf_stat_config'
Commit-ID: 6f6b6594b5f380b0a972b66b275caa6c54bb1fea Gitweb: https://git.kernel.org/tip/6f6b6594b5f380b0a972b66b275caa6c54bb1fea Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:45 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move *_aggr_* data to 'struct perf_stat_config'
Move the *_aggr_* global variables to 'struct perf_stat_config', so that it can be passed around and used outside 'perf stat' command.
--- tools/perf/builtin-stat.c | 112 ++++++++++++++++++++++++---------------------- tools/perf/util/stat.h | 6 +++ 2 files changed, 64 insertions(+), 54 deletions(-)
tools/perf/builtin-stat.c +58 -54
@@ -143,8 +143,6 @@ static struct target target = { .uid = UINT_MAX, }; -typedef int (*aggr_get_id_t )(struct cpu_map *m,int cpu); -#define METRIC_ONLY_LEN 20static volatile pid_t child_pid =-1 ;
@@ -164,8 +162,6 @@ static bool force_metric_only = false;static bool no_merge = false;static bool walltime_run_table = false;static struct timespec ref_time; -static struct cpu_map *aggr_map; -static aggr_get_id_t aggr_get_id;static bool append_file;static bool interval_count;static const char *output_name;
@@ -920,7 +916,7 @@ static int first_shadow_cpu(struct perf_stat_config *config, {int i; -if (!aggr_get_id) +if (!config->aggr_get_id)return 0 ;if (config->aggr_mode ==AGGR_NONE )
@@ -932,7 +928,7 @@ static int first_shadow_cpu(struct perf_stat_config *config,for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) {int cpu2 =perf_evsel__cpus (evsel)->map[i]; -if (aggr_get_id (evsel_list->cpus, cpu2) == id) +if (config->aggr_get_id (config, evsel_list->cpus, cpu2) == id)return cpu2; }return 0 ;
@@ -1102,12 +1098,12 @@ static void aggr_update_shadow(struct perf_stat_config *config,u64 val;struct perf_evsel *counter; -for (s =0 ; s < aggr_map->nr; s++) { - id = aggr_map->map[s]; +for (s =0 ; s < config->aggr_map->nr; s++) { + id = config->aggr_map->map[s];evlist__for_each_entry (evlist, counter) { val =0 ;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - s2 =aggr_get_id (evsel_list->cpus, cpu); + s2 = config->aggr_get_id (config, evsel_list->cpus, cpu);if (s2 != id)continue ; val +=perf_counts (counter->counts, cpu,0 )->val;
@@ -1147,8 +1143,8 @@ static void uniquify_event_name(struct perf_evsel *counter) counter->uniquified_name = true; } -static void collect_all_aliases (struct perf_evsel *counter, -void (*cb)(struct perf_evsel *counter,void *data, +static void collect_all_aliases (struct perf_stat_config *config,struct perf_evsel *counter, +void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data,bool first),void *data) {
@@ -1164,22 +1160,22 @@ static void collect_all_aliases(struct perf_evsel *counter, perf_evsel__is_clock(alias) != perf_evsel__is_clock(counter)) break; alias->merged_stat = true; -cb (alias, data, false); +cb (config, alias, data, false); } } -static bool collect_data (struct perf_evsel *counter, -void (*cb)(struct perf_evsel *counter,void *data, +static bool collect_data (struct perf_stat_config *config,struct perf_evsel *counter, +void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data,bool first),void *data) {if (counter->merged_stat)return false; -cb (counter, data, true); +cb (config, counter, data, true);if (no_merge)uniquify_event_name (counter);else if (counter->auto_merge_stats) -collect_all_aliases (counter, cb, data); +collect_all_aliases (config, counter, cb, data);return true; }
@@ -1190,7 +1186,8 @@ struct aggr_data {int cpu; }; -static void aggr_cb (struct perf_evsel *counter,void *data,bool first) +static void aggr_cb (struct perf_stat_config *config, +struct perf_evsel *counter,void *data,bool first) {struct aggr_data *ad = data;int cpu, s2;
@@ -1198,7 +1195,7 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first)for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) {struct perf_counts_values *counts; - s2 =aggr_get_id (perf_evsel__cpus (counter), cpu); + s2 = config->aggr_get_id (config,perf_evsel__cpus (counter), cpu);if (s2 != ad->id)continue ;if (first)
@@ -1232,7 +1229,7 @@ static void print_aggr(struct perf_stat_config *config,u64 ena, run, val;bool first; -if (!(aggr_map || aggr_get_id)) +if (!(config->aggr_map || config->aggr_get_id))return ;aggr_update_shadow (config, evlist);
@@ -1241,12 +1238,12 @@ static void print_aggr(struct perf_stat_config *config,* With metric_only everything is on a single line. * Without each counter has its own line. */ -for (s =0 ; s < aggr_map->nr; s++) { +for (s =0 ; s < config->aggr_map->nr; s++) {struct aggr_data ad;if (prefix && metric_only)fprintf (output,"%s" , prefix); - ad.id = id = aggr_map->map[s]; + ad.id = id = config->aggr_map->map[s]; first = true;evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))
@@ -1254,7 +1251,7 @@ static void print_aggr(struct perf_stat_config *config, ad.val = ad.ena = ad.run =0 ; ad.nr =0 ; -if (!collect_data (counter, aggr_cb, &ad)) +if (!collect_data (config, counter, aggr_cb, &ad))continue ; nr = ad.nr; ena = ad.ena;
@@ -1370,7 +1367,8 @@ struct caggr_data {double avg, avg_enabled, avg_running; }; -static void counter_aggr_cb (struct perf_evsel *counter,void *data, +static void counter_aggr_cb (struct perf_stat_config *config__maybe_unused , +struct perf_evsel *counter,void *data,bool first__maybe_unused ) {struct caggr_data *cd = data;
@@ -1393,7 +1391,7 @@ static void print_counter_aggr(struct perf_stat_config *config,double uval;struct caggr_data cd = { .avg =0.0 }; -if (!collect_data (counter, counter_aggr_cb, &cd)) +if (!collect_data (config, counter, counter_aggr_cb, &cd))return ;if (prefix && !metric_only)
@@ -1406,7 +1404,8 @@ static void print_counter_aggr(struct perf_stat_config *config,fprintf (output,"\n" ); } -static void counter_cb (struct perf_evsel *counter,void *data, +static void counter_cb (struct perf_stat_config *config__maybe_unused , +struct perf_evsel *counter,void *data,bool first__maybe_unused ) {struct aggr_data *ad = data;
@@ -1431,7 +1430,7 @@ static void print_counter(struct perf_stat_config *config,for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) {struct aggr_data ad = { .cpu = cpu }; -if (!collect_data (counter, counter_cb, &ad)) +if (!collect_data (config, counter, counter_cb, &ad))return ; val = ad.val; ena = ad.ena;
@@ -1944,12 +1943,14 @@ static const struct option stat_options[] = { OPT_END() }; -static int perf_stat__get_socket (struct cpu_map *map,int cpu) +static int perf_stat__get_socket (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int cpu) {return cpu_map__get_socket (map, cpu,NULL ); } -static int perf_stat__get_core (struct cpu_map *map,int cpu) +static int perf_stat__get_core (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int cpu) {return cpu_map__get_core (map, cpu,NULL ); }
@@ -1966,9 +1967,8 @@ static int cpu_map__get_max(struct cpu_map *map)return max; } -static struct cpu_map *cpus_aggr_map; - -static int perf_stat__get_aggr (aggr_get_id_t get_id,struct cpu_map *map,int idx) +static int perf_stat__get_aggr (struct perf_stat_config *config, +aggr_get_id_t get_id,struct cpu_map *map,int idx) {int cpu;
@@ -1977,20 +1977,22 @@ static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int id cpu = map->map[idx]; -if (cpus_aggr_map->map[cpu] ==-1 ) - cpus_aggr_map->map[cpu] =get_id (map, idx); +if (config->cpus_aggr_map->map[cpu] ==-1 ) + config->cpus_aggr_map->map[cpu] =get_id (config, map, idx); -return cpus_aggr_map->map[cpu]; +return config->cpus_aggr_map->map[cpu]; } -static int perf_stat__get_socket_cached (struct cpu_map *map,int idx) +static int perf_stat__get_socket_cached (struct perf_stat_config *config, +struct cpu_map *map,int idx) { -return perf_stat__get_aggr (perf_stat__get_socket, map, idx); +return perf_stat__get_aggr (config, perf_stat__get_socket, map, idx); } -static int perf_stat__get_core_cached (struct cpu_map *map,int idx) +static int perf_stat__get_core_cached (struct perf_stat_config *config, +struct cpu_map *map,int idx) { -return perf_stat__get_aggr (perf_stat__get_core, map, idx); +return perf_stat__get_aggr (config, perf_stat__get_core, map, idx); }static int perf_stat_init_aggr_mode (void )
@@ -1999,18 +2001,18 @@ static int perf_stat_init_aggr_mode(void)switch (stat_config.aggr_mode) {case AGGR_SOCKET : -if (cpu_map__build_socket_map (evsel_list->cpus, &aggr_map)) { +if (cpu_map__build_socket_map (evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build socket map" );return -1 ; } - aggr_get_id = perf_stat__get_socket_cached; + stat_config.aggr_get_id = perf_stat__get_socket_cached;break ;case AGGR_CORE : -if (cpu_map__build_core_map (evsel_list->cpus, &aggr_map)) { +if (cpu_map__build_core_map (evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = perf_stat__get_core_cached; + stat_config.aggr_get_id = perf_stat__get_core_cached;break ;case AGGR_NONE :case AGGR_GLOBAL :
@@ -2026,16 +2028,16 @@ static int perf_stat_init_aggr_mode(void)* the aggregation translate cpumap. */ nr =cpu_map__get_max (evsel_list->cpus); - cpus_aggr_map =cpu_map__empty_new (nr +1 ); -return cpus_aggr_map ?0 : -ENOMEM ; + stat_config.cpus_aggr_map =cpu_map__empty_new (nr +1 ); +return stat_config.cpus_aggr_map ?0 : -ENOMEM ; }static void perf_stat__exit_aggr_mode (void ) { -cpu_map__put (aggr_map); -cpu_map__put (cpus_aggr_map); - aggr_map =NULL ; - cpus_aggr_map =NULL ; +cpu_map__put (stat_config.aggr_map); +cpu_map__put (stat_config.cpus_aggr_map); + stat_config.aggr_map =NULL ; + stat_config.cpus_aggr_map =NULL ; }static inline int perf_env__get_cpu (struct perf_env *env,struct cpu_map *map,int idx)
@@ -2093,12 +2095,14 @@ static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus,return cpu_map__build_map (cpus, corep, perf_env__get_core, env); } -static int perf_stat__get_socket_file (struct cpu_map *map,int idx) +static int perf_stat__get_socket_file (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int idx) {return perf_env__get_socket (map, idx, &perf_stat.session->header.env); } -static int perf_stat__get_core_file (struct cpu_map *map,int idx) +static int perf_stat__get_core_file (struct perf_stat_config *config__maybe_unused , +struct cpu_map *map,int idx) {return perf_env__get_core (map, idx, &perf_stat.session->header.env); }
@@ -2109,18 +2113,18 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st)switch (stat_config.aggr_mode) {case AGGR_SOCKET : -if (perf_env__build_socket_map (env, evsel_list->cpus, &aggr_map)) { +if (perf_env__build_socket_map (env, evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build socket map" );return -1 ; } - aggr_get_id = perf_stat__get_socket_file; + stat_config.aggr_get_id = perf_stat__get_socket_file;break ;case AGGR_CORE : -if (perf_env__build_core_map (env, evsel_list->cpus, &aggr_map)) { +if (perf_env__build_core_map (env, evsel_list->cpus, &stat_config.aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = perf_stat__get_core_file; + stat_config.aggr_get_id = perf_stat__get_core_file;break ;case AGGR_NONE :case AGGR_GLOBAL :
tools/perf/util/stat.h +6 -0
@@ -90,6 +90,9 @@ struct runtime_stat {struct rblist value_list; }; +typedef int (*aggr_get_id_t )(struct perf_stat_config *config, +struct cpu_map *m,int cpu); +struct perf_stat_config {enum aggr_mode aggr_mode;bool scale;
@@ -115,6 +118,9 @@ struct perf_stat_config {const char *csv_sep;struct stats *walltime_nsecs_stats;struct rusage ru_data; +struct cpu_map *aggr_map; +aggr_get_id_t aggr_get_id; +struct cpu_map *cpus_aggr_map; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 37/43 perf stat: Do not use glovab evsel_list in print functions
In reply to Jiri OlsaGetting rid of the evsel_list dependency, here we can use the evlist pointer from the event.
--- tools/perf/builtin-stat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +3 -2
@@ -914,6 +914,7 @@ static void print_metric_header(struct perf_stat_config *config,static int first_shadow_cpu (struct perf_stat_config *config,struct perf_evsel *evsel,int id) { +struct perf_evlist *evlist = evsel->evlist;int i;if (!config->aggr_get_id)
@@ -928,7 +929,7 @@ static int first_shadow_cpu(struct perf_stat_config *config,for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) {int cpu2 =perf_evsel__cpus (evsel)->map[i]; -if (config->aggr_get_id (config, evsel_list->cpus, cpu2) == id) +if (config->aggr_get_id (config, evlist->cpus, cpu2) == id)return cpu2; }return 0 ;
@@ -1103,7 +1104,7 @@ static void aggr_update_shadow(struct perf_stat_config *config,evlist__for_each_entry (evlist, counter) { val =0 ;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - s2 = config->aggr_get_id (config, evsel_list->cpus, cpu); + s2 = config->aggr_get_id (config, evlist->cpus, cpu);if (s2 != id)continue ; val +=perf_counts (counter->counts, cpu,0 )->val;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Do not use the global 'evsel_list' in print functions
perf stat: Do not use the global 'evsel_list' in print functions
Commit-ID: a138af663500a07742bb27793302625135a0f6c4 Gitweb: https://git.kernel.org/tip/a138af663500a07742bb27793302625135a0f6c4 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:46 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Do not use the global 'evsel_list' in print functions
Get rid of the the 'evsel_list' global variable dependency, here we can use the 'evlist' pointer from the evsel.
--- tools/perf/builtin-stat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +3 -2
@@ -914,6 +914,7 @@ static void print_metric_header(struct perf_stat_config *config,static int first_shadow_cpu (struct perf_stat_config *config,struct perf_evsel *evsel,int id) { +struct perf_evlist *evlist = evsel->evlist;int i;if (!config->aggr_get_id)
@@ -928,7 +929,7 @@ static int first_shadow_cpu(struct perf_stat_config *config,for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) {int cpu2 =perf_evsel__cpus (evsel)->map[i]; -if (config->aggr_get_id (config, evsel_list->cpus, cpu2) == id) +if (config->aggr_get_id (config, evlist->cpus, cpu2) == id)return cpu2; }return 0 ;
@@ -1103,7 +1104,7 @@ static void aggr_update_shadow(struct perf_stat_config *config,evlist__for_each_entry (evlist, counter) { val =0 ;for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - s2 = config->aggr_get_id (config, evsel_list->cpus, cpu); + s2 = config->aggr_get_id (config, evlist->cpus, cpu);if (s2 != id)continue ; val +=perf_counts (counter->counts, cpu,0 )->val;
Jiri Olsa
reviewerPATCH 38/43 perf stat: Move big_num data into struct perf_stat_config
In reply to Jiri OlsaMoving static big_num into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 8 ++++---- tools/perf/util/stat.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +4 -4
@@ -151,7 +151,6 @@ static bool transaction_run;static bool topdown_run = false;static bool smi_cost = false;static bool smi_reset = false; -static bool big_num = true;static int big_num_opt =-1 ;static bool group = false;static const char *pre_cmd =NULL ;
@@ -192,6 +191,7 @@ static struct perf_stat_config stat_config = { .run_count = 1, .metric_only_len = METRIC_ONLY_LEN, .walltime_nsecs_stats = &walltime_nsecs_stats, + .big_num = true, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -945,7 +945,7 @@ static void abs_printout(struct perf_stat_config *config,if (config->csv_output) { fmt =floor (sc) != sc ?"%.2f%s" :"%.0f%s" ; }else { -if (big_num) +if (config->big_num) fmt =floor (sc) != sc ?"%'18.2f%s" :"%'18.0f%s" ;else fmt =floor (sc) != sc ?"%18.2f%s" :"%18.0f%s" ;
@@ -2847,9 +2847,9 @@ int cmd_stat(int argc, const char **argv)parse_options_usage (NULL , stat_options,"x" ,1 ); goto out; }else /* Nope, so disable big number formatting */ - big_num = false; + stat_config.big_num = false; }else if (big_num_opt ==0 )/* User passed --no-big-num */ - big_num = false; + stat_config.big_num = false;setup_system_wide (argc);
tools/perf/util/stat.h +1 -0
@@ -103,6 +103,7 @@ struct perf_stat_config {bool metric_only;bool null_run;bool ru_display; +bool big_num;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'big_num' data to 'struct perf_stat_config'
perf stat: Move 'big_num' data to 'struct perf_stat_config'
Commit-ID: 34ff0866d46ae206de884f54e7235f57096e5588 Gitweb: https://git.kernel.org/tip/34ff0866d46ae206de884f54e7235f57096e5588 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:47 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move 'big_num' data to 'struct perf_stat_config'
Move the static variable 'big_num' to 'struct perf_stat_config', so that it can be passed around and used outside 'perf stat' command.
--- tools/perf/builtin-stat.c | 8 ++++---- tools/perf/util/stat.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +4 -4
@@ -151,7 +151,6 @@ static bool transaction_run;static bool topdown_run = false;static bool smi_cost = false;static bool smi_reset = false; -static bool big_num = true;static int big_num_opt =-1 ;static bool group = false;static const char *pre_cmd =NULL ;
@@ -192,6 +191,7 @@ static struct perf_stat_config stat_config = { .run_count = 1, .metric_only_len = METRIC_ONLY_LEN, .walltime_nsecs_stats = &walltime_nsecs_stats, + .big_num = true, };static bool is_duration_time (struct perf_evsel *evsel)
@@ -945,7 +945,7 @@ static void abs_printout(struct perf_stat_config *config,if (config->csv_output) { fmt =floor (sc) != sc ?"%.2f%s" :"%.0f%s" ; }else { -if (big_num) +if (config->big_num) fmt =floor (sc) != sc ?"%'18.2f%s" :"%'18.0f%s" ;else fmt =floor (sc) != sc ?"%18.2f%s" :"%18.0f%s" ;
@@ -2847,9 +2847,9 @@ int cmd_stat(int argc, const char **argv)parse_options_usage (NULL , stat_options,"x" ,1 ); goto out; }else /* Nope, so disable big number formatting */ - big_num = false; + stat_config.big_num = false; }else if (big_num_opt ==0 )/* User passed --no-big-num */ - big_num = false; + stat_config.big_num = false;setup_system_wide (argc);
tools/perf/util/stat.h +1 -0
@@ -103,6 +103,7 @@ struct perf_stat_config {bool metric_only;bool null_run;bool ru_display; +bool big_num;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 39/43 perf stat: Move no_merge data into struct perf_stat_config
In reply to Jiri OlsaMoving static no_merge into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -158,7 +158,6 @@ static const char *post_cmd = NULL;static bool sync_run = false;static bool forever = false;static bool force_metric_only = false; -static bool no_merge = false;static bool walltime_run_table = false;static struct timespec ref_time;static bool append_file;
@@ -1173,7 +1172,7 @@ static bool collect_data(struct perf_stat_config *config, struct perf_evsel *couif (counter->merged_stat)return false;cb (config, counter, data, true); -if (no_merge) +if (config->no_merge)uniquify_event_name (counter);else if (counter->auto_merge_stats)collect_all_aliases (config, counter, cb, data);
@@ -1902,7 +1901,7 @@ static const struct option stat_options[] = { "list of cpus to monitor in system-wide"),OPT_SET_UINT ('A' ,"no-aggr" , &stat_config.aggr_mode,"disable CPU count aggregation" ,AGGR_NONE ), -OPT_BOOLEAN (0 ,"no-merge" , &no_merge,"Do not merge identical named events" ), +OPT_BOOLEAN (0 ,"no-merge" , &stat_config.no_merge,"Do not merge identical named events" ),OPT_STRING ('x' ,"field-separator" , &stat_config.csv_sep,"separator" ,"print counts with custom separator" ), OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
tools/perf/util/stat.h +1 -0
@@ -104,6 +104,7 @@ struct perf_stat_config {bool null_run;bool ru_display;bool big_num; +bool no_merge;FILE *output;unsigned int interval;unsigned int timeout;
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'no_merge' data to 'struct perf_stat_config'
perf stat: Move 'no_merge' data to 'struct perf_stat_config'
Commit-ID: fdee335b00b0807e8d65b8e3d81214556f07bed3 Gitweb: https://git.kernel.org/tip/fdee335b00b0807e8d65b8e3d81214556f07bed3 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:48 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:24 -0300
perf stat: Move 'no_merge' data to 'struct perf_stat_config'
Move the static variable 'no_merge' to 'struct perf_stat_config', so that it can be passed around and used outside 'perf stat' command.
--- tools/perf/builtin-stat.c | 5 ++--- tools/perf/util/stat.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +2 -3
@@ -158,7 +158,6 @@ static const char *post_cmd = NULL;static bool sync_run = false;static bool forever = false;static bool force_metric_only = false; -static bool no_merge = false;static bool walltime_run_table = false;static struct timespec ref_time;static bool append_file;
@@ -1173,7 +1172,7 @@ static bool collect_data(struct perf_stat_config *config, struct perf_evsel *couif (counter->merged_stat)return false;cb (config, counter, data, true); -if (no_merge) +if (config->no_merge)uniquify_event_name (counter);else if (counter->auto_merge_stats)collect_all_aliases (config, counter, cb, data);
@@ -1902,7 +1901,7 @@ static const struct option stat_options[] = { "list of cpus to monitor in system-wide"),OPT_SET_UINT ('A' ,"no-aggr" , &stat_config.aggr_mode,"disable CPU count aggregation" ,AGGR_NONE ), -OPT_BOOLEAN (0 ,"no-merge" , &no_merge,"Do not merge identical named events" ), +OPT_BOOLEAN (0 ,"no-merge" , &stat_config.no_merge,"Do not merge identical named events" ),OPT_STRING ('x' ,"field-separator" , &stat_config.csv_sep,"separator" ,"print counts with custom separator" ), OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
tools/perf/util/stat.h +1 -0
@@ -104,6 +104,7 @@ struct perf_stat_config {bool null_run;bool ru_display;bool big_num; +bool no_merge;FILE *output;unsigned int interval;unsigned int timeout;
Jiri Olsa
reviewerPATCH 40/43 perf stat: Propagate struct target arg to sort_aggr_thread
In reply to Jiri OlsaPropagate struct target arg to sort_aggr_thread so the function does not depend on stat command object local target and can be moved out.
--- tools/perf/builtin-stat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +6 -4
@@ -1284,7 +1284,8 @@ static int cmp_val(const void *a, const void *b)static struct perf_aggr_thread_value *sort_aggr_thread (struct perf_evsel *counter,int nthreads,int ncpus, -int *ret) +int *ret, +struct target *_target) {int cpu, thread, i =0 ;double uval;
@@ -1309,7 +1310,7 @@ static struct perf_aggr_thread_value *sort_aggr_thread(* Skip value 0 when enabling --per-thread globally, * otherwise too many 0 output. */ -if (uval ==0.0 &&target__has_per_thread (&target)) +if (uval ==0.0 &&target__has_per_thread (_target))continue ; buf[i].counter = counter;
@@ -1330,6 +1331,7 @@ static struct perf_aggr_thread_value *sort_aggr_thread( }static void print_aggr_thread (struct perf_stat_config *config, +struct target *_target,struct perf_evsel *counter,char *prefix) {FILE *output = config->output;
@@ -1338,7 +1340,7 @@ static void print_aggr_thread(struct perf_stat_config *config,int thread, sorted_threads, id;struct perf_aggr_thread_value *buf; - buf =sort_aggr_thread (counter, nthreads, ncpus, &sorted_threads); + buf =sort_aggr_thread (counter, nthreads, ncpus, &sorted_threads, _target);if (!buf) {perror ("cannot sort aggr thread" );return ;
@@ -1754,7 +1756,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_aggr_thread (config, counter, prefix); +print_aggr_thread (config, _target, counter, prefix); }break ;case AGGR_GLOBAL :
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Propagate 'struct target' arg to sort_aggr_thread()
perf stat: Propagate 'struct target' arg to sort_aggr_thread()
Commit-ID: be54d59325314be9d4d53852cbfbeeaebc3b9239 Gitweb: https://git.kernel.org/tip/be54d59325314be9d4d53852cbfbeeaebc3b9239 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:49 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:25 -0300
perf stat: Propagate 'struct target' arg to sort_aggr_thread()
Propagate the 'struct target' arg to sort_aggr_thread() so that the function does not depend on the 'perf stat' command object local variable 'target' and can be moved out.
--- tools/perf/builtin-stat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
tools/perf/builtin-stat.c +6 -4
@@ -1284,7 +1284,8 @@ static int cmp_val(const void *a, const void *b)static struct perf_aggr_thread_value *sort_aggr_thread (struct perf_evsel *counter,int nthreads,int ncpus, -int *ret) +int *ret, +struct target *_target) {int cpu, thread, i =0 ;double uval;
@@ -1309,7 +1310,7 @@ static struct perf_aggr_thread_value *sort_aggr_thread(* Skip value 0 when enabling --per-thread globally, * otherwise too many 0 output. */ -if (uval ==0.0 &&target__has_per_thread (&target)) +if (uval ==0.0 &&target__has_per_thread (_target))continue ; buf[i].counter = counter;
@@ -1330,6 +1331,7 @@ static struct perf_aggr_thread_value *sort_aggr_thread( }static void print_aggr_thread (struct perf_stat_config *config, +struct target *_target,struct perf_evsel *counter,char *prefix) {FILE *output = config->output;
@@ -1338,7 +1340,7 @@ static void print_aggr_thread(struct perf_stat_config *config,int thread, sorted_threads, id;struct perf_aggr_thread_value *buf; - buf =sort_aggr_thread (counter, nthreads, ncpus, &sorted_threads); + buf =sort_aggr_thread (counter, nthreads, ncpus, &sorted_threads, _target);if (!buf) {perror ("cannot sort aggr thread" );return ;
@@ -1754,7 +1756,7 @@ perf_evlist__print_counters(struct perf_evlist *evlist,evlist__for_each_entry (evlist, counter) {if (is_duration_time (counter))continue ; -print_aggr_thread (config, counter, prefix); +print_aggr_thread (config, _target, counter, prefix); }break ;case AGGR_GLOBAL :
Jiri Olsa
reviewerPATCH 41/43 perf stat: Move walltime_* data into struct perf_stat_config
In reply to Jiri OlsaMoving static walltime_* data into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 22 ++++++++++------------ tools/perf/util/stat.h | 2 ++ 2 files changed, 12 insertions(+), 12 deletions(-)
tools/perf/builtin-stat.c +10 -12
@@ -158,13 +158,11 @@ static const char *post_cmd = NULL;static bool sync_run = false;static bool forever = false;static bool force_metric_only = false; -static bool walltime_run_table = false;static struct timespec ref_time;static bool append_file;static bool interval_count;static const char *output_name;static int output_fd; -static u64 *walltime_run;struct perf_stat {bool record;
@@ -604,8 +602,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) t1 =rdclock (); -if (walltime_run_table) - walltime_run[run_idx] = t1 - t0; +if (stat_config.walltime_run_table) + stat_config.walltime_run[run_idx] = t1 - t0;update_stats (&walltime_nsecs_stats, t1 - t0);
@@ -1646,7 +1644,7 @@ static void print_table(struct perf_stat_config *config,fprintf (output,"%*s# Table of individual measurements:\n" , indent,"" );for (idx =0 ; idx < config->run_count; idx++) { -double run = (double ) walltime_run[idx] /NSEC_PER_SEC ; +double run = (double ) config->walltime_run[idx] /NSEC_PER_SEC ;int h, n =1 +abs ((int ) (100.0 * (run - avg)/run) /5 ); fprintf(output, " %17.*f (%+.*f) ",
@@ -1694,7 +1692,7 @@ static void print_footer(struct perf_stat_config *config)*/ int precision =get_precision (sd) +2 ; -if (walltime_run_table) +if (config->walltime_run_table)print_table (config, output, precision, avg); fprintf(output, " %17.*f +- %.*f seconds time elapsed",
@@ -1888,7 +1886,7 @@ static const struct option stat_options[] = { "be more verbose (show counter open errors, etc)"),OPT_INTEGER ('r' ,"repeat" , &stat_config.run_count,"repeat command and print average + stddev (max: 100, forever: 0)" ), -OPT_BOOLEAN (0 ,"table" , &walltime_run_table, +OPT_BOOLEAN (0 ,"table" , &stat_config.walltime_run_table,"display details about each run (only with -r option)" ),OPT_BOOLEAN ('n' ,"null" , &stat_config.null_run, "null run - dont start any counters"),
@@ -2802,7 +2800,7 @@ int cmd_stat(int argc, const char **argv) goto out; } -if (walltime_run_table && stat_config.run_count <=1 ) { +if (stat_config.walltime_run_table && stat_config.run_count <=1 ) {fprintf (stderr,"--table is only supported with -r\n" );parse_options_usage (stat_usage, stat_options,"r" ,1 );parse_options_usage (NULL , stat_options,"table" ,0 );
@@ -2870,9 +2868,9 @@ int cmd_stat(int argc, const char **argv) stat_config.run_count =1 ; } -if (walltime_run_table) { - walltime_run =zalloc (stat_config.run_count *sizeof (walltime_run[0 ])); -if (!walltime_run) { +if (stat_config.walltime_run_table) { + stat_config.walltime_run =zalloc (stat_config.run_count *sizeof (stat_config.walltime_run[0 ])); +if (!stat_config.walltime_run) {pr_err ("failed to setup -r option" ); goto out; }
@@ -3052,7 +3050,7 @@ int cmd_stat(int argc, const char **argv)perf_stat__exit_aggr_mode ();perf_evlist__free_stats (evsel_list); out: -free (walltime_run); +free (stat_config.walltime_run);if (smi_cost && smi_reset)sysfs__write_int (FREEZE_ON_SMI_PATH ,0 );
tools/perf/util/stat.h +2 -0
@@ -105,6 +105,7 @@ struct perf_stat_config {bool ru_display;bool big_num;bool no_merge; +bool walltime_run_table;FILE *output;unsigned int interval;unsigned int timeout;
@@ -123,6 +124,7 @@ struct perf_stat_config {struct cpu_map *aggr_map;aggr_get_id_t aggr_get_id;struct cpu_map *cpus_aggr_map; +u64 *walltime_run; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'walltime_*' data to 'struct perf_stat_config'
perf stat: Move 'walltime_*' data to 'struct perf_stat_config'
Commit-ID: 54ac0b1bd25cbdeda226b32a0459e09de46157b3 Gitweb: https://git.kernel.org/tip/54ac0b1bd25cbdeda226b32a0459e09de46157b3 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:50 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:25 -0300
perf stat: Move 'walltime_*' data to 'struct perf_stat_config'
Move the static variables 'walltime_*' to 'struct perf_stat_config', so that it can be passed around and used outside 'perf stat' command.
--- tools/perf/builtin-stat.c | 22 ++++++++++------------ tools/perf/util/stat.h | 2 ++ 2 files changed, 12 insertions(+), 12 deletions(-)
tools/perf/builtin-stat.c +10 -12
@@ -158,13 +158,11 @@ static const char *post_cmd = NULL;static bool sync_run = false;static bool forever = false;static bool force_metric_only = false; -static bool walltime_run_table = false;static struct timespec ref_time;static bool append_file;static bool interval_count;static const char *output_name;static int output_fd; -static u64 *walltime_run;struct perf_stat {bool record;
@@ -604,8 +602,8 @@ try_again: t1 =rdclock (); -if (walltime_run_table) - walltime_run[run_idx] = t1 - t0; +if (stat_config.walltime_run_table) + stat_config.walltime_run[run_idx] = t1 - t0;update_stats (&walltime_nsecs_stats, t1 - t0);
@@ -1646,7 +1644,7 @@ static void print_table(struct perf_stat_config *config,fprintf (output,"%*s# Table of individual measurements:\n" , indent,"" );for (idx =0 ; idx < config->run_count; idx++) { -double run = (double ) walltime_run[idx] /NSEC_PER_SEC ; +double run = (double ) config->walltime_run[idx] /NSEC_PER_SEC ;int h, n =1 +abs ((int ) (100.0 * (run - avg)/run) /5 ); fprintf(output, " %17.*f (%+.*f) ",
@@ -1694,7 +1692,7 @@ static void print_footer(struct perf_stat_config *config)*/ int precision =get_precision (sd) +2 ; -if (walltime_run_table) +if (config->walltime_run_table)print_table (config, output, precision, avg); fprintf(output, " %17.*f +- %.*f seconds time elapsed",
@@ -1888,7 +1886,7 @@ static const struct option stat_options[] = { "be more verbose (show counter open errors, etc)"),OPT_INTEGER ('r' ,"repeat" , &stat_config.run_count,"repeat command and print average + stddev (max: 100, forever: 0)" ), -OPT_BOOLEAN (0 ,"table" , &walltime_run_table, +OPT_BOOLEAN (0 ,"table" , &stat_config.walltime_run_table,"display details about each run (only with -r option)" ),OPT_BOOLEAN ('n' ,"null" , &stat_config.null_run, "null run - dont start any counters"),
@@ -2802,7 +2800,7 @@ int cmd_stat(int argc, const char **argv) goto out; } -if (walltime_run_table && stat_config.run_count <=1 ) { +if (stat_config.walltime_run_table && stat_config.run_count <=1 ) {fprintf (stderr,"--table is only supported with -r\n" );parse_options_usage (stat_usage, stat_options,"r" ,1 );parse_options_usage (NULL , stat_options,"table" ,0 );
@@ -2870,9 +2868,9 @@ int cmd_stat(int argc, const char **argv) stat_config.run_count =1 ; } -if (walltime_run_table) { - walltime_run =zalloc (stat_config.run_count *sizeof (walltime_run[0 ])); -if (!walltime_run) { +if (stat_config.walltime_run_table) { + stat_config.walltime_run =zalloc (stat_config.run_count *sizeof (stat_config.walltime_run[0 ])); +if (!stat_config.walltime_run) {pr_err ("failed to setup -r option" ); goto out; }
@@ -3052,7 +3050,7 @@ int cmd_stat(int argc, const char **argv)perf_stat__exit_aggr_mode ();perf_evlist__free_stats (evsel_list); out: -free (walltime_run); +free (stat_config.walltime_run);if (smi_cost && smi_reset)sysfs__write_int (FREEZE_ON_SMI_PATH ,0 );
tools/perf/util/stat.h +2 -0
@@ -105,6 +105,7 @@ struct perf_stat_config {bool ru_display;bool big_num;bool no_merge; +bool walltime_run_table;FILE *output;unsigned int interval;unsigned int timeout;
@@ -123,6 +124,7 @@ struct perf_stat_config {struct cpu_map *aggr_map;aggr_get_id_t aggr_get_id;struct cpu_map *cpus_aggr_map; +u64 *walltime_run; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 42/43 perf stat: Move metric_events into struct perf_stat_config
In reply to Jiri OlsaMoving static metric_events into struct perf_stat_config, so it can be passed around and used outside stat command.
--- tools/perf/builtin-stat.c | 10 ++++------ tools/perf/util/stat.h | 1 + 2 files changed, 5 insertions(+), 6 deletions(-)
tools/perf/builtin-stat.c +4 -6
@@ -137,8 +137,6 @@ static const char *smi_cost_attrs = {static struct perf_evlist *evsel_list; -static struct rblist metric_events; -static struct target target = { .uid =UINT_MAX , };
@@ -1082,7 +1080,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,perf_stat__print_shadow_stats (config, counter, uval,first_shadow_cpu (config, counter, id), - &out, &metric_events, st); + &out, &config->metric_events, st);if (!config->csv_output && !config->metric_only) {print_noise (config, counter, noise);print_running (config, run, ena);
@@ -1533,7 +1531,7 @@ static void print_metric_headers(struct perf_stat_config *config,perf_stat__print_shadow_stats (config, counter,0 ,0 , &out, - &metric_events, + &config->metric_events, &rt_stat); }fputc ('\n' , config->output);
@@ -1860,7 +1858,7 @@ static int parse_metric_groups(const struct option *opt,const char *str, int unset __maybe_unused) { - return metricgroup__parse_groups(opt, str, &metric_events); + return metricgroup__parse_groups(opt, str, &stat_config.metric_events); } static const struct option stat_options[] = {
@@ -2321,7 +2319,7 @@ static int add_default_attributes(void)struct option opt = { .value = &evsel_list };return metricgroup__parse_groups (&opt,"transaction" , - &metric_events); + &stat_config.metric_events); } if (pmu_have_event("cpu", "cycles-ct") &&
tools/perf/util/stat.h +1 -0
@@ -125,6 +125,7 @@ struct perf_stat_config {aggr_get_id_t aggr_get_id;struct cpu_map *cpus_aggr_map;u64 *walltime_run; +struct rblist metric_events; };void update_stats (struct stats *stats,u64 val);
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move 'metric_events' to 'struct perf_stat_config'
perf stat: Move 'metric_events' to 'struct perf_stat_config'
Commit-ID: d0192fdba09a8901db133fe5a1fcd22d40fcf545 Gitweb: https://git.kernel.org/tip/d0192fdba09a8901db133fe5a1fcd22d40fcf545 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:51 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:25 -0300
perf stat: Move 'metric_events' to 'struct perf_stat_config'
Move the static variable 'metric_events' to 'struct perf_stat_config', so that it can be passed around and used outside 'perf stat' command.
--- tools/perf/builtin-stat.c | 10 ++++------ tools/perf/util/stat.h | 1 + 2 files changed, 5 insertions(+), 6 deletions(-)
tools/perf/builtin-stat.c +4 -6
@@ -137,8 +137,6 @@ static const char *smi_cost_attrs = {static struct perf_evlist *evsel_list; -static struct rblist metric_events; -static struct target target = { .uid =UINT_MAX , };
@@ -1082,7 +1080,7 @@ static void printout(struct perf_stat_config *config, int id, int nr,perf_stat__print_shadow_stats (config, counter, uval,first_shadow_cpu (config, counter, id), - &out, &metric_events, st); + &out, &config->metric_events, st);if (!config->csv_output && !config->metric_only) {print_noise (config, counter, noise);print_running (config, run, ena);
@@ -1533,7 +1531,7 @@ static void print_metric_headers(struct perf_stat_config *config,perf_stat__print_shadow_stats (config, counter,0 ,0 , &out, - &metric_events, + &config->metric_events, &rt_stat); }fputc ('\n' , config->output);
@@ -1860,7 +1858,7 @@ static int parse_metric_groups(const struct option *opt,const char *str, int unset __maybe_unused) { - return metricgroup__parse_groups(opt, str, &metric_events); + return metricgroup__parse_groups(opt, str, &stat_config.metric_events); } static const struct option stat_options[] = {
@@ -2321,7 +2319,7 @@ static int add_default_attributes(void)struct option opt = { .value = &evsel_list };return metricgroup__parse_groups (&opt,"transaction" , - &metric_events); + &stat_config.metric_events); } if (pmu_have_event("cpu", "cycles-ct") &&
tools/perf/util/stat.h +1 -0
@@ -125,6 +125,7 @@ struct perf_stat_config {aggr_get_id_t aggr_get_id;struct cpu_map *cpus_aggr_map;u64 *walltime_run; +struct rblist metric_events; };void update_stats (struct stats *stats,u64 val);
Jiri Olsa
reviewerPATCH 43/43 perf stat: Move display functions into stat-display.c
In reply to Jiri OlsaMoving perf_evlist__print_counters function with all its dependency functions to stat-display.c object.
--- tools/perf/builtin-stat.c | 1150 ------------------------------- tools/perf/util/Build | 1 + tools/perf/util/stat-display.c | 1166 ++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 6 + 4 files changed, 1173 insertions(+), 1150 deletions(-) create mode 100644 tools/perf/util/stat-display.c
tools/perf/builtin-stat.c +0 -1150
@@ -88,8 +88,6 @@#include "sane_ctype.h" #define DEFAULT_SEPARATOR " " -#define CNTR_NOT_SUPPORTED "<not supported>" -#define CNTR_NOT_COUNTED "<not counted>"#define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi"static void print_counters (struct timespec *ts,int argc,const char **argv);
@@ -189,11 +187,6 @@ static struct perf_stat_config stat_config = { .big_num = true, }; -static bool is_duration_time (struct perf_evsel *evsel) -{ -return !strcmp (evsel->name,"duration_time" ); -} -static inline void diff_timespec (struct timespec *r,struct timespec *a,struct timespec *b) {
@@ -643,1149 +636,6 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)return ret; } -static void print_running (struct perf_stat_config *config, -u64 run,u64 ena) -{ -if (config->csv_output) { -fprintf (config->output,"%s%" PRIu64"%s%.2f" , - config->csv_sep, - run, - config->csv_sep, - ena ?100.0 * run / ena :100.0 ); - }else if (run != ena) { -fprintf (config->output," (%.2f%%)" ,100.0 * run / ena); - } -} - -static void print_noise_pct (struct perf_stat_config *config, -double total,double avg) -{ -double pct =rel_stddev_stats (total, avg); - -if (config->csv_output) -fprintf (config->output,"%s%.2f%%" , config->csv_sep, pct); -else if (pct) -fprintf (config->output," ( +-%6.2f%% )" , pct); -} - -static void print_noise (struct perf_stat_config *config, -struct perf_evsel *evsel,double avg) -{ -struct perf_stat_evsel *ps; - -if (config->run_count ==1 ) -return ; - - ps = evsel->stats; -print_noise_pct (config,stddev_stats (&ps->res_stats[0 ]), avg); -} - -static void aggr_printout (struct perf_stat_config *config, -struct perf_evsel *evsel,int id,int nr) -{ -switch (config->aggr_mode) { -case AGGR_CORE : -fprintf (config->output,"S%d-C%*d%s%*d%s" , -cpu_map__id_to_socket (id), - config->csv_output ?0 :-8 , -cpu_map__id_to_cpu (id), - config->csv_sep, - config->csv_output ?0 :4 , - nr, - config->csv_sep); -break ; -case AGGR_SOCKET : -fprintf (config->output,"S%*d%s%*d%s" , - config->csv_output ?0 :-5 , - id, - config->csv_sep, - config->csv_output ?0 :4 , - nr, - config->csv_sep); -break ; -case AGGR_NONE : -fprintf (config->output,"CPU%*d%s" , - config->csv_output ?0 :-4 , -perf_evsel__cpus (evsel)->map[id], config->csv_sep); -break ; -case AGGR_THREAD : -fprintf (config->output,"%*s-%*d%s" , - config->csv_output ?0 :16 , -thread_map__comm (evsel->threads, id), - config->csv_output ?0 :-8 , -thread_map__pid (evsel->threads, id), - config->csv_sep); -break ; -case AGGR_GLOBAL : -case AGGR_UNSET : -default : -break ; - } -} - -struct outstate { -FILE *fh; -bool newline; -const char *prefix; -int nfields; -int id, nr; -struct perf_evsel *evsel; -}; - -#define METRIC_LEN 35 - -static void new_line_std (struct perf_stat_config *config__maybe_unused , -void *ctx) -{ -struct outstate *os = ctx; - - os->newline = true; -} - -static void do_new_line_std (struct perf_stat_config *config, -struct outstate *os) -{ -fputc ('\n' , os->fh); -fputs (os->prefix, os->fh); -aggr_printout (config, os->evsel, os->id, os->nr); -if (config->aggr_mode ==AGGR_NONE ) -fprintf (os->fh," " ); -fprintf (os->fh," " ); -} - -static void print_metric_std (struct perf_stat_config *config, -void *ctx,const char *color,const char *fmt, -const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -int n; -bool newline = os->newline; - - os->newline = false; - -if (unit ==NULL || fmt ==NULL ) { -fprintf (out,"%-*s" ,METRIC_LEN ,"" ); -return ; - } - -if (newline) -do_new_line_std (config, os); - - n =fprintf (out," # " ); -if (color) - n +=color_fprintf (out, color, fmt, val); -else - n +=fprintf (out, fmt, val); -fprintf (out," %-*s" ,METRIC_LEN - n -1 , unit); -} - -static void new_line_csv (struct perf_stat_config *config,void *ctx) -{ -struct outstate *os = ctx; -int i; - -fputc ('\n' , os->fh); -if (os->prefix) -fprintf (os->fh,"%s%s" , os->prefix, config->csv_sep); -aggr_printout (config, os->evsel, os->id, os->nr); -for (i =0 ; i < os->nfields; i++) -fputs (config->csv_sep, os->fh); -} - -static void print_metric_csv (struct perf_stat_config *config__maybe_unused , -void *ctx, -const char *color__maybe_unused , -const char *fmt,const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -char buf[64 ], *vals, *ends; - -if (unit ==NULL || fmt ==NULL ) { -fprintf (out,"%s%s" , config->csv_sep, config->csv_sep); -return ; - } -snprintf (buf,sizeof (buf), fmt, val); - ends = vals =ltrim (buf); -while (isdigit (*ends) || *ends =='.' ) - ends++; - *ends =0 ; -while (isspace (*unit)) - unit++; -fprintf (out,"%s%s%s%s" , config->csv_sep, vals, config->csv_sep, unit); -} - -/* Filter out some columns that don't work well in metrics only mode */ - -static bool valid_only_metric (const char *unit) -{ -if (!unit) -return false; -if (strstr (unit,"/sec" ) || -strstr (unit,"hz" ) || -strstr (unit,"Hz" ) || -strstr (unit,"CPUs utilized" )) -return false; -return true; -} - -static const char *fixunit (char *buf,struct perf_evsel *evsel, -const char *unit) -{ -if (!strncmp (unit,"of all" ,6 )) { -snprintf (buf,1024 ,"%s %s" ,perf_evsel__name (evsel), - unit); -return buf; - } -return unit; -} - -static void print_metric_only (struct perf_stat_config *config, -void *ctx,const char *color,const char *fmt, -const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -char buf[1024 ], str[1024 ]; -unsigned mlen = config->metric_only_len; - -if (!valid_only_metric (unit)) -return ; - unit =fixunit (buf, os->evsel, unit); -if (mlen <strlen (unit)) - mlen =strlen (unit) +1 ; - -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 (struct perf_stat_config *config__maybe_unused , -void *ctx,const char *color__maybe_unused , -const char *fmt, -const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -char buf[64 ], *vals, *ends; -char tbuf[1024 ]; - -if (!valid_only_metric (unit)) -return ; - unit =fixunit (tbuf, os->evsel, unit); -snprintf (buf,sizeof buf, fmt, val); - ends = vals =ltrim (buf); -while (isdigit (*ends) || *ends =='.' ) - ends++; - *ends =0 ; -fprintf (out,"%s%s" , vals, config->csv_sep); -} - -static void new_line_metric (struct perf_stat_config *config__maybe_unused , -void *ctx__maybe_unused ) -{ -} - -static void print_metric_header (struct perf_stat_config *config, -void *ctx,const char *color__maybe_unused , -const char *fmt__maybe_unused , -const char *unit,double val__maybe_unused ) -{ -struct outstate *os = ctx; -char tbuf[1024 ]; - -if (!valid_only_metric (unit)) -return ; - unit =fixunit (tbuf, os->evsel, unit); -if (config->csv_output) -fprintf (os->fh,"%s%s" , unit, config->csv_sep); -else -fprintf (os->fh,"%*s " , config->metric_only_len, unit); -} - -static int first_shadow_cpu (struct perf_stat_config *config, -struct perf_evsel *evsel,int id) -{ -struct perf_evlist *evlist = evsel->evlist; -int i; - -if (!config->aggr_get_id) -return 0 ; - -if (config->aggr_mode ==AGGR_NONE ) -return id; - -if (config->aggr_mode ==AGGR_GLOBAL ) -return 0 ; - -for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) { -int cpu2 =perf_evsel__cpus (evsel)->map[i]; - -if (config->aggr_get_id (config, evlist->cpus, cpu2) == id) -return cpu2; - } -return 0 ; -} - -static void abs_printout (struct perf_stat_config *config, -int id,int nr,struct perf_evsel *evsel,double avg) -{ -FILE *output = config->output; -double sc = evsel->scale; -const char *fmt; - -if (config->csv_output) { - fmt =floor (sc) != sc ?"%.2f%s" :"%.0f%s" ; - }else { -if (config->big_num) - fmt =floor (sc) != sc ?"%'18.2f%s" :"%'18.0f%s" ; -else - fmt =floor (sc) != sc ?"%18.2f%s" :"%18.0f%s" ; - } - -aggr_printout (config, evsel, id, nr); - -fprintf (output, fmt, avg, config->csv_sep); - -if (evsel->unit) -fprintf (output,"%-*s%s" , - config->csv_output ?0 : config->unit_width, - evsel->unit, config->csv_sep); - -fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel)); - -if (evsel->cgrp) -fprintf (output,"%s%s" , config->csv_sep, evsel->cgrp->name); -} - -static bool is_mixed_hw_group (struct perf_evsel *counter) -{ -struct perf_evlist *evlist = counter->evlist; -u32 pmu_type = counter->attr.type; -struct perf_evsel *pos; - -if (counter->nr_members <2 ) -return false; - -evlist__for_each_entry (evlist, pos) { -/* software events can be part of any hardware group */ -if (pos->attr.type ==PERF_TYPE_SOFTWARE ) -continue ; -if (pmu_type ==PERF_TYPE_SOFTWARE ) { - pmu_type = pos->attr.type; -continue ; - } -if (pmu_type != pos->attr.type) -return true; - } - -return false; -} - -static void printout (struct perf_stat_config *config,int id,int nr, -struct perf_evsel *counter,double uval, -char *prefix,u64 run,u64 ena,double noise, -struct runtime_stat *st) -{ -struct perf_stat_output_ctx out; -struct outstate os = { - .fh = config->output, - .prefix = prefix ? prefix :"" , - .id = id, - .nr = nr, - .evsel = counter, - }; -print_metric_t pm = print_metric_std; -new_line_t nl; - -if (config->metric_only) { - nl = new_line_metric; -if (config->csv_output) - pm = print_metric_only_csv; -else - pm = print_metric_only; - }else - nl = new_line_std; - -if (config->csv_output && !config->metric_only) { -static int aggr_fields[] = { - [AGGR_GLOBAL ] =0 , - [AGGR_THREAD ] =1 , - [AGGR_NONE ] =1 , - [AGGR_SOCKET ] =2 , - [AGGR_CORE ] =2 , - }; - - pm = print_metric_csv; - nl = new_line_csv; - os.nfields =3 ; - os.nfields += aggr_fields[config->aggr_mode]; -if (counter->cgrp) - os.nfields++; - } -if (run ==0 || ena ==0 || counter->counts->scaled ==-1 ) { -if (config->metric_only) { -pm (config, &os,NULL ,"" ,"" ,0 ); -return ; - } -aggr_printout (config, counter, id, nr); - -fprintf (config->output,"%*s%s" , - config->csv_output ?0 :18 , - counter->supported ?CNTR_NOT_COUNTED :CNTR_NOT_SUPPORTED , - config->csv_sep); - -if (counter->supported) { - config->print_free_counters_hint =1 ; -if (is_mixed_hw_group (counter)) - config->print_mixed_hw_group_error =1 ; - } - -fprintf (config->output,"%-*s%s" , - config->csv_output ?0 : config->unit_width, - counter->unit, config->csv_sep); - -fprintf (config->output,"%*s" , - config->csv_output ?0 :-25 , -perf_evsel__name (counter)); - -if (counter->cgrp) -fprintf (config->output,"%s%s" , - config->csv_sep, counter->cgrp->name); - -if (!config->csv_output) -pm (config, &os,NULL ,NULL ,"" ,0 ); -print_noise (config, counter, noise); -print_running (config, run, ena); -if (config->csv_output) -pm (config, &os,NULL ,NULL ,"" ,0 ); -return ; - } - -if (!config->metric_only) -abs_printout (config, id, nr, counter, uval); - - out.print_metric = pm; - out.new_line = nl; - out.ctx = &os; - out.force_header = false; - -if (config->csv_output && !config->metric_only) { -print_noise (config, counter, noise); -print_running (config, run, ena); - } - -perf_stat__print_shadow_stats (config, counter, uval, -first_shadow_cpu (config, counter, id), - &out, &config->metric_events, st); -if (!config->csv_output && !config->metric_only) { -print_noise (config, counter, noise); -print_running (config, run, ena); - } -} - -static void aggr_update_shadow (struct perf_stat_config *config, -struct perf_evlist *evlist) -{ -int cpu, s2, id, s; -u64 val; -struct perf_evsel *counter; - -for (s =0 ; s < config->aggr_map->nr; s++) { - id = config->aggr_map->map[s]; -evlist__for_each_entry (evlist, counter) { - val =0 ; -for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - s2 = config->aggr_get_id (config, evlist->cpus, cpu); -if (s2 != id) -continue ; - val +=perf_counts (counter->counts, cpu,0 )->val; - } -perf_stat__update_shadow_stats (counter, val, -first_shadow_cpu (config, counter, id), - &rt_stat); - } - } -} - -static void uniquify_event_name (struct perf_evsel *counter) -{ -char *new_name; -char *config; - -if (counter->uniquified_name || - !counter->pmu_name || !strncmp (counter->name, counter->pmu_name, -strlen (counter->pmu_name))) -return ; - - config =strchr (counter->name,'/' ); -if (config) { -if (asprintf (&new_name, -"%s%s" , counter->pmu_name, config) >0 ) { -free (counter->name); - counter->name = new_name; - } - }else { -if (asprintf (&new_name, -"%s [%s]" , counter->name, counter->pmu_name) >0 ) { -free (counter->name); - counter->name = new_name; - } - } - - counter->uniquified_name = true; -} - -static void collect_all_aliases (struct perf_stat_config *config,struct perf_evsel *counter, -void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data, -bool first), -void *data) -{ -struct perf_evlist *evlist = counter->evlist; -struct perf_evsel *alias; - - alias =list_prepare_entry (counter, &(evlist->entries), node); - list_for_each_entry_continue (alias, &evlist->entries, node) { -if (strcmp (perf_evsel__name (alias),perf_evsel__name (counter)) || - alias->scale != counter->scale || - alias->cgrp != counter->cgrp || -strcmp (alias->unit, counter->unit) || -perf_evsel__is_clock (alias) !=perf_evsel__is_clock (counter)) -break ; - alias->merged_stat = true; -cb (config, alias, data, false); - } -} - -static bool collect_data (struct perf_stat_config *config,struct perf_evsel *counter, -void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data, -bool first), -void *data) -{ -if (counter->merged_stat) -return false; -cb (config, counter, data, true); -if (config->no_merge) -uniquify_event_name (counter); -else if (counter->auto_merge_stats) -collect_all_aliases (config, counter, cb, data); -return true; -} - -struct aggr_data { -u64 ena, run, val; -int id; -int nr; -int cpu; -}; - -static void aggr_cb (struct perf_stat_config *config, -struct perf_evsel *counter,void *data,bool first) -{ -struct aggr_data *ad = data; -int cpu, s2; - -for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { -struct perf_counts_values *counts; - - s2 = config->aggr_get_id (config,perf_evsel__cpus (counter), cpu); -if (s2 != ad->id) -continue ; -if (first) - ad->nr++; - counts =perf_counts (counter->counts, cpu,0 ); -/* -* When any result is bad, make them all to give -* consistent output in interval mode. -*/ -if (counts->ena ==0 || counts->run ==0 || - counter->counts->scaled ==-1 ) { - ad->ena =0 ; - ad->run =0 ; -break ; - } - ad->val += counts->val; - ad->ena += counts->ena; - ad->run += counts->run; - } -} - -static void print_aggr (struct perf_stat_config *config, -struct perf_evlist *evlist, -char *prefix) -{ -bool metric_only = config->metric_only; -FILE *output = config->output; -struct perf_evsel *counter; -int s, id, nr; -double uval; -u64 ena, run, val; -bool first; - -if (!(config->aggr_map || config->aggr_get_id)) -return ; - -aggr_update_shadow (config, evlist); - -/* -* With metric_only everything is on a single line. -* Without each counter has its own line. -*/ -for (s =0 ; s < config->aggr_map->nr; s++) { -struct aggr_data ad; -if (prefix && metric_only) -fprintf (output,"%s" , prefix); - - ad.id = id = config->aggr_map->map[s]; - first = true; -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; - - ad.val = ad.ena = ad.run =0 ; - ad.nr =0 ; -if (!collect_data (config, counter, aggr_cb, &ad)) -continue ; - nr = ad.nr; - ena = ad.ena; - run = ad.run; - val = ad.val; -if (first && metric_only) { - first = false; -aggr_printout (config, counter, id, nr); - } -if (prefix && !metric_only) -fprintf (output,"%s" , prefix); - - uval = val * counter->scale; -printout (config, id, nr, counter, uval, prefix, - run, ena,1.0 , &rt_stat); -if (!metric_only) -fputc ('\n' , output); - } -if (metric_only) -fputc ('\n' , output); - } -} - -static int cmp_val (const void *a,const void *b) -{ -return ((struct perf_aggr_thread_value *)b)->val - - ((struct perf_aggr_thread_value *)a)->val; -} - -static struct perf_aggr_thread_value *sort_aggr_thread ( -struct perf_evsel *counter, -int nthreads,int ncpus, -int *ret, -struct target *_target) -{ -int cpu, thread, i =0 ; -double uval; -struct perf_aggr_thread_value *buf; - - buf =calloc (nthreads,sizeof (struct perf_aggr_thread_value )); -if (!buf) -return NULL ; - -for (thread =0 ; thread < nthreads; thread++) { -u64 ena =0 , run =0 , val =0 ; - -for (cpu =0 ; cpu < ncpus; cpu++) { - val +=perf_counts (counter->counts, cpu, thread)->val; - ena +=perf_counts (counter->counts, cpu, thread)->ena; - run +=perf_counts (counter->counts, cpu, thread)->run; - } - - uval = val * counter->scale; - -/* -* Skip value 0 when enabling --per-thread globally, -* otherwise too many 0 output. -*/ -if (uval ==0.0 &&target__has_per_thread (_target)) -continue ; - - buf[i].counter = counter; - buf[i].id = thread; - buf[i].uval = uval; - buf[i].val = val; - buf[i].run = run; - buf[i].ena = ena; - i++; - } - -qsort (buf, i,sizeof (struct perf_aggr_thread_value ), cmp_val); - -if (ret) - *ret = i; - -return buf; -} - -static void print_aggr_thread (struct perf_stat_config *config, -struct target *_target, -struct perf_evsel *counter,char *prefix) -{ -FILE *output = config->output; -int nthreads =thread_map__nr (counter->threads); -int ncpus =cpu_map__nr (counter->cpus); -int thread, sorted_threads, id; -struct perf_aggr_thread_value *buf; - - buf =sort_aggr_thread (counter, nthreads, ncpus, &sorted_threads, _target); -if (!buf) { -perror ("cannot sort aggr thread" ); -return ; - } - -for (thread =0 ; thread < sorted_threads; thread++) { -if (prefix) -fprintf (output,"%s" , prefix); - - id = buf[thread].id; -if (config->stats) -printout (config, id,0 , buf[thread].counter, buf[thread].uval, - prefix, buf[thread].run, buf[thread].ena,1.0 , - &config->stats[id]); -else -printout (config, id,0 , buf[thread].counter, buf[thread].uval, - prefix, buf[thread].run, buf[thread].ena,1.0 , - &rt_stat); -fputc ('\n' , output); - } - -free (buf); -} - -struct caggr_data { -double avg, avg_enabled, avg_running; -}; - -static void counter_aggr_cb (struct perf_stat_config *config__maybe_unused , -struct perf_evsel *counter,void *data, -bool first__maybe_unused ) -{ -struct caggr_data *cd = data; -struct perf_stat_evsel *ps = counter->stats; - - cd->avg +=avg_stats (&ps->res_stats[0 ]); - cd->avg_enabled +=avg_stats (&ps->res_stats[1 ]); - cd->avg_running +=avg_stats (&ps->res_stats[2 ]); -} - -/* -* Print out the results of a single counter: -* aggregated counts in system-wide mode -*/ -static void print_counter_aggr (struct perf_stat_config *config, -struct perf_evsel *counter,char *prefix) -{ -bool metric_only = config->metric_only; -FILE *output = config->output; -double uval; -struct caggr_data cd = { .avg =0.0 }; - -if (!collect_data (config, counter, counter_aggr_cb, &cd)) -return ; - -if (prefix && !metric_only) -fprintf (output,"%s" , prefix); - - uval = cd.avg * counter->scale; -printout (config,-1 ,0 , counter, uval, prefix, cd.avg_running, cd.avg_enabled, - cd.avg, &rt_stat); -if (!metric_only) -fprintf (output,"\n" ); -} - -static void counter_cb (struct perf_stat_config *config__maybe_unused , -struct perf_evsel *counter,void *data, -bool first__maybe_unused ) -{ -struct aggr_data *ad = data; - - ad->val +=perf_counts (counter->counts, ad->cpu,0 )->val; - ad->ena +=perf_counts (counter->counts, ad->cpu,0 )->ena; - ad->run +=perf_counts (counter->counts, ad->cpu,0 )->run; -} - -/* -* Print out the results of a single counter: -* does not use aggregated count in system-wide -*/ -static void print_counter (struct perf_stat_config *config, -struct perf_evsel *counter,char *prefix) -{ -FILE *output = config->output; -u64 ena, run, val; -double uval; -int cpu; - -for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { -struct aggr_data ad = { .cpu = cpu }; - -if (!collect_data (config, counter, counter_cb, &ad)) -return ; - val = ad.val; - ena = ad.ena; - run = ad.run; - -if (prefix) -fprintf (output,"%s" , prefix); - - uval = val * counter->scale; -printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , - &rt_stat); - -fputc ('\n' , output); - } -} - -static void print_no_aggr_metric (struct perf_stat_config *config, -struct perf_evlist *evlist, -char *prefix) -{ -int cpu; -int nrcpus =0 ; -struct perf_evsel *counter; -u64 ena, run, val; -double uval; - - nrcpus = evlist->cpus->nr; -for (cpu =0 ; cpu < nrcpus; cpu++) { -bool first = true; - -if (prefix) -fputs (prefix, config->output); -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -if (first) { -aggr_printout (config, counter, cpu,0 ); - first = false; - } - val =perf_counts (counter->counts, cpu,0 )->val; - ena =perf_counts (counter->counts, cpu,0 )->ena; - run =perf_counts (counter->counts, cpu,0 )->run; - - uval = val * counter->scale; -printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , - &rt_stat); - } -fputc ('\n' , config->output); - } -} - -static int aggr_header_lens[] = { - [AGGR_CORE ] =18 , - [AGGR_SOCKET ] =12 , - [AGGR_NONE ] =6 , - [AGGR_THREAD ] =24 , - [AGGR_GLOBAL ] =0 , -}; - -static const char *aggr_header_csv[] = { - [AGGR_CORE ] ="core,cpus," , - [AGGR_SOCKET ] ="socket,cpus" , - [AGGR_NONE ] ="cpu," , - [AGGR_THREAD ] ="comm-pid," , - [AGGR_GLOBAL ] ="" -}; - -static void print_metric_headers (struct perf_stat_config *config, -struct perf_evlist *evlist, -const char *prefix,bool no_indent) -{ -struct perf_stat_output_ctx out; -struct perf_evsel *counter; -struct outstate os = { - .fh = config->output - }; - -if (prefix) -fprintf (config->output,"%s" , prefix); - -if (!config->csv_output && !no_indent) -fprintf (config->output,"%*s" , - aggr_header_lens[config->aggr_mode],"" ); -if (config->csv_output) { -if (config->interval) -fputs ("time," , config->output); -fputs (aggr_header_csv[config->aggr_mode], config->output); - } - -/* Print metrics headers only */ -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; - os.evsel = counter; - out.ctx = &os; - out.print_metric = print_metric_header; - out.new_line = new_line_metric; - out.force_header = true; - os.evsel = counter; -perf_stat__print_shadow_stats (config, counter,0 , -0 , - &out, - &config->metric_events, - &rt_stat); - } -fputc ('\n' , config->output); -} - -static void print_interval (struct perf_stat_config *config, -struct perf_evlist *evlist, -char *prefix,struct timespec *ts) -{ -bool metric_only = config->metric_only; -unsigned int unit_width = config->unit_width; -FILE *output = config->output; -static int num_print_interval; - -if (config->interval_clear) -puts (CONSOLE_CLEAR ); - -sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, config->csv_sep); - -if ((num_print_interval ==0 && !config->csv_output) || config->interval_clear) { -switch (config->aggr_mode) { -case AGGR_SOCKET : -fprintf (output,"# time socket cpus" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_CORE : -fprintf (output,"# time core cpus" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_NONE : -fprintf (output,"# time CPU " ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_THREAD : -fprintf (output,"# time comm-pid" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_GLOBAL : -default : -fprintf (output,"# time" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -case AGGR_UNSET : -break ; - } - } - -if ((num_print_interval ==0 || config->interval_clear) && metric_only) -print_metric_headers (config, evlist," " , true); -if (++num_print_interval ==25 ) - num_print_interval =0 ; -} - -static void print_header (struct perf_stat_config *config, -struct target *_target, -int argc,const char **argv) -{ -FILE *output = config->output; -int i; - -fflush (stdout); - -if (!config->csv_output) { -fprintf (output,"\n" ); -fprintf (output," Performance counter stats for " ); -if (_target->system_wide) -fprintf (output,"\'system wide" ); -else if (_target->cpu_list) -fprintf (output,"\'CPU(s) %s" , _target->cpu_list); -else if (!target__has_task (_target)) { -fprintf (output,"\'%s" , argv ? argv[0 ] :"pipe" ); -for (i =1 ; argv && (i < argc); i++) -fprintf (output," %s" , argv[i]); - }else if (_target->pid) -fprintf (output,"process id \'%s" , _target->pid); -else -fprintf (output,"thread id \'%s" , _target->tid); - -fprintf (output,"\'" ); -if (config->run_count >1 ) -fprintf (output," (%d runs)" , config->run_count); -fprintf (output,":\n\n" ); - } -} - -static int get_precision (double num) -{ -if (num >1 ) -return 0 ; - -return lround (ceil (-log10 (num))); -} - -static void print_table (struct perf_stat_config *config, -FILE *output,int precision,double avg) -{ -char tmp[64 ]; -int idx, indent =0 ; - -scnprintf (tmp,64 ," %17.*f" , precision, avg); -while (tmp[indent] ==' ' ) - indent++; - -fprintf (output,"%*s# Table of individual measurements:\n" , indent,"" ); - -for (idx =0 ; idx < config->run_count; idx++) { -double run = (double ) config->walltime_run[idx] /NSEC_PER_SEC ; -int h, n =1 +abs ((int ) (100.0 * (run - avg)/run) /5 ); - -fprintf (output," %17.*f (%+.*f) " , - precision, run, precision, run - avg); - -for (h =0 ; h < n; h++) -fprintf (output,"#" ); - -fprintf (output,"\n" ); - } - -fprintf (output,"\n%*s# Final result:\n" , indent,"" ); -} - -static double timeval2double (struct timeval *t) -{ -return t->tv_sec + (double ) t->tv_usec/USEC_PER_SEC ; -} - -static void print_footer (struct perf_stat_config *config) -{ -double avg =avg_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ; -FILE *output = config->output; -int n; - -if (!config->null_run) -fprintf (output,"\n" ); - -if (config->run_count ==1 ) { -fprintf (output," %17.9f seconds time elapsed" , avg); - -if (config->ru_display) { -double ru_utime =timeval2double (&config->ru_data.ru_utime); -double ru_stime =timeval2double (&config->ru_data.ru_stime); - -fprintf (output,"\n\n" ); -fprintf (output," %17.9f seconds user\n" , ru_utime); -fprintf (output," %17.9f seconds sys\n" , ru_stime); - } - }else { -double sd =stddev_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ; -/* -* Display at most 2 more significant -* digits than the stddev inaccuracy. -*/ -int precision =get_precision (sd) +2 ; - -if (config->walltime_run_table) -print_table (config, output, precision, avg); - -fprintf (output," %17.*f +- %.*f seconds time elapsed" , - precision, avg, precision, sd); - -print_noise_pct (config, sd, avg); - } -fprintf (output,"\n\n" ); - -if (config->print_free_counters_hint && -sysctl__read_int ("kernel/nmi_watchdog" , &n) >=0 && - n >0 ) -fprintf (output, -"Some events weren't counted. Try disabling the NMI watchdog:\n" -" echo 0 > /proc/sys/kernel/nmi_watchdog\n" -" perf stat ...\n" -" echo 1 > /proc/sys/kernel/nmi_watchdog\n" ); - -if (config->print_mixed_hw_group_error) -fprintf (output, -"The events in group usually have to be from " -"the same PMU. Try reorganizing the group.\n" ); -} - -static void -perf_evlist__print_counters (struct perf_evlist *evlist, -struct perf_stat_config *config, -struct target *_target, -struct timespec *ts, -int argc,const char **argv) -{ -bool metric_only = config->metric_only; -int interval = config->interval; -struct perf_evsel *counter; -char buf[64 ], *prefix =NULL ; - -if (interval) -print_interval (config, evlist, prefix = buf, ts); -else -print_header (config, _target, argc, argv); - -if (metric_only) { -static int num_print_iv; - -if (num_print_iv ==0 && !interval) -print_metric_headers (config, evlist, prefix, false); -if (num_print_iv++ ==25 ) - num_print_iv =0 ; -if (config->aggr_mode ==AGGR_GLOBAL && prefix) -fprintf (config->output,"%s" , prefix); - } - -switch (config->aggr_mode) { -case AGGR_CORE : -case AGGR_SOCKET : -print_aggr (config, evlist, prefix); -break ; -case AGGR_THREAD : -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -print_aggr_thread (config, _target, counter, prefix); - } -break ; -case AGGR_GLOBAL : -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -print_counter_aggr (config, counter, prefix); - } -if (metric_only) -fputc ('\n' , config->output); -break ; -case AGGR_NONE : -if (metric_only) -print_no_aggr_metric (config, evlist, prefix); -else { -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -print_counter (config, counter, prefix); - } - } -break ; -case AGGR_UNSET : -default : -break ; - } - -if (!interval && !config->csv_output) -print_footer (config); - -fflush (config->output); -} -static void print_counters (struct timespec *ts,int argc,const char **argv) {/* Do not print anything if we record to the pipe. */
tools/perf/util/Build +1 -0
@@ -73,6 +73,7 @@ libperf-y += vdso.o libperf-y += counts.o libperf-y += stat.o libperf-y += stat-shadow.o +libperf-y += stat-display.o libperf-y += record.o libperf-y += srcline.o libperf-y += data.o
tools/perf/util/stat-display.c new file +1166 -0
1,166 lines not on this page · raw message
tools/perf/util/stat.h +6 -0
@@ -215,4 +215,10 @@ int perf_stat_synthesize_config(struct perf_stat_config *config,struct perf_evlist *evlist, perf_event__handler_t process, bool attrs); +void +perf_evlist__print_counters (struct perf_evlist *evlist, +struct perf_stat_config *config, +struct target *_target, +struct timespec *ts, +int argc,const char **argv);#endif
Signature · 1 line
2.17.1
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf stat: Move the display functions to stat-display.c
perf stat: Move the display functions to stat-display.c
Commit-ID: 088519f318be3a41d1afe8d628c4a1eb5a50b4c0 Gitweb: https://git.kernel.org/tip/088519f318be3a41d1afe8d628c4a1eb5a50b4c0 Author: Jiri Olsa <[email protected]> AuthorDate: Thu, 30 Aug 2018 08:32:52 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 30 Aug 2018 15:52:25 -0300
perf stat: Move the display functions to stat-display.c
Move perf_evlist__print_counters() with all its dependency functions to the stat-display.c object.
--- tools/perf/builtin-stat.c | 1150 --------------------------------------- tools/perf/util/Build | 1 + tools/perf/util/stat-display.c | 1166 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/stat.h | 6 + 4 files changed, 1173 insertions(+), 1150 deletions(-)
tools/perf/builtin-stat.c +0 -1150
@@ -88,8 +88,6 @@#include "sane_ctype.h" #define DEFAULT_SEPARATOR " " -#define CNTR_NOT_SUPPORTED "<not supported>" -#define CNTR_NOT_COUNTED "<not counted>"#define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi"static void print_counters (struct timespec *ts,int argc,const char **argv);
@@ -189,11 +187,6 @@ static struct perf_stat_config stat_config = { .big_num = true, }; -static bool is_duration_time (struct perf_evsel *evsel) -{ -return !strcmp (evsel->name,"duration_time" ); -} -static inline void diff_timespec (struct timespec *r,struct timespec *a,struct timespec *b) {
@@ -643,1149 +636,6 @@ static int run_perf_stat(int argc, const char **argv, int run_idx)return ret; } -static void print_running (struct perf_stat_config *config, -u64 run,u64 ena) -{ -if (config->csv_output) { -fprintf (config->output,"%s%" PRIu64"%s%.2f" , - config->csv_sep, - run, - config->csv_sep, - ena ?100.0 * run / ena :100.0 ); - }else if (run != ena) { -fprintf (config->output," (%.2f%%)" ,100.0 * run / ena); - } -} - -static void print_noise_pct (struct perf_stat_config *config, -double total,double avg) -{ -double pct =rel_stddev_stats (total, avg); - -if (config->csv_output) -fprintf (config->output,"%s%.2f%%" , config->csv_sep, pct); -else if (pct) -fprintf (config->output," ( +-%6.2f%% )" , pct); -} - -static void print_noise (struct perf_stat_config *config, -struct perf_evsel *evsel,double avg) -{ -struct perf_stat_evsel *ps; - -if (config->run_count ==1 ) -return ; - - ps = evsel->stats; -print_noise_pct (config,stddev_stats (&ps->res_stats[0 ]), avg); -} - -static void aggr_printout (struct perf_stat_config *config, -struct perf_evsel *evsel,int id,int nr) -{ -switch (config->aggr_mode) { -case AGGR_CORE : -fprintf (config->output,"S%d-C%*d%s%*d%s" , -cpu_map__id_to_socket (id), - config->csv_output ?0 :-8 , -cpu_map__id_to_cpu (id), - config->csv_sep, - config->csv_output ?0 :4 , - nr, - config->csv_sep); -break ; -case AGGR_SOCKET : -fprintf (config->output,"S%*d%s%*d%s" , - config->csv_output ?0 :-5 , - id, - config->csv_sep, - config->csv_output ?0 :4 , - nr, - config->csv_sep); -break ; -case AGGR_NONE : -fprintf (config->output,"CPU%*d%s" , - config->csv_output ?0 :-4 , -perf_evsel__cpus (evsel)->map[id], config->csv_sep); -break ; -case AGGR_THREAD : -fprintf (config->output,"%*s-%*d%s" , - config->csv_output ?0 :16 , -thread_map__comm (evsel->threads, id), - config->csv_output ?0 :-8 , -thread_map__pid (evsel->threads, id), - config->csv_sep); -break ; -case AGGR_GLOBAL : -case AGGR_UNSET : -default : -break ; - } -} - -struct outstate { -FILE *fh; -bool newline; -const char *prefix; -int nfields; -int id, nr; -struct perf_evsel *evsel; -}; - -#define METRIC_LEN 35 - -static void new_line_std (struct perf_stat_config *config__maybe_unused , -void *ctx) -{ -struct outstate *os = ctx; - - os->newline = true; -} - -static void do_new_line_std (struct perf_stat_config *config, -struct outstate *os) -{ -fputc ('\n' , os->fh); -fputs (os->prefix, os->fh); -aggr_printout (config, os->evsel, os->id, os->nr); -if (config->aggr_mode ==AGGR_NONE ) -fprintf (os->fh," " ); -fprintf (os->fh," " ); -} - -static void print_metric_std (struct perf_stat_config *config, -void *ctx,const char *color,const char *fmt, -const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -int n; -bool newline = os->newline; - - os->newline = false; - -if (unit ==NULL || fmt ==NULL ) { -fprintf (out,"%-*s" ,METRIC_LEN ,"" ); -return ; - } - -if (newline) -do_new_line_std (config, os); - - n =fprintf (out," # " ); -if (color) - n +=color_fprintf (out, color, fmt, val); -else - n +=fprintf (out, fmt, val); -fprintf (out," %-*s" ,METRIC_LEN - n -1 , unit); -} - -static void new_line_csv (struct perf_stat_config *config,void *ctx) -{ -struct outstate *os = ctx; -int i; - -fputc ('\n' , os->fh); -if (os->prefix) -fprintf (os->fh,"%s%s" , os->prefix, config->csv_sep); -aggr_printout (config, os->evsel, os->id, os->nr); -for (i =0 ; i < os->nfields; i++) -fputs (config->csv_sep, os->fh); -} - -static void print_metric_csv (struct perf_stat_config *config__maybe_unused , -void *ctx, -const char *color__maybe_unused , -const char *fmt,const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -char buf[64 ], *vals, *ends; - -if (unit ==NULL || fmt ==NULL ) { -fprintf (out,"%s%s" , config->csv_sep, config->csv_sep); -return ; - } -snprintf (buf,sizeof (buf), fmt, val); - ends = vals =ltrim (buf); -while (isdigit (*ends) || *ends =='.' ) - ends++; - *ends =0 ; -while (isspace (*unit)) - unit++; -fprintf (out,"%s%s%s%s" , config->csv_sep, vals, config->csv_sep, unit); -} - -/* Filter out some columns that don't work well in metrics only mode */ - -static bool valid_only_metric (const char *unit) -{ -if (!unit) -return false; -if (strstr (unit,"/sec" ) || -strstr (unit,"hz" ) || -strstr (unit,"Hz" ) || -strstr (unit,"CPUs utilized" )) -return false; -return true; -} - -static const char *fixunit (char *buf,struct perf_evsel *evsel, -const char *unit) -{ -if (!strncmp (unit,"of all" ,6 )) { -snprintf (buf,1024 ,"%s %s" ,perf_evsel__name (evsel), - unit); -return buf; - } -return unit; -} - -static void print_metric_only (struct perf_stat_config *config, -void *ctx,const char *color,const char *fmt, -const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -char buf[1024 ], str[1024 ]; -unsigned mlen = config->metric_only_len; - -if (!valid_only_metric (unit)) -return ; - unit =fixunit (buf, os->evsel, unit); -if (mlen <strlen (unit)) - mlen =strlen (unit) +1 ; - -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 (struct perf_stat_config *config__maybe_unused , -void *ctx,const char *color__maybe_unused , -const char *fmt, -const char *unit,double val) -{ -struct outstate *os = ctx; -FILE *out = os->fh; -char buf[64 ], *vals, *ends; -char tbuf[1024 ]; - -if (!valid_only_metric (unit)) -return ; - unit =fixunit (tbuf, os->evsel, unit); -snprintf (buf,sizeof buf, fmt, val); - ends = vals =ltrim (buf); -while (isdigit (*ends) || *ends =='.' ) - ends++; - *ends =0 ; -fprintf (out,"%s%s" , vals, config->csv_sep); -} - -static void new_line_metric (struct perf_stat_config *config__maybe_unused , -void *ctx__maybe_unused ) -{ -} - -static void print_metric_header (struct perf_stat_config *config, -void *ctx,const char *color__maybe_unused , -const char *fmt__maybe_unused , -const char *unit,double val__maybe_unused ) -{ -struct outstate *os = ctx; -char tbuf[1024 ]; - -if (!valid_only_metric (unit)) -return ; - unit =fixunit (tbuf, os->evsel, unit); -if (config->csv_output) -fprintf (os->fh,"%s%s" , unit, config->csv_sep); -else -fprintf (os->fh,"%*s " , config->metric_only_len, unit); -} - -static int first_shadow_cpu (struct perf_stat_config *config, -struct perf_evsel *evsel,int id) -{ -struct perf_evlist *evlist = evsel->evlist; -int i; - -if (!config->aggr_get_id) -return 0 ; - -if (config->aggr_mode ==AGGR_NONE ) -return id; - -if (config->aggr_mode ==AGGR_GLOBAL ) -return 0 ; - -for (i =0 ; i <perf_evsel__nr_cpus (evsel); i++) { -int cpu2 =perf_evsel__cpus (evsel)->map[i]; - -if (config->aggr_get_id (config, evlist->cpus, cpu2) == id) -return cpu2; - } -return 0 ; -} - -static void abs_printout (struct perf_stat_config *config, -int id,int nr,struct perf_evsel *evsel,double avg) -{ -FILE *output = config->output; -double sc = evsel->scale; -const char *fmt; - -if (config->csv_output) { - fmt =floor (sc) != sc ?"%.2f%s" :"%.0f%s" ; - }else { -if (config->big_num) - fmt =floor (sc) != sc ?"%'18.2f%s" :"%'18.0f%s" ; -else - fmt =floor (sc) != sc ?"%18.2f%s" :"%18.0f%s" ; - } - -aggr_printout (config, evsel, id, nr); - -fprintf (output, fmt, avg, config->csv_sep); - -if (evsel->unit) -fprintf (output,"%-*s%s" , - config->csv_output ?0 : config->unit_width, - evsel->unit, config->csv_sep); - -fprintf (output,"%-*s" , config->csv_output ?0 :25 ,perf_evsel__name (evsel)); - -if (evsel->cgrp) -fprintf (output,"%s%s" , config->csv_sep, evsel->cgrp->name); -} - -static bool is_mixed_hw_group (struct perf_evsel *counter) -{ -struct perf_evlist *evlist = counter->evlist; -u32 pmu_type = counter->attr.type; -struct perf_evsel *pos; - -if (counter->nr_members <2 ) -return false; - -evlist__for_each_entry (evlist, pos) { -/* software events can be part of any hardware group */ -if (pos->attr.type ==PERF_TYPE_SOFTWARE ) -continue ; -if (pmu_type ==PERF_TYPE_SOFTWARE ) { - pmu_type = pos->attr.type; -continue ; - } -if (pmu_type != pos->attr.type) -return true; - } - -return false; -} - -static void printout (struct perf_stat_config *config,int id,int nr, -struct perf_evsel *counter,double uval, -char *prefix,u64 run,u64 ena,double noise, -struct runtime_stat *st) -{ -struct perf_stat_output_ctx out; -struct outstate os = { - .fh = config->output, - .prefix = prefix ? prefix :"" , - .id = id, - .nr = nr, - .evsel = counter, - }; -print_metric_t pm = print_metric_std; -new_line_t nl; - -if (config->metric_only) { - nl = new_line_metric; -if (config->csv_output) - pm = print_metric_only_csv; -else - pm = print_metric_only; - }else - nl = new_line_std; - -if (config->csv_output && !config->metric_only) { -static int aggr_fields[] = { - [AGGR_GLOBAL ] =0 , - [AGGR_THREAD ] =1 , - [AGGR_NONE ] =1 , - [AGGR_SOCKET ] =2 , - [AGGR_CORE ] =2 , - }; - - pm = print_metric_csv; - nl = new_line_csv; - os.nfields =3 ; - os.nfields += aggr_fields[config->aggr_mode]; -if (counter->cgrp) - os.nfields++; - } -if (run ==0 || ena ==0 || counter->counts->scaled ==-1 ) { -if (config->metric_only) { -pm (config, &os,NULL ,"" ,"" ,0 ); -return ; - } -aggr_printout (config, counter, id, nr); - -fprintf (config->output,"%*s%s" , - config->csv_output ?0 :18 , - counter->supported ?CNTR_NOT_COUNTED :CNTR_NOT_SUPPORTED , - config->csv_sep); - -if (counter->supported) { - config->print_free_counters_hint =1 ; -if (is_mixed_hw_group (counter)) - config->print_mixed_hw_group_error =1 ; - } - -fprintf (config->output,"%-*s%s" , - config->csv_output ?0 : config->unit_width, - counter->unit, config->csv_sep); - -fprintf (config->output,"%*s" , - config->csv_output ?0 :-25 , -perf_evsel__name (counter)); - -if (counter->cgrp) -fprintf (config->output,"%s%s" , - config->csv_sep, counter->cgrp->name); - -if (!config->csv_output) -pm (config, &os,NULL ,NULL ,"" ,0 ); -print_noise (config, counter, noise); -print_running (config, run, ena); -if (config->csv_output) -pm (config, &os,NULL ,NULL ,"" ,0 ); -return ; - } - -if (!config->metric_only) -abs_printout (config, id, nr, counter, uval); - - out.print_metric = pm; - out.new_line = nl; - out.ctx = &os; - out.force_header = false; - -if (config->csv_output && !config->metric_only) { -print_noise (config, counter, noise); -print_running (config, run, ena); - } - -perf_stat__print_shadow_stats (config, counter, uval, -first_shadow_cpu (config, counter, id), - &out, &config->metric_events, st); -if (!config->csv_output && !config->metric_only) { -print_noise (config, counter, noise); -print_running (config, run, ena); - } -} - -static void aggr_update_shadow (struct perf_stat_config *config, -struct perf_evlist *evlist) -{ -int cpu, s2, id, s; -u64 val; -struct perf_evsel *counter; - -for (s =0 ; s < config->aggr_map->nr; s++) { - id = config->aggr_map->map[s]; -evlist__for_each_entry (evlist, counter) { - val =0 ; -for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { - s2 = config->aggr_get_id (config, evlist->cpus, cpu); -if (s2 != id) -continue ; - val +=perf_counts (counter->counts, cpu,0 )->val; - } -perf_stat__update_shadow_stats (counter, val, -first_shadow_cpu (config, counter, id), - &rt_stat); - } - } -} - -static void uniquify_event_name (struct perf_evsel *counter) -{ -char *new_name; -char *config; - -if (counter->uniquified_name || - !counter->pmu_name || !strncmp (counter->name, counter->pmu_name, -strlen (counter->pmu_name))) -return ; - - config =strchr (counter->name,'/' ); -if (config) { -if (asprintf (&new_name, -"%s%s" , counter->pmu_name, config) >0 ) { -free (counter->name); - counter->name = new_name; - } - }else { -if (asprintf (&new_name, -"%s [%s]" , counter->name, counter->pmu_name) >0 ) { -free (counter->name); - counter->name = new_name; - } - } - - counter->uniquified_name = true; -} - -static void collect_all_aliases (struct perf_stat_config *config,struct perf_evsel *counter, -void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data, -bool first), -void *data) -{ -struct perf_evlist *evlist = counter->evlist; -struct perf_evsel *alias; - - alias =list_prepare_entry (counter, &(evlist->entries), node); - list_for_each_entry_continue (alias, &evlist->entries, node) { -if (strcmp (perf_evsel__name (alias),perf_evsel__name (counter)) || - alias->scale != counter->scale || - alias->cgrp != counter->cgrp || -strcmp (alias->unit, counter->unit) || -perf_evsel__is_clock (alias) !=perf_evsel__is_clock (counter)) -break ; - alias->merged_stat = true; -cb (config, alias, data, false); - } -} - -static bool collect_data (struct perf_stat_config *config,struct perf_evsel *counter, -void (*cb)(struct perf_stat_config *config,struct perf_evsel *counter,void *data, -bool first), -void *data) -{ -if (counter->merged_stat) -return false; -cb (config, counter, data, true); -if (config->no_merge) -uniquify_event_name (counter); -else if (counter->auto_merge_stats) -collect_all_aliases (config, counter, cb, data); -return true; -} - -struct aggr_data { -u64 ena, run, val; -int id; -int nr; -int cpu; -}; - -static void aggr_cb (struct perf_stat_config *config, -struct perf_evsel *counter,void *data,bool first) -{ -struct aggr_data *ad = data; -int cpu, s2; - -for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { -struct perf_counts_values *counts; - - s2 = config->aggr_get_id (config,perf_evsel__cpus (counter), cpu); -if (s2 != ad->id) -continue ; -if (first) - ad->nr++; - counts =perf_counts (counter->counts, cpu,0 ); -/* -* When any result is bad, make them all to give -* consistent output in interval mode. -*/ -if (counts->ena ==0 || counts->run ==0 || - counter->counts->scaled ==-1 ) { - ad->ena =0 ; - ad->run =0 ; -break ; - } - ad->val += counts->val; - ad->ena += counts->ena; - ad->run += counts->run; - } -} - -static void print_aggr (struct perf_stat_config *config, -struct perf_evlist *evlist, -char *prefix) -{ -bool metric_only = config->metric_only; -FILE *output = config->output; -struct perf_evsel *counter; -int s, id, nr; -double uval; -u64 ena, run, val; -bool first; - -if (!(config->aggr_map || config->aggr_get_id)) -return ; - -aggr_update_shadow (config, evlist); - -/* -* With metric_only everything is on a single line. -* Without each counter has its own line. -*/ -for (s =0 ; s < config->aggr_map->nr; s++) { -struct aggr_data ad; -if (prefix && metric_only) -fprintf (output,"%s" , prefix); - - ad.id = id = config->aggr_map->map[s]; - first = true; -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; - - ad.val = ad.ena = ad.run =0 ; - ad.nr =0 ; -if (!collect_data (config, counter, aggr_cb, &ad)) -continue ; - nr = ad.nr; - ena = ad.ena; - run = ad.run; - val = ad.val; -if (first && metric_only) { - first = false; -aggr_printout (config, counter, id, nr); - } -if (prefix && !metric_only) -fprintf (output,"%s" , prefix); - - uval = val * counter->scale; -printout (config, id, nr, counter, uval, prefix, - run, ena,1.0 , &rt_stat); -if (!metric_only) -fputc ('\n' , output); - } -if (metric_only) -fputc ('\n' , output); - } -} - -static int cmp_val (const void *a,const void *b) -{ -return ((struct perf_aggr_thread_value *)b)->val - - ((struct perf_aggr_thread_value *)a)->val; -} - -static struct perf_aggr_thread_value *sort_aggr_thread ( -struct perf_evsel *counter, -int nthreads,int ncpus, -int *ret, -struct target *_target) -{ -int cpu, thread, i =0 ; -double uval; -struct perf_aggr_thread_value *buf; - - buf =calloc (nthreads,sizeof (struct perf_aggr_thread_value )); -if (!buf) -return NULL ; - -for (thread =0 ; thread < nthreads; thread++) { -u64 ena =0 , run =0 , val =0 ; - -for (cpu =0 ; cpu < ncpus; cpu++) { - val +=perf_counts (counter->counts, cpu, thread)->val; - ena +=perf_counts (counter->counts, cpu, thread)->ena; - run +=perf_counts (counter->counts, cpu, thread)->run; - } - - uval = val * counter->scale; - -/* -* Skip value 0 when enabling --per-thread globally, -* otherwise too many 0 output. -*/ -if (uval ==0.0 &&target__has_per_thread (_target)) -continue ; - - buf[i].counter = counter; - buf[i].id = thread; - buf[i].uval = uval; - buf[i].val = val; - buf[i].run = run; - buf[i].ena = ena; - i++; - } - -qsort (buf, i,sizeof (struct perf_aggr_thread_value ), cmp_val); - -if (ret) - *ret = i; - -return buf; -} - -static void print_aggr_thread (struct perf_stat_config *config, -struct target *_target, -struct perf_evsel *counter,char *prefix) -{ -FILE *output = config->output; -int nthreads =thread_map__nr (counter->threads); -int ncpus =cpu_map__nr (counter->cpus); -int thread, sorted_threads, id; -struct perf_aggr_thread_value *buf; - - buf =sort_aggr_thread (counter, nthreads, ncpus, &sorted_threads, _target); -if (!buf) { -perror ("cannot sort aggr thread" ); -return ; - } - -for (thread =0 ; thread < sorted_threads; thread++) { -if (prefix) -fprintf (output,"%s" , prefix); - - id = buf[thread].id; -if (config->stats) -printout (config, id,0 , buf[thread].counter, buf[thread].uval, - prefix, buf[thread].run, buf[thread].ena,1.0 , - &config->stats[id]); -else -printout (config, id,0 , buf[thread].counter, buf[thread].uval, - prefix, buf[thread].run, buf[thread].ena,1.0 , - &rt_stat); -fputc ('\n' , output); - } - -free (buf); -} - -struct caggr_data { -double avg, avg_enabled, avg_running; -}; - -static void counter_aggr_cb (struct perf_stat_config *config__maybe_unused , -struct perf_evsel *counter,void *data, -bool first__maybe_unused ) -{ -struct caggr_data *cd = data; -struct perf_stat_evsel *ps = counter->stats; - - cd->avg +=avg_stats (&ps->res_stats[0 ]); - cd->avg_enabled +=avg_stats (&ps->res_stats[1 ]); - cd->avg_running +=avg_stats (&ps->res_stats[2 ]); -} - -/* -* Print out the results of a single counter: -* aggregated counts in system-wide mode -*/ -static void print_counter_aggr (struct perf_stat_config *config, -struct perf_evsel *counter,char *prefix) -{ -bool metric_only = config->metric_only; -FILE *output = config->output; -double uval; -struct caggr_data cd = { .avg =0.0 }; - -if (!collect_data (config, counter, counter_aggr_cb, &cd)) -return ; - -if (prefix && !metric_only) -fprintf (output,"%s" , prefix); - - uval = cd.avg * counter->scale; -printout (config,-1 ,0 , counter, uval, prefix, cd.avg_running, cd.avg_enabled, - cd.avg, &rt_stat); -if (!metric_only) -fprintf (output,"\n" ); -} - -static void counter_cb (struct perf_stat_config *config__maybe_unused , -struct perf_evsel *counter,void *data, -bool first__maybe_unused ) -{ -struct aggr_data *ad = data; - - ad->val +=perf_counts (counter->counts, ad->cpu,0 )->val; - ad->ena +=perf_counts (counter->counts, ad->cpu,0 )->ena; - ad->run +=perf_counts (counter->counts, ad->cpu,0 )->run; -} - -/* -* Print out the results of a single counter: -* does not use aggregated count in system-wide -*/ -static void print_counter (struct perf_stat_config *config, -struct perf_evsel *counter,char *prefix) -{ -FILE *output = config->output; -u64 ena, run, val; -double uval; -int cpu; - -for (cpu =0 ; cpu <perf_evsel__nr_cpus (counter); cpu++) { -struct aggr_data ad = { .cpu = cpu }; - -if (!collect_data (config, counter, counter_cb, &ad)) -return ; - val = ad.val; - ena = ad.ena; - run = ad.run; - -if (prefix) -fprintf (output,"%s" , prefix); - - uval = val * counter->scale; -printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , - &rt_stat); - -fputc ('\n' , output); - } -} - -static void print_no_aggr_metric (struct perf_stat_config *config, -struct perf_evlist *evlist, -char *prefix) -{ -int cpu; -int nrcpus =0 ; -struct perf_evsel *counter; -u64 ena, run, val; -double uval; - - nrcpus = evlist->cpus->nr; -for (cpu =0 ; cpu < nrcpus; cpu++) { -bool first = true; - -if (prefix) -fputs (prefix, config->output); -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -if (first) { -aggr_printout (config, counter, cpu,0 ); - first = false; - } - val =perf_counts (counter->counts, cpu,0 )->val; - ena =perf_counts (counter->counts, cpu,0 )->ena; - run =perf_counts (counter->counts, cpu,0 )->run; - - uval = val * counter->scale; -printout (config, cpu,0 , counter, uval, prefix, run, ena,1.0 , - &rt_stat); - } -fputc ('\n' , config->output); - } -} - -static int aggr_header_lens[] = { - [AGGR_CORE ] =18 , - [AGGR_SOCKET ] =12 , - [AGGR_NONE ] =6 , - [AGGR_THREAD ] =24 , - [AGGR_GLOBAL ] =0 , -}; - -static const char *aggr_header_csv[] = { - [AGGR_CORE ] ="core,cpus," , - [AGGR_SOCKET ] ="socket,cpus" , - [AGGR_NONE ] ="cpu," , - [AGGR_THREAD ] ="comm-pid," , - [AGGR_GLOBAL ] ="" -}; - -static void print_metric_headers (struct perf_stat_config *config, -struct perf_evlist *evlist, -const char *prefix,bool no_indent) -{ -struct perf_stat_output_ctx out; -struct perf_evsel *counter; -struct outstate os = { - .fh = config->output - }; - -if (prefix) -fprintf (config->output,"%s" , prefix); - -if (!config->csv_output && !no_indent) -fprintf (config->output,"%*s" , - aggr_header_lens[config->aggr_mode],"" ); -if (config->csv_output) { -if (config->interval) -fputs ("time," , config->output); -fputs (aggr_header_csv[config->aggr_mode], config->output); - } - -/* Print metrics headers only */ -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; - os.evsel = counter; - out.ctx = &os; - out.print_metric = print_metric_header; - out.new_line = new_line_metric; - out.force_header = true; - os.evsel = counter; -perf_stat__print_shadow_stats (config, counter,0 , -0 , - &out, - &config->metric_events, - &rt_stat); - } -fputc ('\n' , config->output); -} - -static void print_interval (struct perf_stat_config *config, -struct perf_evlist *evlist, -char *prefix,struct timespec *ts) -{ -bool metric_only = config->metric_only; -unsigned int unit_width = config->unit_width; -FILE *output = config->output; -static int num_print_interval; - -if (config->interval_clear) -puts (CONSOLE_CLEAR ); - -sprintf (prefix,"%6lu.%09lu%s" , ts->tv_sec, ts->tv_nsec, config->csv_sep); - -if ((num_print_interval ==0 && !config->csv_output) || config->interval_clear) { -switch (config->aggr_mode) { -case AGGR_SOCKET : -fprintf (output,"# time socket cpus" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_CORE : -fprintf (output,"# time core cpus" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_NONE : -fprintf (output,"# time CPU " ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_THREAD : -fprintf (output,"# time comm-pid" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -break ; -case AGGR_GLOBAL : -default : -fprintf (output,"# time" ); -if (!metric_only) -fprintf (output," counts %*s events\n" , unit_width,"unit" ); -case AGGR_UNSET : -break ; - } - } - -if ((num_print_interval ==0 || config->interval_clear) && metric_only) -print_metric_headers (config, evlist," " , true); -if (++num_print_interval ==25 ) - num_print_interval =0 ; -} - -static void print_header (struct perf_stat_config *config, -struct target *_target, -int argc,const char **argv) -{ -FILE *output = config->output; -int i; - -fflush (stdout); - -if (!config->csv_output) { -fprintf (output,"\n" ); -fprintf (output," Performance counter stats for " ); -if (_target->system_wide) -fprintf (output,"\'system wide" ); -else if (_target->cpu_list) -fprintf (output,"\'CPU(s) %s" , _target->cpu_list); -else if (!target__has_task (_target)) { -fprintf (output,"\'%s" , argv ? argv[0 ] :"pipe" ); -for (i =1 ; argv && (i < argc); i++) -fprintf (output," %s" , argv[i]); - }else if (_target->pid) -fprintf (output,"process id \'%s" , _target->pid); -else -fprintf (output,"thread id \'%s" , _target->tid); - -fprintf (output,"\'" ); -if (config->run_count >1 ) -fprintf (output," (%d runs)" , config->run_count); -fprintf (output,":\n\n" ); - } -} - -static int get_precision (double num) -{ -if (num >1 ) -return 0 ; - -return lround (ceil (-log10 (num))); -} - -static void print_table (struct perf_stat_config *config, -FILE *output,int precision,double avg) -{ -char tmp[64 ]; -int idx, indent =0 ; - -scnprintf (tmp,64 ," %17.*f" , precision, avg); -while (tmp[indent] ==' ' ) - indent++; - -fprintf (output,"%*s# Table of individual measurements:\n" , indent,"" ); - -for (idx =0 ; idx < config->run_count; idx++) { -double run = (double ) config->walltime_run[idx] /NSEC_PER_SEC ; -int h, n =1 +abs ((int ) (100.0 * (run - avg)/run) /5 ); - -fprintf (output," %17.*f (%+.*f) " , - precision, run, precision, run - avg); - -for (h =0 ; h < n; h++) -fprintf (output,"#" ); - -fprintf (output,"\n" ); - } - -fprintf (output,"\n%*s# Final result:\n" , indent,"" ); -} - -static double timeval2double (struct timeval *t) -{ -return t->tv_sec + (double ) t->tv_usec/USEC_PER_SEC ; -} - -static void print_footer (struct perf_stat_config *config) -{ -double avg =avg_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ; -FILE *output = config->output; -int n; - -if (!config->null_run) -fprintf (output,"\n" ); - -if (config->run_count ==1 ) { -fprintf (output," %17.9f seconds time elapsed" , avg); - -if (config->ru_display) { -double ru_utime =timeval2double (&config->ru_data.ru_utime); -double ru_stime =timeval2double (&config->ru_data.ru_stime); - -fprintf (output,"\n\n" ); -fprintf (output," %17.9f seconds user\n" , ru_utime); -fprintf (output," %17.9f seconds sys\n" , ru_stime); - } - }else { -double sd =stddev_stats (config->walltime_nsecs_stats) /NSEC_PER_SEC ; -/* -* Display at most 2 more significant -* digits than the stddev inaccuracy. -*/ -int precision =get_precision (sd) +2 ; - -if (config->walltime_run_table) -print_table (config, output, precision, avg); - -fprintf (output," %17.*f +- %.*f seconds time elapsed" , - precision, avg, precision, sd); - -print_noise_pct (config, sd, avg); - } -fprintf (output,"\n\n" ); - -if (config->print_free_counters_hint && -sysctl__read_int ("kernel/nmi_watchdog" , &n) >=0 && - n >0 ) -fprintf (output, -"Some events weren't counted. Try disabling the NMI watchdog:\n" -" echo 0 > /proc/sys/kernel/nmi_watchdog\n" -" perf stat ...\n" -" echo 1 > /proc/sys/kernel/nmi_watchdog\n" ); - -if (config->print_mixed_hw_group_error) -fprintf (output, -"The events in group usually have to be from " -"the same PMU. Try reorganizing the group.\n" ); -} - -static void -perf_evlist__print_counters (struct perf_evlist *evlist, -struct perf_stat_config *config, -struct target *_target, -struct timespec *ts, -int argc,const char **argv) -{ -bool metric_only = config->metric_only; -int interval = config->interval; -struct perf_evsel *counter; -char buf[64 ], *prefix =NULL ; - -if (interval) -print_interval (config, evlist, prefix = buf, ts); -else -print_header (config, _target, argc, argv); - -if (metric_only) { -static int num_print_iv; - -if (num_print_iv ==0 && !interval) -print_metric_headers (config, evlist, prefix, false); -if (num_print_iv++ ==25 ) - num_print_iv =0 ; -if (config->aggr_mode ==AGGR_GLOBAL && prefix) -fprintf (config->output,"%s" , prefix); - } - -switch (config->aggr_mode) { -case AGGR_CORE : -case AGGR_SOCKET : -print_aggr (config, evlist, prefix); -break ; -case AGGR_THREAD : -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -print_aggr_thread (config, _target, counter, prefix); - } -break ; -case AGGR_GLOBAL : -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -print_counter_aggr (config, counter, prefix); - } -if (metric_only) -fputc ('\n' , config->output); -break ; -case AGGR_NONE : -if (metric_only) -print_no_aggr_metric (config, evlist, prefix); -else { -evlist__for_each_entry (evlist, counter) { -if (is_duration_time (counter)) -continue ; -print_counter (config, counter, prefix); - } - } -break ; -case AGGR_UNSET : -default : -break ; - } - -if (!interval && !config->csv_output) -print_footer (config); - -fflush (config->output); -} -static void print_counters (struct timespec *ts,int argc,const char **argv) {/* Do not print anything if we record to the pipe. */
tools/perf/util/Build +1 -0
@@ -73,6 +73,7 @@ libperf-y += vdso.o libperf-y += counts.o libperf-y += stat.o libperf-y += stat-shadow.o +libperf-y += stat-display.o libperf-y += record.o libperf-y += srcline.o libperf-y += data.o
tools/perf/util/stat-display.c new file +1166 -0
1,166 lines not on this page · raw message
tools/perf/util/stat.h +6 -0
@@ -215,4 +215,10 @@ int perf_stat_synthesize_config(struct perf_stat_config *config,struct perf_evlist *evlist, perf_event__handler_t process, bool attrs); +void +perf_evlist__print_counters (struct perf_evlist *evlist, +struct perf_stat_config *config, +struct target *_target, +struct timespec *ts, +int argc,const char **argv);#endif
Em Thu, Aug 30, 2018 at 08:32:09AM +0200, Jiri Olsa escreveu:
Quoted 6 lines
hi,
while going for the ability to store/display stat data in perf record/top I ended up with bunch of generic patches that make some of the stat functions standalone and simplify/reduce thebuiltin-stat.ccode.
Quoted 6 lines
This patchset mostly separates the display functions into separate object, plus several other functions.
Also available in here:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/fixes
Thanks, applied,
- Arnaldo