perf_counter tools: Add string.[ch]
[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"
7
8int nr_counters;
9
10__u64 event_id[MAX_COUNTERS] = { };
5242519b 11int event_mask[MAX_COUNTERS];
8ad8db37
IM
12
13struct event_symbol {
14 __u64 event;
15 char *symbol;
16};
17
18static struct event_symbol event_symbols[] = {
19 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", },
20 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", },
21 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", },
22 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", },
23 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", },
24 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", },
25 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", },
26 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", },
27 {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", },
28
29 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", },
30 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", },
31 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", },
32 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", },
33 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", },
34 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", },
35 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", },
36 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", },
37 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", },
38 {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", },
39};
40
5242519b
IM
41#define __PERF_COUNTER_FIELD(config, name) \
42 ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT)
43
44#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW)
45#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG)
46#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE)
47#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT)
48
49static char *hw_event_names[] = {
50 "CPU cycles",
51 "instructions",
52 "cache references",
53 "cache misses",
54 "branches",
55 "branch misses",
56 "bus cycles",
57};
58
59static char *sw_event_names[] = {
60 "cpu clock ticks",
61 "task clock ticks",
62 "pagefaults",
63 "context switches",
64 "CPU migrations",
65 "minor faults",
66 "major faults",
67};
68
69char *event_name(int ctr)
70{
71 __u64 config = event_id[ctr];
72 int type = PERF_COUNTER_TYPE(config);
73 int id = PERF_COUNTER_ID(config);
74 static char buf[32];
75
76 if (PERF_COUNTER_RAW(config)) {
77 sprintf(buf, "raw 0x%llx", PERF_COUNTER_CONFIG(config));
78 return buf;
79 }
80
81 switch (type) {
82 case PERF_TYPE_HARDWARE:
83 if (id < PERF_HW_EVENTS_MAX)
84 return hw_event_names[id];
85 return "unknown-hardware";
86
87 case PERF_TYPE_SOFTWARE:
88 if (id < PERF_SW_EVENTS_MAX)
89 return sw_event_names[id];
90 return "unknown-software";
91
92 default:
93 break;
94 }
95
96 return "unknown";
97}
98
8ad8db37
IM
99/*
100 * Each event can have multiple symbolic names.
101 * Symbolic names are (almost) exactly matched.
102 */
103static __u64 match_event_symbols(const char *str)
104{
105 __u64 config, id;
106 int type;
107 unsigned int i;
5242519b 108 char mask_str[4];
8ad8db37
IM
109
110 if (sscanf(str, "r%llx", &config) == 1)
111 return config | PERF_COUNTER_RAW_MASK;
112
5242519b
IM
113 switch (sscanf(str, "%d:%llu:%2s", &type, &id, mask_str)) {
114 case 3:
115 if (strchr(mask_str, 'k'))
116 event_mask[nr_counters] |= EVENT_MASK_USER;
117 if (strchr(mask_str, 'u'))
118 event_mask[nr_counters] |= EVENT_MASK_KERNEL;
119 case 2:
120 return EID(type, id);
121
122 default:
123 break;
124 }
8ad8db37
IM
125
126 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
127 if (!strncmp(str, event_symbols[i].symbol,
128 strlen(event_symbols[i].symbol)))
129 return event_symbols[i].event;
130 }
131
132 return ~0ULL;
133}
134
135int parse_events(const struct option *opt, const char *str, int unset)
136{
137 __u64 config;
138
139again:
140 if (nr_counters == MAX_COUNTERS)
141 return -1;
142
143 config = match_event_symbols(str);
144 if (config == ~0ULL)
145 return -1;
146
147 event_id[nr_counters] = config;
148 nr_counters++;
149
150 str = strstr(str, ",");
151 if (str) {
152 str++;
153 goto again;
154 }
155
156 return 0;
157}
158
8ad8db37
IM
159/*
160 * Create the help text for the event symbols:
161 */
162void create_events_help(char *events_help_msg)
163{
164 unsigned int i;
165 char *str;
166 __u64 e;
167
168 str = events_help_msg;
169
170 str += sprintf(str,
171 "event name: [");
172
173 for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
174 int type, id;
175
176 e = event_symbols[i].event;
177 type = PERF_COUNTER_TYPE(e);
178 id = PERF_COUNTER_ID(e);
179
180 if (i)
181 str += sprintf(str, "|");
182
183 str += sprintf(str, "%s",
184 event_symbols[i].symbol);
185 }
186
187 str += sprintf(str, "|rNNN]");
188}
189
This page took 0.033053 seconds and 5 git commands to generate.