perf_counter tools: Librarize event string parsing
[firefly-linux-kernel-4.4.55.git] / Documentation / perf_counter / util / parse-events.c
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
8 int nr_counters;
9
10 __u64                   event_id[MAX_COUNTERS]          = { };
11
12 struct event_symbol {
13         __u64 event;
14         char *symbol;
15 };
16
17 static struct event_symbol event_symbols[] = {
18         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES),                "cpu-cycles",           },
19         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES),                "cycles",               },
20         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS),              "instructions",         },
21         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES),          "cache-references",     },
22         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES),              "cache-misses",         },
23         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS),       "branch-instructions",  },
24         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS),       "branches",             },
25         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES),             "branch-misses",        },
26         {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES),                "bus-cycles",           },
27
28         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK),                 "cpu-clock",            },
29         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK),                "task-clock",           },
30         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS),               "page-faults",          },
31         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS),               "faults",               },
32         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN),           "minor-faults",         },
33         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ),           "major-faults",         },
34         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES),          "context-switches",     },
35         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES),          "cs",                   },
36         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS),            "cpu-migrations",       },
37         {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS),            "migrations",           },
38 };
39
40 /*
41  * Each event can have multiple symbolic names.
42  * Symbolic names are (almost) exactly matched.
43  */
44 static __u64 match_event_symbols(const char *str)
45 {
46         __u64 config, id;
47         int type;
48         unsigned int i;
49
50         if (sscanf(str, "r%llx", &config) == 1)
51                 return config | PERF_COUNTER_RAW_MASK;
52
53         if (sscanf(str, "%d:%llu", &type, &id) == 2)
54                 return EID(type, id);
55
56         for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
57                 if (!strncmp(str, event_symbols[i].symbol,
58                              strlen(event_symbols[i].symbol)))
59                         return event_symbols[i].event;
60         }
61
62         return ~0ULL;
63 }
64
65 int parse_events(const struct option *opt, const char *str, int unset)
66 {
67         __u64 config;
68
69 again:
70         if (nr_counters == MAX_COUNTERS)
71                 return -1;
72
73         config = match_event_symbols(str);
74         if (config == ~0ULL)
75                 return -1;
76
77         event_id[nr_counters] = config;
78         nr_counters++;
79
80         str = strstr(str, ",");
81         if (str) {
82                 str++;
83                 goto again;
84         }
85
86         return 0;
87 }
88
89 #define __PERF_COUNTER_FIELD(config, name) \
90         ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT)
91
92 #define PERF_COUNTER_RAW(config)        __PERF_COUNTER_FIELD(config, RAW)
93 #define PERF_COUNTER_CONFIG(config)     __PERF_COUNTER_FIELD(config, CONFIG)
94 #define PERF_COUNTER_TYPE(config)       __PERF_COUNTER_FIELD(config, TYPE)
95 #define PERF_COUNTER_ID(config)         __PERF_COUNTER_FIELD(config, EVENT)
96
97 /*
98  * Create the help text for the event symbols:
99  */
100 void create_events_help(char *events_help_msg)
101 {
102         unsigned int i;
103         char *str;
104         __u64 e;
105
106         str = events_help_msg;
107
108         str += sprintf(str,
109         "event name: [");
110
111         for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
112                 int type, id;
113
114                 e = event_symbols[i].event;
115                 type = PERF_COUNTER_TYPE(e);
116                 id = PERF_COUNTER_ID(e);
117
118                 if (i)
119                         str += sprintf(str, "|");
120
121                 str += sprintf(str, "%s",
122                                 event_symbols[i].symbol);
123         }
124
125         str += sprintf(str, "|rNNN]");
126 }
127