13ce311afSJiri Olsa // SPDX-License-Identifier: GPL-2.0
23ce311afSJiri Olsa #include <perf/threadmap.h>
33ce311afSJiri Olsa #include <stdlib.h>
43ce311afSJiri Olsa #include <linux/refcount.h>
53ce311afSJiri Olsa #include <internal/threadmap.h>
63ce311afSJiri Olsa #include <string.h>
73ce311afSJiri Olsa #include <asm/bug.h>
83ce311afSJiri Olsa #include <stdio.h>
93ce311afSJiri Olsa
perf_thread_map__reset(struct perf_thread_map * map,int start,int nr)103ce311afSJiri Olsa static void perf_thread_map__reset(struct perf_thread_map *map, int start, int nr)
113ce311afSJiri Olsa {
123ce311afSJiri Olsa size_t size = (nr - start) * sizeof(map->map[0]);
133ce311afSJiri Olsa
143ce311afSJiri Olsa memset(&map->map[start], 0, size);
153ce311afSJiri Olsa map->err_thread = -1;
163ce311afSJiri Olsa }
173ce311afSJiri Olsa
perf_thread_map__realloc(struct perf_thread_map * map,int nr)183ce311afSJiri Olsa struct perf_thread_map *perf_thread_map__realloc(struct perf_thread_map *map, int nr)
193ce311afSJiri Olsa {
203ce311afSJiri Olsa size_t size = sizeof(*map) + sizeof(map->map[0]) * nr;
213ce311afSJiri Olsa int start = map ? map->nr : 0;
223ce311afSJiri Olsa
233ce311afSJiri Olsa map = realloc(map, size);
243ce311afSJiri Olsa /*
253ce311afSJiri Olsa * We only realloc to add more items, let's reset new items.
263ce311afSJiri Olsa */
273ce311afSJiri Olsa if (map)
283ce311afSJiri Olsa perf_thread_map__reset(map, start, nr);
293ce311afSJiri Olsa
303ce311afSJiri Olsa return map;
313ce311afSJiri Olsa }
323ce311afSJiri Olsa
333ce311afSJiri Olsa #define thread_map__alloc(__nr) perf_thread_map__realloc(NULL, __nr)
343ce311afSJiri Olsa
perf_thread_map__set_pid(struct perf_thread_map * map,int idx,pid_t pid)3541415b8aSTzvetomir Stoyanov (VMware) void perf_thread_map__set_pid(struct perf_thread_map *map, int idx, pid_t pid)
363ce311afSJiri Olsa {
3741415b8aSTzvetomir Stoyanov (VMware) map->map[idx].pid = pid;
383ce311afSJiri Olsa }
393ce311afSJiri Olsa
perf_thread_map__comm(struct perf_thread_map * map,int idx)4041415b8aSTzvetomir Stoyanov (VMware) char *perf_thread_map__comm(struct perf_thread_map *map, int idx)
413ce311afSJiri Olsa {
4241415b8aSTzvetomir Stoyanov (VMware) return map->map[idx].comm;
433ce311afSJiri Olsa }
443ce311afSJiri Olsa
perf_thread_map__new_array(int nr_threads,pid_t * array)45*56dce868STzvetomir Stoyanov (VMware) struct perf_thread_map *perf_thread_map__new_array(int nr_threads, pid_t *array)
46*56dce868STzvetomir Stoyanov (VMware) {
47*56dce868STzvetomir Stoyanov (VMware) struct perf_thread_map *threads = thread_map__alloc(nr_threads);
48*56dce868STzvetomir Stoyanov (VMware) int i;
49*56dce868STzvetomir Stoyanov (VMware)
50*56dce868STzvetomir Stoyanov (VMware) if (!threads)
51*56dce868STzvetomir Stoyanov (VMware) return NULL;
52*56dce868STzvetomir Stoyanov (VMware)
53*56dce868STzvetomir Stoyanov (VMware) for (i = 0; i < nr_threads; i++)
54*56dce868STzvetomir Stoyanov (VMware) perf_thread_map__set_pid(threads, i, array ? array[i] : -1);
55*56dce868STzvetomir Stoyanov (VMware)
56*56dce868STzvetomir Stoyanov (VMware) threads->nr = nr_threads;
57*56dce868STzvetomir Stoyanov (VMware) refcount_set(&threads->refcnt, 1);
58*56dce868STzvetomir Stoyanov (VMware)
59*56dce868STzvetomir Stoyanov (VMware) return threads;
60*56dce868STzvetomir Stoyanov (VMware) }
61*56dce868STzvetomir Stoyanov (VMware)
perf_thread_map__new_dummy(void)623ce311afSJiri Olsa struct perf_thread_map *perf_thread_map__new_dummy(void)
633ce311afSJiri Olsa {
64*56dce868STzvetomir Stoyanov (VMware) return perf_thread_map__new_array(1, NULL);
653ce311afSJiri Olsa }
663ce311afSJiri Olsa
perf_thread_map__delete(struct perf_thread_map * threads)673ce311afSJiri Olsa static void perf_thread_map__delete(struct perf_thread_map *threads)
683ce311afSJiri Olsa {
693ce311afSJiri Olsa if (threads) {
703ce311afSJiri Olsa int i;
713ce311afSJiri Olsa
723ce311afSJiri Olsa WARN_ONCE(refcount_read(&threads->refcnt) != 0,
733ce311afSJiri Olsa "thread map refcnt unbalanced\n");
743ce311afSJiri Olsa for (i = 0; i < threads->nr; i++)
753ce311afSJiri Olsa free(perf_thread_map__comm(threads, i));
763ce311afSJiri Olsa free(threads);
773ce311afSJiri Olsa }
783ce311afSJiri Olsa }
793ce311afSJiri Olsa
perf_thread_map__get(struct perf_thread_map * map)803ce311afSJiri Olsa struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map)
813ce311afSJiri Olsa {
823ce311afSJiri Olsa if (map)
833ce311afSJiri Olsa refcount_inc(&map->refcnt);
843ce311afSJiri Olsa return map;
853ce311afSJiri Olsa }
863ce311afSJiri Olsa
perf_thread_map__put(struct perf_thread_map * map)873ce311afSJiri Olsa void perf_thread_map__put(struct perf_thread_map *map)
883ce311afSJiri Olsa {
893ce311afSJiri Olsa if (map && refcount_dec_and_test(&map->refcnt))
903ce311afSJiri Olsa perf_thread_map__delete(map);
913ce311afSJiri Olsa }
923ce311afSJiri Olsa
perf_thread_map__nr(struct perf_thread_map * threads)933ce311afSJiri Olsa int perf_thread_map__nr(struct perf_thread_map *threads)
943ce311afSJiri Olsa {
953ce311afSJiri Olsa return threads ? threads->nr : 1;
963ce311afSJiri Olsa }
973ce311afSJiri Olsa
perf_thread_map__pid(struct perf_thread_map * map,int idx)9841415b8aSTzvetomir Stoyanov (VMware) pid_t perf_thread_map__pid(struct perf_thread_map *map, int idx)
993ce311afSJiri Olsa {
10041415b8aSTzvetomir Stoyanov (VMware) return map->map[idx].pid;
1013ce311afSJiri Olsa }
102