Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Change cpu_map__fprintf output

Display cpu map in standard list form. (perf report -D output on perf stat data).

before:
0x590 [0x18]: PERF_RECORD_CPU_MAP nr: 4 cpus: 0, 1, 2, 3

after:
0x590 [0x18]: PERF_RECORD_CPU_MAP: 0-3

Adding automated testcase.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1467113345-12669-4-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
a24020e6 7fa9b8fb

+79 -7
+4
tools/perf/tests/builtin-test.c
··· 214 214 .func = test__backward_ring_buffer, 215 215 }, 216 216 { 217 + .desc = "Test cpu map print", 218 + .func = test__cpu_map_print, 219 + }, 220 + { 217 221 .func = NULL, 218 222 }, 219 223 };
+24
tools/perf/tests/cpumap.c
··· 86 86 cpu_map__put(cpus); 87 87 return 0; 88 88 } 89 + 90 + static int cpu_map_print(const char *str) 91 + { 92 + struct cpu_map *map = cpu_map__new(str); 93 + char buf[100]; 94 + 95 + if (!map) 96 + return -1; 97 + 98 + cpu_map__snprint(map, buf, sizeof(buf)); 99 + return !strcmp(buf, str); 100 + } 101 + 102 + int test__cpu_map_print(int subtest __maybe_unused) 103 + { 104 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); 105 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); 106 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3,5,7,9,11,13,15,17,19,21-40")); 107 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("2-5")); 108 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); 109 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); 110 + TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1-10,12-20,22-30,32-40")); 111 + return 0; 112 + }
+1
tools/perf/tests/tests.h
··· 87 87 int test__event_update(int subtest); 88 88 int test__event_times(int subtest); 89 89 int test__backward_ring_buffer(int subtest); 90 + int test__cpu_map_print(int subtest); 90 91 91 92 #if defined(__arm__) || defined(__aarch64__) 92 93 #ifdef HAVE_DWARF_UNWIND_SUPPORT
+48 -6
tools/perf/util/cpumap.c
··· 236 236 237 237 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp) 238 238 { 239 - int i; 240 - size_t printed = fprintf(fp, "%d cpu%s: ", 241 - map->nr, map->nr > 1 ? "s" : ""); 242 - for (i = 0; i < map->nr; ++i) 243 - printed += fprintf(fp, "%s%d", i ? ", " : "", map->map[i]); 239 + #define BUFSIZE 1024 240 + char buf[BUFSIZE]; 244 241 245 - return printed + fprintf(fp, "\n"); 242 + cpu_map__snprint(map, buf, sizeof(buf)); 243 + return fprintf(fp, "%s\n", buf); 244 + #undef BUFSIZE 246 245 } 247 246 248 247 struct cpu_map *cpu_map__dummy_new(void) ··· 597 598 } 598 599 599 600 return false; 601 + } 602 + 603 + size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size) 604 + { 605 + int i, cpu, start = -1; 606 + bool first = true; 607 + size_t ret = 0; 608 + 609 + #define COMMA first ? "" : "," 610 + 611 + for (i = 0; i < map->nr + 1; i++) { 612 + bool last = i == map->nr; 613 + 614 + cpu = last ? INT_MAX : map->map[i]; 615 + 616 + if (start == -1) { 617 + start = i; 618 + if (last) { 619 + ret += snprintf(buf + ret, size - ret, 620 + "%s%d", COMMA, 621 + map->map[i]); 622 + } 623 + } else if (((i - start) != (cpu - map->map[start])) || last) { 624 + int end = i - 1; 625 + 626 + if (start == end) { 627 + ret += snprintf(buf + ret, size - ret, 628 + "%s%d", COMMA, 629 + map->map[start]); 630 + } else { 631 + ret += snprintf(buf + ret, size - ret, 632 + "%s%d-%d", COMMA, 633 + map->map[start], map->map[end]); 634 + } 635 + first = false; 636 + start = i; 637 + } 638 + } 639 + 640 + #undef COMMA 641 + 642 + pr_debug("cpumask list: %s\n", buf); 643 + return ret; 600 644 }
+1
tools/perf/util/cpumap.h
··· 19 19 struct cpu_map *cpu_map__dummy_new(void); 20 20 struct cpu_map *cpu_map__new_data(struct cpu_map_data *data); 21 21 struct cpu_map *cpu_map__read(FILE *file); 22 + size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size); 22 23 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); 23 24 int cpu_map__get_socket_id(int cpu); 24 25 int cpu_map__get_socket(struct cpu_map *map, int idx, void *data);
+1 -1
tools/perf/util/event.c
··· 1092 1092 struct cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data); 1093 1093 size_t ret; 1094 1094 1095 - ret = fprintf(fp, " nr: "); 1095 + ret = fprintf(fp, ": "); 1096 1096 1097 1097 if (cpus) 1098 1098 ret += cpu_map__fprintf(cpus, fp);