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 10 static 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 18 struct 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 35 void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid) 36 { 37 map->map[thread].pid = pid; 38 } 39 40 char *perf_thread_map__comm(struct perf_thread_map *map, int thread) 41 { 42 return map->map[thread].comm; 43 } 44 45 struct perf_thread_map *perf_thread_map__new_dummy(void) 46 { 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; 55 } 56 57 static void perf_thread_map__delete(struct perf_thread_map *threads) 58 { 59 if (threads) { 60 int i; 61 62 WARN_ONCE(refcount_read(&threads->refcnt) != 0, 63 "thread map refcnt unbalanced\n"); 64 for (i = 0; i < threads->nr; i++) 65 free(perf_thread_map__comm(threads, i)); 66 free(threads); 67 } 68 } 69 70 struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map) 71 { 72 if (map) 73 refcount_inc(&map->refcnt); 74 return map; 75 } 76 77 void perf_thread_map__put(struct perf_thread_map *map) 78 { 79 if (map && refcount_dec_and_test(&map->refcnt)) 80 perf_thread_map__delete(map); 81 } 82 83 int perf_thread_map__nr(struct perf_thread_map *threads) 84 { 85 return threads ? threads->nr : 1; 86 } 87 88 pid_t perf_thread_map__pid(struct perf_thread_map *map, int thread) 89 { 90 return map->map[thread].pid; 91 } 92