cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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}