102 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <perf/threadmap.h>3#include <stdlib.h>4#include <linux/refcount.h>5#include <internal/threadmap.h>6#include <string.h>7#include <asm/bug.h>8#include <stdio.h>9 10static void perf_thread_map__reset(struct perf_thread_map *map, int start, int nr)11{12 size_t size = (nr - start) * sizeof(map->map[0]);13 14 memset(&map->map[start], 0, size);15 map->err_thread = -1;16}17 18struct perf_thread_map *perf_thread_map__realloc(struct perf_thread_map *map, int nr)19{20 size_t size = sizeof(*map) + sizeof(map->map[0]) * nr;21 int start = map ? map->nr : 0;22 23 map = realloc(map, size);24 /*25 * We only realloc to add more items, let's reset new items.26 */27 if (map)28 perf_thread_map__reset(map, start, nr);29 30 return map;31}32 33#define thread_map__alloc(__nr) perf_thread_map__realloc(NULL, __nr)34 35void perf_thread_map__set_pid(struct perf_thread_map *map, int idx, pid_t pid)36{37 map->map[idx].pid = pid;38}39 40char *perf_thread_map__comm(struct perf_thread_map *map, int idx)41{42 return map->map[idx].comm;43}44 45struct 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 62struct perf_thread_map *perf_thread_map__new_dummy(void)63{64 return perf_thread_map__new_array(1, NULL);65}66 67static void perf_thread_map__delete(struct perf_thread_map *threads)68{69 if (threads) {70 int i;71 72 WARN_ONCE(refcount_read(&threads->refcnt) != 0,73 "thread map refcnt unbalanced\n");74 for (i = 0; i < threads->nr; i++)75 free(perf_thread_map__comm(threads, i));76 free(threads);77 }78}79 80struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map)81{82 if (map)83 refcount_inc(&map->refcnt);84 return map;85}86 87void perf_thread_map__put(struct perf_thread_map *map)88{89 if (map && refcount_dec_and_test(&map->refcnt))90 perf_thread_map__delete(map);91}92 93int perf_thread_map__nr(struct perf_thread_map *threads)94{95 return threads ? threads->nr : 1;96}97 98pid_t perf_thread_map__pid(struct perf_thread_map *map, int idx)99{100 return map->map[idx].pid;101}102