tools/lib/perf/evsel.c

Source file repositories/reference/linux-study-clean/tools/lib/perf/evsel.c

File Facts

System
Linux kernel
Corpus path
tools/lib/perf/evsel.c
Extension
.c
Size
13852 bytes
Lines
619
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (empty_cpu_map == NULL) {
			empty_cpu_map = perf_cpu_map__new_any_cpu();
			if (empty_cpu_map == NULL)
				return -ENOMEM;
		}

		cpus = empty_cpu_map;
	}

	if (threads == NULL) {
		static struct perf_thread_map *empty_thread_map;

		if (empty_thread_map == NULL) {
			empty_thread_map = perf_thread_map__new_dummy();
			if (empty_thread_map == NULL)
				return -ENOMEM;
		}

		threads = empty_thread_map;
	}

	if (evsel->fd == NULL &&
	    perf_evsel__alloc_fd(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0)
		return -ENOMEM;

	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
		for (thread = 0; thread < threads->nr; thread++) {
			int fd, group_fd, *evsel_fd;

			evsel_fd = FD(evsel, idx, thread);
			if (evsel_fd == NULL) {
				err = -EINVAL;
				goto out;
			}

			err = get_group_fd(evsel, idx, thread, &group_fd);
			if (err < 0)
				goto out;

			fd = sys_perf_event_open(&evsel->attr,
						 threads->map[thread].pid,
						 cpu, group_fd, 0);

			if (fd < 0) {
				err = -errno;
				goto out;
			}

			*evsel_fd = fd;
		}
	}
out:
	if (err)
		perf_evsel__close(evsel);

	return err;
}

static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu_map_idx)
{
	int thread;

	for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
		int *fd = FD(evsel, cpu_map_idx, thread);

		if (fd && *fd >= 0) {
			close(*fd);
			*fd = -1;
		}
	}
}

void perf_evsel__close_fd(struct perf_evsel *evsel)
{
	for (int idx = 0; idx < xyarray__max_x(evsel->fd); idx++)
		perf_evsel__close_fd_cpu(evsel, idx);
}

void perf_evsel__free_fd(struct perf_evsel *evsel)
{
	xyarray__delete(evsel->fd);
	evsel->fd = NULL;
}

void perf_evsel__close(struct perf_evsel *evsel)
{
	if (evsel->fd == NULL)
		return;

	perf_evsel__close_fd(evsel);

Annotation

Implementation Notes