Loading tools/lib/perf/evlist.c +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, if (!evsel->own_cpus || evlist->has_user_cpus) { perf_cpu_map__put(evsel->cpus); evsel->cpus = perf_cpu_map__get(evlist->cpus); } else if (!evsel->system_wide && perf_cpu_map__empty(evlist->cpus)) { perf_cpu_map__put(evsel->cpus); evsel->cpus = perf_cpu_map__get(evlist->cpus); } else if (evsel->cpus != evsel->own_cpus) { perf_cpu_map__put(evsel->cpus); evsel->cpus = perf_cpu_map__get(evsel->own_cpus); Loading tools/perf/util/metricgroup.c +56 −19 Original line number Diff line number Diff line Loading @@ -150,6 +150,18 @@ static void expr_ids__exit(struct expr_ids *ids) free(ids->id[i].id); } static bool contains_event(struct evsel **metric_events, int num_events, const char *event_name) { int i; for (i = 0; i < num_events; i++) { if (!strcmp(metric_events[i]->name, event_name)) return true; } return false; } /** * Find a group of events in perf_evlist that correspond to those from a parsed * metric expression. Note, as find_evsel_group is called in the same order as Loading Loading @@ -180,7 +192,11 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, int i = 0, matched_events = 0, events_to_match; const int idnum = (int)hashmap__size(&pctx->ids); /* duration_time is grouped separately. */ /* * duration_time is always grouped separately, when events are grouped * (ie has_constraint is false) then ignore it in the matching loop and * add it to metric_events at the end. */ if (!has_constraint && hashmap__find(&pctx->ids, "duration_time", (void **)&val_ptr)) events_to_match = idnum - 1; Loading @@ -207,23 +223,20 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, sizeof(struct evsel *) * idnum); current_leader = ev->leader; } if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) { if (has_constraint) { /* * Events aren't grouped, ensure the same event * isn't matched from two groups. * Check for duplicate events with the same name. For example, * uncore_imc/cas_count_read/ will turn into 6 events per socket * on skylakex. Only the first such event is placed in * metric_events. If events aren't grouped then this also * ensures that the same event in different sibling groups * aren't both added to metric_events. */ for (i = 0; i < matched_events; i++) { if (!strcmp(ev->name, metric_events[i]->name)) { break; } } if (i != matched_events) if (contains_event(metric_events, matched_events, ev->name)) continue; } /* Does this event belong to the parse context? */ if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) metric_events[matched_events++] = ev; } if (matched_events == events_to_match) break; } Loading @@ -239,7 +252,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, } if (matched_events != idnum) { /* Not whole match */ /* Not a whole match */ return NULL; } Loading @@ -247,8 +260,32 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, for (i = 0; i < idnum; i++) { ev = metric_events[i]; /* Don't free the used events. */ set_bit(ev->idx, evlist_used); /* * The metric leader points to the identically named event in * metric_events. */ ev->metric_leader = ev; /* * Mark two events with identical names in the same group (or * globally) as being in use as uncore events may be duplicated * for each pmu. Set the metric leader of such events to be the * event that appears in metric_events. */ evlist__for_each_entry_continue(perf_evlist, ev) { /* * If events are grouped then the search can terminate * when then group is left. */ if (!has_constraint && ev->leader != metric_events[i]->leader) break; if (!strcmp(metric_events[i]->name, ev->name)) { set_bit(ev->idx, evlist_used); ev->metric_leader = metric_events[i]; } } } return metric_events[0]; Loading tools/perf/util/parse-events.c +5 −3 Original line number Diff line number Diff line Loading @@ -353,18 +353,20 @@ __add_event(struct list_head *list, int *idx, const char *cpu_list) { struct evsel *evsel; struct perf_cpu_map *cpus = pmu ? pmu->cpus : struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) : cpu_list ? perf_cpu_map__new(cpu_list) : NULL; if (init_attr) event_attr_init(attr); evsel = evsel__new_idx(attr, *idx); if (!evsel) if (!evsel) { perf_cpu_map__put(cpus); return NULL; } (*idx)++; evsel->core.cpus = perf_cpu_map__get(cpus); evsel->core.cpus = cpus; evsel->core.own_cpus = perf_cpu_map__get(cpus); evsel->core.system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; Loading tools/perf/util/print_binary.c +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ int is_printable_array(char *p, unsigned int len) len--; for (i = 0; i < len; i++) { for (i = 0; i < len && p[i]; i++) { if (!isprint(p[i]) && !isspace(p[i])) return 0; } Loading Loading
tools/lib/perf/evlist.c +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, if (!evsel->own_cpus || evlist->has_user_cpus) { perf_cpu_map__put(evsel->cpus); evsel->cpus = perf_cpu_map__get(evlist->cpus); } else if (!evsel->system_wide && perf_cpu_map__empty(evlist->cpus)) { perf_cpu_map__put(evsel->cpus); evsel->cpus = perf_cpu_map__get(evlist->cpus); } else if (evsel->cpus != evsel->own_cpus) { perf_cpu_map__put(evsel->cpus); evsel->cpus = perf_cpu_map__get(evsel->own_cpus); Loading
tools/perf/util/metricgroup.c +56 −19 Original line number Diff line number Diff line Loading @@ -150,6 +150,18 @@ static void expr_ids__exit(struct expr_ids *ids) free(ids->id[i].id); } static bool contains_event(struct evsel **metric_events, int num_events, const char *event_name) { int i; for (i = 0; i < num_events; i++) { if (!strcmp(metric_events[i]->name, event_name)) return true; } return false; } /** * Find a group of events in perf_evlist that correspond to those from a parsed * metric expression. Note, as find_evsel_group is called in the same order as Loading Loading @@ -180,7 +192,11 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, int i = 0, matched_events = 0, events_to_match; const int idnum = (int)hashmap__size(&pctx->ids); /* duration_time is grouped separately. */ /* * duration_time is always grouped separately, when events are grouped * (ie has_constraint is false) then ignore it in the matching loop and * add it to metric_events at the end. */ if (!has_constraint && hashmap__find(&pctx->ids, "duration_time", (void **)&val_ptr)) events_to_match = idnum - 1; Loading @@ -207,23 +223,20 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, sizeof(struct evsel *) * idnum); current_leader = ev->leader; } if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) { if (has_constraint) { /* * Events aren't grouped, ensure the same event * isn't matched from two groups. * Check for duplicate events with the same name. For example, * uncore_imc/cas_count_read/ will turn into 6 events per socket * on skylakex. Only the first such event is placed in * metric_events. If events aren't grouped then this also * ensures that the same event in different sibling groups * aren't both added to metric_events. */ for (i = 0; i < matched_events; i++) { if (!strcmp(ev->name, metric_events[i]->name)) { break; } } if (i != matched_events) if (contains_event(metric_events, matched_events, ev->name)) continue; } /* Does this event belong to the parse context? */ if (hashmap__find(&pctx->ids, ev->name, (void **)&val_ptr)) metric_events[matched_events++] = ev; } if (matched_events == events_to_match) break; } Loading @@ -239,7 +252,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, } if (matched_events != idnum) { /* Not whole match */ /* Not a whole match */ return NULL; } Loading @@ -247,8 +260,32 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, for (i = 0; i < idnum; i++) { ev = metric_events[i]; /* Don't free the used events. */ set_bit(ev->idx, evlist_used); /* * The metric leader points to the identically named event in * metric_events. */ ev->metric_leader = ev; /* * Mark two events with identical names in the same group (or * globally) as being in use as uncore events may be duplicated * for each pmu. Set the metric leader of such events to be the * event that appears in metric_events. */ evlist__for_each_entry_continue(perf_evlist, ev) { /* * If events are grouped then the search can terminate * when then group is left. */ if (!has_constraint && ev->leader != metric_events[i]->leader) break; if (!strcmp(metric_events[i]->name, ev->name)) { set_bit(ev->idx, evlist_used); ev->metric_leader = metric_events[i]; } } } return metric_events[0]; Loading
tools/perf/util/parse-events.c +5 −3 Original line number Diff line number Diff line Loading @@ -353,18 +353,20 @@ __add_event(struct list_head *list, int *idx, const char *cpu_list) { struct evsel *evsel; struct perf_cpu_map *cpus = pmu ? pmu->cpus : struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) : cpu_list ? perf_cpu_map__new(cpu_list) : NULL; if (init_attr) event_attr_init(attr); evsel = evsel__new_idx(attr, *idx); if (!evsel) if (!evsel) { perf_cpu_map__put(cpus); return NULL; } (*idx)++; evsel->core.cpus = perf_cpu_map__get(cpus); evsel->core.cpus = cpus; evsel->core.own_cpus = perf_cpu_map__get(cpus); evsel->core.system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats; Loading
tools/perf/util/print_binary.c +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ int is_printable_array(char *p, unsigned int len) len--; for (i = 0; i < len; i++) { for (i = 0; i < len && p[i]; i++) { if (!isprint(p[i]) && !isspace(p[i])) return 0; } Loading