1 // SPDX-License-Identifier: GPL-2.0
6 #include "util/synthetic-events.h"
8 #include <linux/bitops.h>
9 #include <internal/cpumap.h>
14 static int process_event_mask(const struct perf_tool
*tool __maybe_unused
,
15 union perf_event
*event
,
16 struct perf_sample
*sample __maybe_unused
,
17 struct machine
*machine __maybe_unused
)
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 unsigned int long_size
;
24 data
= &map_event
->data
;
26 TEST_ASSERT_VAL("wrong type", data
->type
== PERF_CPU_MAP__MASK
);
28 long_size
= data
->mask32_data
.long_size
;
30 TEST_ASSERT_VAL("wrong long_size", long_size
== 4 || long_size
== 8);
32 TEST_ASSERT_VAL("wrong nr", data
->mask32_data
.nr
== 1);
34 TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(0, data
));
35 TEST_ASSERT_VAL("wrong cpu", !perf_record_cpu_map_data__test_bit(1, data
));
36 for (int i
= 2; i
<= 20; i
++)
37 TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(i
, data
));
39 map
= cpu_map__new_data(data
);
40 TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map
) == 20);
42 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map
, 0).cpu
== 0);
43 for (int i
= 2; i
<= 20; i
++)
44 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map
, i
- 1).cpu
== i
);
46 perf_cpu_map__put(map
);
50 static int process_event_cpus(const struct perf_tool
*tool __maybe_unused
,
51 union perf_event
*event
,
52 struct perf_sample
*sample __maybe_unused
,
53 struct machine
*machine __maybe_unused
)
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
;
59 data
= &map_event
->data
;
61 TEST_ASSERT_VAL("wrong type", data
->type
== PERF_CPU_MAP__CPUS
);
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);
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(perf_cpu_map__refcnt(map
)) == 1);
72 perf_cpu_map__put(map
);
76 static int process_event_range_cpus(const struct perf_tool
*tool __maybe_unused
,
77 union perf_event
*event
,
78 struct perf_sample
*sample __maybe_unused
,
79 struct machine
*machine __maybe_unused
)
81 struct perf_record_cpu_map
*map_event
= &event
->cpu_map
;
82 struct perf_record_cpu_map_data
*data
;
83 struct perf_cpu_map
*map
;
85 data
= &map_event
->data
;
87 TEST_ASSERT_VAL("wrong type", data
->type
== PERF_CPU_MAP__RANGE_CPUS
);
89 TEST_ASSERT_VAL("wrong any_cpu", data
->range_cpu_data
.any_cpu
== 0);
90 TEST_ASSERT_VAL("wrong start_cpu", data
->range_cpu_data
.start_cpu
== 1);
91 TEST_ASSERT_VAL("wrong end_cpu", data
->range_cpu_data
.end_cpu
== 256);
93 map
= cpu_map__new_data(data
);
94 TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map
) == 256);
95 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map
, 0).cpu
== 1);
96 TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__max(map
).cpu
== 256);
97 TEST_ASSERT_VAL("wrong refcnt", refcount_read(perf_cpu_map__refcnt(map
)) == 1);
98 perf_cpu_map__put(map
);
103 static int test__cpu_map_synthesize(struct test_suite
*test __maybe_unused
, int subtest __maybe_unused
)
105 struct perf_cpu_map
*cpus
;
107 /* This one is better stored in a mask. */
108 cpus
= perf_cpu_map__new("0,2-20");
110 TEST_ASSERT_VAL("failed to synthesize map",
111 !perf_event__synthesize_cpu_map(NULL
, cpus
, process_event_mask
, NULL
));
113 perf_cpu_map__put(cpus
);
115 /* This one is better stored in cpu values. */
116 cpus
= perf_cpu_map__new("1,256");
118 TEST_ASSERT_VAL("failed to synthesize map",
119 !perf_event__synthesize_cpu_map(NULL
, cpus
, process_event_cpus
, NULL
));
121 perf_cpu_map__put(cpus
);
123 /* This one is better stored as a range. */
124 cpus
= perf_cpu_map__new("1-256");
126 TEST_ASSERT_VAL("failed to synthesize map",
127 !perf_event__synthesize_cpu_map(NULL
, cpus
, process_event_range_cpus
, NULL
));
129 perf_cpu_map__put(cpus
);
133 static int cpu_map_print(const char *str
)
135 struct perf_cpu_map
*map
= perf_cpu_map__new(str
);
141 cpu_map__snprint(map
, buf
, sizeof(buf
));
142 perf_cpu_map__put(map
);
144 return !strcmp(buf
, str
);
147 static int test__cpu_map_print(struct test_suite
*test __maybe_unused
, int subtest __maybe_unused
)
149 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1"));
150 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5"));
151 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3,5,7,9,11,13,15,17,19,21-40"));
152 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("2-5"));
153 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37"));
154 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37"));
155 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1-10,12-20,22-30,32-40"));
159 static int test__cpu_map_merge(struct test_suite
*test __maybe_unused
, int subtest __maybe_unused
)
161 struct perf_cpu_map
*a
= perf_cpu_map__new("4,2,1");
162 struct perf_cpu_map
*b
= perf_cpu_map__new("4,5,7");
163 struct perf_cpu_map
*c
= perf_cpu_map__merge(a
, b
);
166 TEST_ASSERT_VAL("failed to merge map: bad nr", perf_cpu_map__nr(c
) == 5);
167 cpu_map__snprint(c
, buf
, sizeof(buf
));
168 TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf
, "1-2,4-5,7"));
169 perf_cpu_map__put(b
);
170 perf_cpu_map__put(c
);
174 static int __test__cpu_map_intersect(const char *lhs
, const char *rhs
, int nr
, const char *expected
)
176 struct perf_cpu_map
*a
= perf_cpu_map__new(lhs
);
177 struct perf_cpu_map
*b
= perf_cpu_map__new(rhs
);
178 struct perf_cpu_map
*c
= perf_cpu_map__intersect(a
, b
);
181 TEST_ASSERT_EQUAL("failed to intersect map: bad nr", perf_cpu_map__nr(c
), nr
);
182 cpu_map__snprint(c
, buf
, sizeof(buf
));
183 TEST_ASSERT_VAL("failed to intersect map: bad result", !strcmp(buf
, expected
));
184 perf_cpu_map__put(a
);
185 perf_cpu_map__put(b
);
186 perf_cpu_map__put(c
);
190 static int test__cpu_map_intersect(struct test_suite
*test __maybe_unused
,
191 int subtest __maybe_unused
)
195 ret
= __test__cpu_map_intersect("4,2,1", "4,5,7", 1, "4");
198 ret
= __test__cpu_map_intersect("1-8", "6-9", 3, "6-8");
201 ret
= __test__cpu_map_intersect("1-8,12-20", "6-9,15", 4, "6-8,15");
204 ret
= __test__cpu_map_intersect("4,2,1", "1", 1, "1");
207 ret
= __test__cpu_map_intersect("1", "4,2,1", 1, "1");
210 ret
= __test__cpu_map_intersect("1", "1", 1, "1");
214 static int test__cpu_map_equal(struct test_suite
*test __maybe_unused
, int subtest __maybe_unused
)
216 struct perf_cpu_map
*any
= perf_cpu_map__new_any_cpu();
217 struct perf_cpu_map
*one
= perf_cpu_map__new("1");
218 struct perf_cpu_map
*two
= perf_cpu_map__new("2");
219 struct perf_cpu_map
*empty
= perf_cpu_map__intersect(one
, two
);
220 struct perf_cpu_map
*pair
= perf_cpu_map__new("1-2");
221 struct perf_cpu_map
*tmp
;
222 struct perf_cpu_map
*maps
[] = {empty
, any
, one
, two
, pair
};
224 for (size_t i
= 0; i
< ARRAY_SIZE(maps
); i
++) {
225 /* Maps equal themself. */
226 TEST_ASSERT_VAL("equal", perf_cpu_map__equal(maps
[i
], maps
[i
]));
227 for (size_t j
= 0; j
< ARRAY_SIZE(maps
); j
++) {
228 /* Maps dont't equal each other. */
231 TEST_ASSERT_VAL("not equal", !perf_cpu_map__equal(maps
[i
], maps
[j
]));
235 /* Maps equal made maps. */
236 tmp
= perf_cpu_map__merge(perf_cpu_map__get(one
), two
);
237 TEST_ASSERT_VAL("pair", perf_cpu_map__equal(pair
, tmp
));
238 perf_cpu_map__put(tmp
);
240 tmp
= perf_cpu_map__intersect(pair
, one
);
241 TEST_ASSERT_VAL("one", perf_cpu_map__equal(one
, tmp
));
242 perf_cpu_map__put(tmp
);
244 for (size_t i
= 0; i
< ARRAY_SIZE(maps
); i
++)
245 perf_cpu_map__put(maps
[i
]);
250 static struct test_case tests__cpu_map
[] = {
251 TEST_CASE("Synthesize cpu map", cpu_map_synthesize
),
252 TEST_CASE("Print cpu map", cpu_map_print
),
253 TEST_CASE("Merge cpu map", cpu_map_merge
),
254 TEST_CASE("Intersect cpu map", cpu_map_intersect
),
255 TEST_CASE("Equal cpu map", cpu_map_equal
),
259 struct test_suite suite__cpu_map
= {
261 .test_cases
= tests__cpu_map
,