perf_counter: Separate out attr->type from attr->config
[deliverable/linux.git] / Documentation / perf_counter / util / parse-events.c
CommitLineData
8ad8db37
IM
1
2#include "../perf.h"
3#include "util.h"
4#include "parse-options.h"
5#include "parse-events.h"
6#include "exec_cmd.h"
a0055ae2 7#include "string.h"
8ad8db37 8
a21ca2ca 9int nr_counters;
8ad8db37 10
a21ca2ca 11struct perf_counter_attr attrs[MAX_COUNTERS];
8ad8db37
IM
12
13struct event_symbol {
a21ca2ca
IM
14 __u8 type;
15 __u64 config;
16 char *symbol;
8ad8db37
IM
17};
18
a21ca2ca
IM
19#define C(x, y) .type = PERF_TYPE_##x, .config = PERF_COUNT_##y
20
8ad8db37 21static struct event_symbol event_symbols[] = {
a21ca2ca
IM
22 { C(HARDWARE, CPU_CYCLES), "cpu-cycles", },
23 { C(HARDWARE, CPU_CYCLES), "cycles", },
24 { C(HARDWARE, INSTRUCTIONS), "instructions", },
25 { C(HARDWARE, CACHE_REFERENCES), "cache-references", },
26 { C(HARDWARE, CACHE_MISSES), "cache-misses", },
27 { C(HARDWARE, BRANCH_INSTRUCTIONS), "branch-instructions", },
28 { C(HARDWARE, BRANCH_INSTRUCTIONS), "branches", },
29 { C(HARDWARE, BRANCH_MISSES), "branch-misses", },
30 { C(HARDWARE, BUS_CYCLES), "bus-cycles", },
31
32 { C(SOFTWARE, CPU_CLOCK), "cpu-clock", },
33 { C(SOFTWARE, TASK_CLOCK), "task-clock", },
34 { C(SOFTWARE, PAGE_FAULTS), "page-faults", },
35 { C(SOFTWARE, PAGE_FAULTS), "faults", },
36 { C(SOFTWARE, PAGE_FAULTS_MIN), "minor-faults", },
37 { C(SOFTWARE, PAGE_FAULTS_MAJ), "major-faults", },
38 { C(SOFTWARE, CONTEXT_SWITCHES), "context-switches", },
39 { C(SOFTWARE, CONTEXT_SWITCHES), "cs", },
40 { C(SOFTWARE, CPU_MIGRATIONS), "cpu-migrations", },
41 { C(SOFTWARE, CPU_MIGRATIONS), "migrations", },
8ad8db37
IM
42};
43
5242519b
IM
44#define __PERF_COUNTER_FIELD(config, name) \
45 ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT)
46
47#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW)
48#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG)
49#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE)
50#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT)
51
52static char *hw_event_names[] = {
53 "CPU cycles",
54 "instructions",
55 "cache references",
56 "cache misses",
57 "branches",
58 "branch misses",
59 "bus cycles",
60};
61
62static char *sw_event_names[] = {
63 "cpu clock ticks",
64 "task clock ticks",
65 "pagefaults",
66 "context switches",
67 "CPU migrations",
68 "minor faults",
69 "major faults",
70};
71
a21ca2ca 72char *event_name(int counter)
5242519b 73{
a21ca2ca
IM
74 __u64 config = attrs[counter].config;
75 int type = attrs[counter].type;
5242519b
IM
76 static char buf[32];
77
a21ca2ca
IM
78 if (attrs[counter].type == PERF_TYPE_RAW) {
79 sprintf(buf, "raw 0x%llx", config);
5242519b
IM
80 return buf;
81 }
82
83 switch (type) {
84 case PERF_TYPE_HARDWARE:
a21ca2ca
IM
85 if (config < PERF_HW_EVENTS_MAX)
86 return hw_event_names[config];
5242519b
IM
87 return "unknown-hardware";
88
89 case PERF_TYPE_SOFTWARE:
a21ca2ca
IM
90 if (config < PERF_SW_EVENTS_MAX)
91 return sw_event_names[config];
5242519b
IM
92 return "unknown-software";
93
94 default:
95 break;
96 }
97
98 return "unknown";
99}
100
8ad8db37
IM
101/*
102 * Each event can have multiple symbolic names.
103 * Symbolic names are (almost) exactly matched.
104 */
a21ca2ca 105static int match_event_symbols(const char *str, struct perf_counter_attr *attr)
8ad8db37
IM
106{
107 __u64 config, id;
108 int type;
109 unsigned int i;
a0055ae2 110 const char *sep, *pstr;
8ad8db37 111
a21ca2ca
IM
112 if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) {
113 attr->type = PERF_TYPE_RAW;
114 attr->config = config;
115
116 return 0;
117 }
8ad8db37 118
a0055ae2
ACM
119 pstr = str;
120 sep = strchr(pstr, ':');
121 if (sep) {
122 type = atoi(pstr);
123 pstr = sep + 1;
124 id = atoi(pstr);
125 sep = strchr(pstr, ':');
126 if (sep) {
127 pstr = sep + 1;
128 if (strchr(pstr, 'k'))
a21ca2ca 129 attr->exclude_user = 1;
a0055ae2 130 if (strchr(pstr, 'u'))
a21ca2ca 131 attr->exclude_kernel = 1;
a0055ae2 132 }
a21ca2ca
IM
133 attr->type = type;
134 attr->config = id;
135
136 return 0;
5242519b 137 }
8ad8db37
IM
138
139 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
140 if (!strncmp(str, event_symbols[i].symbol,
a21ca2ca
IM
141 strlen(event_symbols[i].symbol))) {
142
143 attr->type = event_symbols[i].type;
144 attr->config = event_symbols[i].config;
145
146 return 0;
147 }
8ad8db37
IM
148 }
149
a21ca2ca 150 return -EINVAL;
8ad8db37
IM
151}
152
153int parse_events(const struct option *opt, const char *str, int unset)
154{
a21ca2ca
IM
155 struct perf_counter_attr attr;
156 int ret;
8ad8db37 157
a21ca2ca 158 memset(&attr, 0, sizeof(attr));
8ad8db37
IM
159again:
160 if (nr_counters == MAX_COUNTERS)
161 return -1;
162
a21ca2ca
IM
163 ret = match_event_symbols(str, &attr);
164 if (ret < 0)
165 return ret;
8ad8db37 166
a21ca2ca 167 attrs[nr_counters] = attr;
8ad8db37
IM
168 nr_counters++;
169
170 str = strstr(str, ",");
171 if (str) {
172 str++;
173 goto again;
174 }
175
176 return 0;
177}
178
8ad8db37
IM
179/*
180 * Create the help text for the event symbols:
181 */
182void create_events_help(char *events_help_msg)
183{
184 unsigned int i;
185 char *str;
8ad8db37
IM
186
187 str = events_help_msg;
188
189 str += sprintf(str,
190 "event name: [");
191
192 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
193 int type, id;
194
a21ca2ca
IM
195 type = event_symbols[i].type;
196 id = event_symbols[i].config;
8ad8db37
IM
197
198 if (i)
199 str += sprintf(str, "|");
200
201 str += sprintf(str, "%s",
202 event_symbols[i].symbol);
203 }
204
205 str += sprintf(str, "|rNNN]");
206}
This page took 0.039409 seconds and 5 git commands to generate.