7a8b549f1b59b6e34a5572dff34ab13eb70b6095
[lttng-tools.git] / tests / perf / find_event.c
1 /*
2 * Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include <errno.h>
9 #include <linux/perf_event.h>
10 #include <perfmon/perf_event.h>
11 #include <perfmon/pfmlib_perf_event.h>
12 #include <stdio.h>
13 #include <string.h>
14
15 int main(int argc, char **argv)
16 {
17 int ret, fd;
18
19 /* pfm query objects */
20 pfm_perf_encode_arg_t pencoder;
21 pfm_event_info_t info;
22
23 /* Perf event object to be populated by libpfm */
24 struct perf_event_attr attr;
25
26 if (argc != 2) {
27 fprintf(stderr,
28 "Usage: %s <pmu counter to find>\n"
29 "ex: %s UNHALTED_REFERENCE_CYCLES\n"
30 "Returns the event raw number if found and actionable with"
31 "return code 0.\n"
32 "If not found returns 1,"
33 "If not actionable return 2,"
34 "on error returns 255\n",
35 argv[0],
36 argv[0]);
37 ret = -1;
38 goto end;
39 }
40
41 /* Initialize perf_event_attr. */
42 memset(&attr, 0, sizeof(struct perf_event_attr));
43
44 /* Initialize libpfm encoder structure. */
45 memset(&pencoder, 0, sizeof(pencoder));
46 pencoder.size = sizeof(pfm_perf_encode_arg_t);
47
48 /* Initialize libpfm event info structure. */
49 memset(&info, 0, sizeof(info));
50 info.size = sizeof(info);
51
52 /* Prepare the encoder for query. */
53 pencoder.attr = &attr; /* Set the perf_event_attr pointer. */
54 pencoder.fstr = NULL; /* Not interested by the fully qualified event string. */
55
56 ret = pfm_initialize();
57 if (ret != PFM_SUCCESS) {
58 fprintf(stderr, "Failed to initialise libpfm: %s", pfm_strerror(ret));
59 ret = 255;
60 goto end;
61 }
62
63 ret = pfm_get_os_event_encoding(
64 argv[1], PFM_PLM0 | PFM_PLM1 | PFM_PLM2 | PFM_PLM3, PFM_OS_PERF_EVENT, &pencoder);
65 if (ret != PFM_SUCCESS) {
66 fprintf(stderr, "libpfm: error pfm_get_os_event_encoding: %s\n", pfm_strerror(ret));
67 ret = 1;
68 goto end;
69 }
70
71 /*
72 * Query the raw code for later use. Do it now to simplify error
73 * management.
74 */
75 ret = pfm_get_event_info(pencoder.idx, PFM_OS_NONE, &info);
76 if (ret != PFM_SUCCESS) {
77 fprintf(stderr, "libpfm: error pfm_get_event_info: %s\n", pfm_strerror(ret));
78 ret = 1;
79 goto end;
80 }
81
82 /*
83 * Now that the event is found, try to use it to validate that
84 * the current user has access to it and that it can be used on that
85 * host.
86 */
87
88 /* Set the event to disabled to prevent unnecessary side effects. */
89 pencoder.attr->disabled = 1;
90
91 /* perf_event_open is provided by perfmon/perf_event.h. */
92 fd = perf_event_open(pencoder.attr, 0, -1, -1, 0);
93 if (fd == -1) {
94 fprintf(stderr, "perf: error perf_event_open: %d: %s\n", errno, strerror(errno));
95 ret = 2;
96 goto end;
97 }
98
99 /* We close the fd immediately since the event is actionable. */
100 close(fd);
101
102 /* Output the raw code for the event */
103 fprintf(stdout, "r%" PRIx64 "\n", info.code);
104 ret = 0;
105
106 end:
107 return ret;
108 }
This page took 0.032423 seconds and 5 git commands to generate.