1 // SPDX-License-Identifier: GPL-2.0 2 #include "tests.h" 3 #include <stdio.h> 4 #include "cpumap.h" 5 #include "event.h" 6 #include "util/synthetic-events.h" 7 #include <string.h> 8 #include <linux/bitops.h> 9 #include <perf/cpumap.h> 10 #include "debug.h" 11 12 struct machine; 13 14 static int process_event_mask(struct perf_tool *tool __maybe_unused, 15 union perf_event *event, 16 struct perf_sample *sample __maybe_unused, 17 struct machine *machine __maybe_unused) 18 { 19 struct perf_record_cpu_map *map_event = &event->cpu_map; 20 struct perf_record_cpu_map_data *data; 21 struct perf_cpu_map *map; 22 int i; 23 unsigned int long_size; 24 25 data = &map_event->data; 26 27 TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__MASK); 28 29 long_size = data->mask32_data.long_size; 30 31 TEST_ASSERT_VAL("wrong long_size", long_size == 4 || long_size == 8); 32 33 TEST_ASSERT_VAL("wrong nr", data->mask32_data.nr == 1); 34 35 for (i = 0; i < 20; i++) { 36 TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(i, data)); 37 } 38 39 map = cpu_map__new_data(data); 40 TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) == 20); 41 42 for (i = 0; i < 20; i++) { 43 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, i).cpu == i); 44 } 45 46 perf_cpu_map__put(map); 47 return 0; 48 } 49 50 static int process_event_cpus(struct perf_tool *tool __maybe_unused, 51 union perf_event *event, 52 struct perf_sample *sample __maybe_unused, 53 struct machine *machine __maybe_unused) 54 { 55 struct perf_record_cpu_map *map_event = &event->cpu_map; 56 struct perf_record_cpu_map_data *data; 57 struct perf_cpu_map *map; 58 59 data = &map_event->data; 60 61 TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__CPUS); 62 63 TEST_ASSERT_VAL("wrong nr", data->cpus_data.nr == 2); 64 TEST_ASSERT_VAL("wrong cpu", data->cpus_data.cpu[0] == 1); 65 TEST_ASSERT_VAL("wrong cpu", data->cpus_data.cpu[1] == 256); 66 67 map = cpu_map__new_data(data); 68 TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) == 2); 69 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu == 1); 70 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 1).cpu == 256); 71 TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); 72 perf_cpu_map__put(map); 73 return 0; 74 } 75 76 77 static int test__cpu_map_synthesize(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 78 { 79 struct perf_cpu_map *cpus; 80 81 /* This one is better stores in mask. */ 82 cpus = perf_cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); 83 84 TEST_ASSERT_VAL("failed to synthesize map", 85 !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); 86 87 perf_cpu_map__put(cpus); 88 89 /* This one is better stores in cpu values. */ 90 cpus = perf_cpu_map__new("1,256"); 91 92 TEST_ASSERT_VAL("failed to synthesize map", 93 !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); 94 95 perf_cpu_map__put(cpus); 96 return 0; 97 } 98 99 static int cpu_map_print(const char *str) 100 { 101 struct perf_cpu_map *map = perf_cpu_map__new(str); 102 char buf[100]; 103 104 if (!map) 105 return -1; 106 107 cpu_map__snprint(map, buf, sizeof(buf)); 108 perf_cpu_map__put(map); 109 110 return !strcmp(buf, str); 111 } 112 113 static int test__cpu_map_print(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 114 { 115 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); 116 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); 117 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3,5,7,9,11,13,15,17,19,21-40")); 118 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("2-5")); 119 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); 120 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); 121 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1-10,12-20,22-30,32-40")); 122 return 0; 123 } 124 125 static int test__cpu_map_merge(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 126 { 127 struct perf_cpu_map *a = perf_cpu_map__new("4,2,1"); 128 struct perf_cpu_map *b = perf_cpu_map__new("4,5,7"); 129 struct perf_cpu_map *c = perf_cpu_map__merge(a, b); 130 char buf[100]; 131 132 TEST_ASSERT_VAL("failed to merge map: bad nr", perf_cpu_map__nr(c) == 5); 133 cpu_map__snprint(c, buf, sizeof(buf)); 134 TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,7")); 135 perf_cpu_map__put(b); 136 perf_cpu_map__put(c); 137 return 0; 138 } 139 140 DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize); 141 DEFINE_SUITE("Print cpu map", cpu_map_print); 142 DEFINE_SUITE("Merge cpu map", cpu_map_merge); 143