threadmap.c (2261B)
1// SPDX-License-Identifier: GPL-2.0 2#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}