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