brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 0c1c1bd Raw
149 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2013, Michael Ellerman, IBM Corp.4 */5 6#define _GNU_SOURCE7#include <unistd.h>8#include <sys/syscall.h>9#include <string.h>10#include <stdio.h>11#include <stdbool.h>12#include <sys/ioctl.h>13 14#include "event.h"15 16 17int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,18		int group_fd, unsigned long flags)19{20	return syscall(__NR_perf_event_open, attr, pid, cpu,21			   group_fd, flags);22}23 24static void  __event_init_opts(struct event *e, u64 config,25			       int type, char *name, bool sampling)26{27	memset(e, 0, sizeof(*e));28 29	e->name = name;30 31	e->attr.type = type;32	e->attr.config = config;33	e->attr.size = sizeof(e->attr);34	/* This has to match the structure layout in the header */35	e->attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | \36				  PERF_FORMAT_TOTAL_TIME_RUNNING;37	if (sampling) {38		e->attr.sample_period = 1000;39		e->attr.sample_type = PERF_SAMPLE_REGS_INTR;40		e->attr.disabled = 1;41	}42}43 44void event_init_opts(struct event *e, u64 config, int type, char *name)45{46	__event_init_opts(e, config, type, name, false);47}48 49void event_init_named(struct event *e, u64 config, char *name)50{51	event_init_opts(e, config, PERF_TYPE_RAW, name);52}53 54void event_init(struct event *e, u64 config)55{56	event_init_opts(e, config, PERF_TYPE_RAW, "event");57}58 59void event_init_sampling(struct event *e, u64 config)60{61	__event_init_opts(e, config, PERF_TYPE_RAW, "event", true);62}63 64#define PERF_CURRENT_PID	065#define PERF_NO_PID		-166#define PERF_NO_CPU		-167#define PERF_NO_GROUP		-168 69int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd)70{71	e->fd = perf_event_open(&e->attr, pid, cpu, group_fd, 0);72	if (e->fd == -1) {73		perror("perf_event_open");74		return -1;75	}76 77	return 0;78}79 80int event_open_with_group(struct event *e, int group_fd)81{82	return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, group_fd);83}84 85int event_open_with_pid(struct event *e, pid_t pid)86{87	return event_open_with_options(e, pid, PERF_NO_CPU, PERF_NO_GROUP);88}89 90int event_open_with_cpu(struct event *e, int cpu)91{92	return event_open_with_options(e, PERF_NO_PID, cpu, PERF_NO_GROUP);93}94 95int event_open(struct event *e)96{97	return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, PERF_NO_GROUP);98}99 100void event_close(struct event *e)101{102	close(e->fd);103}104 105int event_enable(struct event *e)106{107	return ioctl(e->fd, PERF_EVENT_IOC_ENABLE);108}109 110int event_disable(struct event *e)111{112	return ioctl(e->fd, PERF_EVENT_IOC_DISABLE);113}114 115int event_reset(struct event *e)116{117	return ioctl(e->fd, PERF_EVENT_IOC_RESET);118}119 120int event_read(struct event *e)121{122	int rc;123 124	rc = read(e->fd, &e->result, sizeof(e->result));125	if (rc != sizeof(e->result)) {126		fprintf(stderr, "read error on event %p!\n", e);127		return -1;128	}129 130	return 0;131}132 133void event_report_justified(struct event *e, int name_width, int result_width)134{135	printf("%*s: result %*llu ", name_width, e->name, result_width,136	       e->result.value);137 138	if (e->result.running == e->result.enabled)139		printf("running/enabled %llu\n", e->result.running);140	else141		printf("running %llu enabled %llu\n", e->result.running,142			e->result.enabled);143}144 145void event_report(struct event *e)146{147	event_report_justified(e, 0, 0);148}149