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

libperf: Add API for allocating new thread map array

The existing API perf_thread_map__new_dummy() allocates new thread map
for one thread. I couldn't find a way to reallocate the map with more
threads, or to allocate a new map for more than one thread.

Having multiple threads in a thread map is essential for some use cases.
That's why a new API is proposed, which allocates a new thread map for
given number of threads: perf_thread_map__new_array()

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/linux-perf-users/20220221102628.43904-1-tz.stoyanov@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Tzvetomir Stoyanov (VMware) and committed by
Arnaldo Carvalho de Melo
56dce868 41415b8a

+62 -8
+1
tools/lib/perf/Documentation/libperf.txt
··· 62 62 struct perf_thread_map; 63 63 64 64 struct perf_thread_map *perf_thread_map__new_dummy(void); 65 + struct perf_thread_map *perf_thread_map__new_array(int nr_threads, pid_t *array); 65 66 66 67 void perf_thread_map__set_pid(struct perf_thread_map *map, int idx, pid_t pid); 67 68 char *perf_thread_map__comm(struct perf_thread_map *map, int idx);
+1
tools/lib/perf/include/perf/threadmap.h
··· 8 8 struct perf_thread_map; 9 9 10 10 LIBPERF_API struct perf_thread_map *perf_thread_map__new_dummy(void); 11 + LIBPERF_API struct perf_thread_map *perf_thread_map__new_array(int nr_threads, pid_t *array); 11 12 12 13 LIBPERF_API void perf_thread_map__set_pid(struct perf_thread_map *map, int idx, pid_t pid); 13 14 LIBPERF_API char *perf_thread_map__comm(struct perf_thread_map *map, int idx);
+1
tools/lib/perf/libperf.map
··· 12 12 perf_cpu_map__empty; 13 13 perf_cpu_map__max; 14 14 perf_cpu_map__has; 15 + perf_thread_map__new_array; 15 16 perf_thread_map__new_dummy; 16 17 perf_thread_map__set_pid; 17 18 perf_thread_map__comm;
+41
tools/lib/perf/tests/test-threadmap.c
··· 11 11 return vfprintf(stderr, fmt, ap); 12 12 } 13 13 14 + static int test_threadmap_array(int nr, pid_t *array) 15 + { 16 + struct perf_thread_map *threads; 17 + int i; 18 + 19 + threads = perf_thread_map__new_array(nr, array); 20 + __T("Failed to allocate new thread map", threads); 21 + 22 + __T("Unexpected number of threads", perf_thread_map__nr(threads) == nr); 23 + 24 + for (i = 0; i < nr; i++) { 25 + __T("Unexpected initial value of thread", 26 + perf_thread_map__pid(threads, i) == (array ? array[i] : -1)); 27 + } 28 + 29 + for (i = 1; i < nr; i++) 30 + perf_thread_map__set_pid(threads, i, i * 100); 31 + 32 + __T("Unexpected value of thread 0", 33 + perf_thread_map__pid(threads, 0) == (array ? array[0] : -1)); 34 + 35 + for (i = 1; i < nr; i++) { 36 + __T("Unexpected thread value", 37 + perf_thread_map__pid(threads, i) == i * 100); 38 + } 39 + 40 + perf_thread_map__put(threads); 41 + 42 + return 0; 43 + } 44 + 45 + #define THREADS_NR 10 14 46 int test_threadmap(int argc, char **argv) 15 47 { 16 48 struct perf_thread_map *threads; 49 + pid_t thr_array[THREADS_NR]; 50 + int i; 17 51 18 52 __T_START; 19 53 ··· 60 26 perf_thread_map__get(threads); 61 27 perf_thread_map__put(threads); 62 28 perf_thread_map__put(threads); 29 + 30 + test_threadmap_array(THREADS_NR, NULL); 31 + 32 + for (i = 0; i < THREADS_NR; i++) 33 + thr_array[i] = i + 100; 34 + 35 + test_threadmap_array(THREADS_NR, thr_array); 63 36 64 37 __T_END; 65 38 return tests_failed == 0 ? 0 : -1;
+18 -8
tools/lib/perf/threadmap.c
··· 42 42 return map->map[idx].comm; 43 43 } 44 44 45 + struct perf_thread_map *perf_thread_map__new_array(int nr_threads, pid_t *array) 46 + { 47 + struct perf_thread_map *threads = thread_map__alloc(nr_threads); 48 + int i; 49 + 50 + if (!threads) 51 + return NULL; 52 + 53 + for (i = 0; i < nr_threads; i++) 54 + perf_thread_map__set_pid(threads, i, array ? array[i] : -1); 55 + 56 + threads->nr = nr_threads; 57 + refcount_set(&threads->refcnt, 1); 58 + 59 + return threads; 60 + } 61 + 45 62 struct perf_thread_map *perf_thread_map__new_dummy(void) 46 63 { 47 - struct perf_thread_map *threads = thread_map__alloc(1); 48 - 49 - if (threads != NULL) { 50 - perf_thread_map__set_pid(threads, 0, -1); 51 - threads->nr = 1; 52 - refcount_set(&threads->refcnt, 1); 53 - } 54 - return threads; 64 + return perf_thread_map__new_array(1, NULL); 55 65 } 56 66 57 67 static void perf_thread_map__delete(struct perf_thread_map *threads)