diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-04-25 12:24:57 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-05-18 11:15:32 -0400 |
commit | 16fa7e8200fb9066b77a3f27cbed8e4a9fc71998 (patch) | |
tree | d1454e844fe5b40389970995830f6eaabbe51c86 /tools | |
parent | a0187060f4ab68cf1aa533446b906cae5b14eb48 (diff) |
perf tools: Split term type into value type and term type
Introducing type_val and type_term for term instead of a single type
value. Currently the term type marked out the value type as well.
With this change we can have future string term values being specified
by user and translated into proper number along the processing.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1335371102-11358-2-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/parse-events.c | 45 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 21 | ||||
-rw-r--r-- | tools/perf/util/parse-events.y | 16 | ||||
-rw-r--r-- | tools/perf/util/pmu.c | 70 |
4 files changed, 96 insertions, 56 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 5b3a0ef4e232..c7fc18a33d54 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -593,17 +593,27 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx, | |||
593 | static int config_term(struct perf_event_attr *attr, | 593 | static int config_term(struct perf_event_attr *attr, |
594 | struct parse_events__term *term) | 594 | struct parse_events__term *term) |
595 | { | 595 | { |
596 | switch (term->type) { | 596 | #define CHECK_TYPE_VAL(type) \ |
597 | do { \ | ||
598 | if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \ | ||
599 | return -EINVAL; \ | ||
600 | } while (0) | ||
601 | |||
602 | switch (term->type_term) { | ||
597 | case PARSE_EVENTS__TERM_TYPE_CONFIG: | 603 | case PARSE_EVENTS__TERM_TYPE_CONFIG: |
604 | CHECK_TYPE_VAL(NUM); | ||
598 | attr->config = term->val.num; | 605 | attr->config = term->val.num; |
599 | break; | 606 | break; |
600 | case PARSE_EVENTS__TERM_TYPE_CONFIG1: | 607 | case PARSE_EVENTS__TERM_TYPE_CONFIG1: |
608 | CHECK_TYPE_VAL(NUM); | ||
601 | attr->config1 = term->val.num; | 609 | attr->config1 = term->val.num; |
602 | break; | 610 | break; |
603 | case PARSE_EVENTS__TERM_TYPE_CONFIG2: | 611 | case PARSE_EVENTS__TERM_TYPE_CONFIG2: |
612 | CHECK_TYPE_VAL(NUM); | ||
604 | attr->config2 = term->val.num; | 613 | attr->config2 = term->val.num; |
605 | break; | 614 | break; |
606 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: | 615 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: |
616 | CHECK_TYPE_VAL(NUM); | ||
607 | attr->sample_period = term->val.num; | 617 | attr->sample_period = term->val.num; |
608 | break; | 618 | break; |
609 | case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: | 619 | case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: |
@@ -615,7 +625,9 @@ static int config_term(struct perf_event_attr *attr, | |||
615 | default: | 625 | default: |
616 | return -EINVAL; | 626 | return -EINVAL; |
617 | } | 627 | } |
628 | |||
618 | return 0; | 629 | return 0; |
630 | #undef CHECK_TYPE_VAL | ||
619 | } | 631 | } |
620 | 632 | ||
621 | static int config_attr(struct perf_event_attr *attr, | 633 | static int config_attr(struct perf_event_attr *attr, |
@@ -1015,11 +1027,12 @@ void print_events(const char *event_glob) | |||
1015 | 1027 | ||
1016 | int parse_events__is_hardcoded_term(struct parse_events__term *term) | 1028 | int parse_events__is_hardcoded_term(struct parse_events__term *term) |
1017 | { | 1029 | { |
1018 | return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX; | 1030 | return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; |
1019 | } | 1031 | } |
1020 | 1032 | ||
1021 | int parse_events__new_term(struct parse_events__term **_term, int type, | 1033 | static int new_term(struct parse_events__term **_term, int type_val, |
1022 | char *config, char *str, long num) | 1034 | int type_term, char *config, |
1035 | char *str, long num) | ||
1023 | { | 1036 | { |
1024 | struct parse_events__term *term; | 1037 | struct parse_events__term *term; |
1025 | 1038 | ||
@@ -1028,15 +1041,11 @@ int parse_events__new_term(struct parse_events__term **_term, int type, | |||
1028 | return -ENOMEM; | 1041 | return -ENOMEM; |
1029 | 1042 | ||
1030 | INIT_LIST_HEAD(&term->list); | 1043 | INIT_LIST_HEAD(&term->list); |
1031 | term->type = type; | 1044 | term->type_val = type_val; |
1045 | term->type_term = type_term; | ||
1032 | term->config = config; | 1046 | term->config = config; |
1033 | 1047 | ||
1034 | switch (type) { | 1048 | switch (type_val) { |
1035 | case PARSE_EVENTS__TERM_TYPE_CONFIG: | ||
1036 | case PARSE_EVENTS__TERM_TYPE_CONFIG1: | ||
1037 | case PARSE_EVENTS__TERM_TYPE_CONFIG2: | ||
1038 | case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: | ||
1039 | case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: | ||
1040 | case PARSE_EVENTS__TERM_TYPE_NUM: | 1049 | case PARSE_EVENTS__TERM_TYPE_NUM: |
1041 | term->val.num = num; | 1050 | term->val.num = num; |
1042 | break; | 1051 | break; |
@@ -1051,6 +1060,20 @@ int parse_events__new_term(struct parse_events__term **_term, int type, | |||
1051 | return 0; | 1060 | return 0; |
1052 | } | 1061 | } |
1053 | 1062 | ||
1063 | int parse_events__term_num(struct parse_events__term **term, | ||
1064 | int type_term, char *config, long num) | ||
1065 | { | ||
1066 | return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, | ||
1067 | config, NULL, num); | ||
1068 | } | ||
1069 | |||
1070 | int parse_events__term_str(struct parse_events__term **term, | ||
1071 | int type_term, char *config, char *str) | ||
1072 | { | ||
1073 | return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, | ||
1074 | config, str, 0); | ||
1075 | } | ||
1076 | |||
1054 | void parse_events__free_terms(struct list_head *terms) | 1077 | void parse_events__free_terms(struct list_head *terms) |
1055 | { | 1078 | { |
1056 | struct parse_events__term *term, *h; | 1079 | struct parse_events__term *term, *h; |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 5cb002894a17..3fddd610d350 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -36,16 +36,17 @@ extern int parse_filter(const struct option *opt, const char *str, int unset); | |||
36 | #define EVENTS_HELP_MAX (128*1024) | 36 | #define EVENTS_HELP_MAX (128*1024) |
37 | 37 | ||
38 | enum { | 38 | enum { |
39 | PARSE_EVENTS__TERM_TYPE_NUM, | ||
40 | PARSE_EVENTS__TERM_TYPE_STR, | ||
41 | }; | ||
42 | |||
43 | enum { | ||
44 | PARSE_EVENTS__TERM_TYPE_USER, | ||
39 | PARSE_EVENTS__TERM_TYPE_CONFIG, | 45 | PARSE_EVENTS__TERM_TYPE_CONFIG, |
40 | PARSE_EVENTS__TERM_TYPE_CONFIG1, | 46 | PARSE_EVENTS__TERM_TYPE_CONFIG1, |
41 | PARSE_EVENTS__TERM_TYPE_CONFIG2, | 47 | PARSE_EVENTS__TERM_TYPE_CONFIG2, |
42 | PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD, | 48 | PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD, |
43 | PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, | 49 | PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, |
44 | PARSE_EVENTS__TERM_TYPE_NUM, | ||
45 | PARSE_EVENTS__TERM_TYPE_STR, | ||
46 | |||
47 | PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX = | ||
48 | PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | struct parse_events__term { | 52 | struct parse_events__term { |
@@ -54,14 +55,16 @@ struct parse_events__term { | |||
54 | char *str; | 55 | char *str; |
55 | long num; | 56 | long num; |
56 | } val; | 57 | } val; |
57 | int type; | 58 | int type_val; |
58 | 59 | int type_term; | |
59 | struct list_head list; | 60 | struct list_head list; |
60 | }; | 61 | }; |
61 | 62 | ||
62 | int parse_events__is_hardcoded_term(struct parse_events__term *term); | 63 | int parse_events__is_hardcoded_term(struct parse_events__term *term); |
63 | int parse_events__new_term(struct parse_events__term **term, int type, | 64 | int parse_events__term_num(struct parse_events__term **_term, |
64 | char *config, char *str, long num); | 65 | int type_term, char *config, long num); |
66 | int parse_events__term_str(struct parse_events__term **_term, | ||
67 | int type_term, char *config, char *str); | ||
65 | void parse_events__free_terms(struct list_head *terms); | 68 | void parse_events__free_terms(struct list_head *terms); |
66 | int parse_events_modifier(struct list_head *list __used, char *str __used); | 69 | int parse_events_modifier(struct list_head *list __used, char *str __used); |
67 | int parse_events_add_tracepoint(struct list_head *list, int *idx, | 70 | int parse_events_add_tracepoint(struct list_head *list, int *idx, |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index d9637da7333c..936913ea0ab6 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
@@ -176,8 +176,8 @@ PE_NAME '=' PE_NAME | |||
176 | { | 176 | { |
177 | struct parse_events__term *term; | 177 | struct parse_events__term *term; |
178 | 178 | ||
179 | ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR, | 179 | ABORT_ON(parse_events__term_str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
180 | $1, $3, 0)); | 180 | $1, $3)); |
181 | $$ = term; | 181 | $$ = term; |
182 | } | 182 | } |
183 | | | 183 | | |
@@ -185,8 +185,8 @@ PE_NAME '=' PE_VALUE | |||
185 | { | 185 | { |
186 | struct parse_events__term *term; | 186 | struct parse_events__term *term; |
187 | 187 | ||
188 | ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM, | 188 | ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
189 | $1, NULL, $3)); | 189 | $1, $3)); |
190 | $$ = term; | 190 | $$ = term; |
191 | } | 191 | } |
192 | | | 192 | | |
@@ -194,8 +194,8 @@ PE_NAME | |||
194 | { | 194 | { |
195 | struct parse_events__term *term; | 195 | struct parse_events__term *term; |
196 | 196 | ||
197 | ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM, | 197 | ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
198 | $1, NULL, 1)); | 198 | $1, 1)); |
199 | $$ = term; | 199 | $$ = term; |
200 | } | 200 | } |
201 | | | 201 | | |
@@ -203,7 +203,7 @@ PE_TERM '=' PE_VALUE | |||
203 | { | 203 | { |
204 | struct parse_events__term *term; | 204 | struct parse_events__term *term; |
205 | 205 | ||
206 | ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, $3)); | 206 | ABORT_ON(parse_events__term_num(&term, $1, NULL, $3)); |
207 | $$ = term; | 207 | $$ = term; |
208 | } | 208 | } |
209 | | | 209 | | |
@@ -211,7 +211,7 @@ PE_TERM | |||
211 | { | 211 | { |
212 | struct parse_events__term *term; | 212 | struct parse_events__term *term; |
213 | 213 | ||
214 | ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, 1)); | 214 | ABORT_ON(parse_events__term_num(&term, $1, NULL, 1)); |
215 | $$ = term; | 215 | $$ = term; |
216 | } | 216 | } |
217 | 217 | ||
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index cb08a118e811..8ee219b7285b 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -225,7 +225,7 @@ static int pmu_config_term(struct list_head *formats, | |||
225 | if (parse_events__is_hardcoded_term(term)) | 225 | if (parse_events__is_hardcoded_term(term)) |
226 | return 0; | 226 | return 0; |
227 | 227 | ||
228 | if (term->type != PARSE_EVENTS__TERM_TYPE_NUM) | 228 | if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM) |
229 | return -EINVAL; | 229 | return -EINVAL; |
230 | 230 | ||
231 | format = pmu_find_format(formats, term->config); | 231 | format = pmu_find_format(formats, term->config); |
@@ -246,6 +246,11 @@ static int pmu_config_term(struct list_head *formats, | |||
246 | return -EINVAL; | 246 | return -EINVAL; |
247 | } | 247 | } |
248 | 248 | ||
249 | /* | ||
250 | * XXX If we ever decide to go with string values for | ||
251 | * non-hardcoded terms, here's the place to translate | ||
252 | * them into value. | ||
253 | */ | ||
249 | *vp |= pmu_format_value(format->bits, term->val.num); | 254 | *vp |= pmu_format_value(format->bits, term->val.num); |
250 | return 0; | 255 | return 0; |
251 | } | 256 | } |
@@ -324,49 +329,58 @@ static struct test_format { | |||
324 | /* Simulated users input. */ | 329 | /* Simulated users input. */ |
325 | static struct parse_events__term test_terms[] = { | 330 | static struct parse_events__term test_terms[] = { |
326 | { | 331 | { |
327 | .config = (char *) "krava01", | 332 | .config = (char *) "krava01", |
328 | .val.num = 15, | 333 | .val.num = 15, |
329 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 334 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
335 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
330 | }, | 336 | }, |
331 | { | 337 | { |
332 | .config = (char *) "krava02", | 338 | .config = (char *) "krava02", |
333 | .val.num = 170, | 339 | .val.num = 170, |
334 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 340 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
341 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
335 | }, | 342 | }, |
336 | { | 343 | { |
337 | .config = (char *) "krava03", | 344 | .config = (char *) "krava03", |
338 | .val.num = 1, | 345 | .val.num = 1, |
339 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 346 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
347 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
340 | }, | 348 | }, |
341 | { | 349 | { |
342 | .config = (char *) "krava11", | 350 | .config = (char *) "krava11", |
343 | .val.num = 27, | 351 | .val.num = 27, |
344 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 352 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
353 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
345 | }, | 354 | }, |
346 | { | 355 | { |
347 | .config = (char *) "krava12", | 356 | .config = (char *) "krava12", |
348 | .val.num = 1, | 357 | .val.num = 1, |
349 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 358 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
359 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
350 | }, | 360 | }, |
351 | { | 361 | { |
352 | .config = (char *) "krava13", | 362 | .config = (char *) "krava13", |
353 | .val.num = 2, | 363 | .val.num = 2, |
354 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 364 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
365 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
355 | }, | 366 | }, |
356 | { | 367 | { |
357 | .config = (char *) "krava21", | 368 | .config = (char *) "krava21", |
358 | .val.num = 119, | 369 | .val.num = 119, |
359 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 370 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
371 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
360 | }, | 372 | }, |
361 | { | 373 | { |
362 | .config = (char *) "krava22", | 374 | .config = (char *) "krava22", |
363 | .val.num = 11, | 375 | .val.num = 11, |
364 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 376 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
377 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
365 | }, | 378 | }, |
366 | { | 379 | { |
367 | .config = (char *) "krava23", | 380 | .config = (char *) "krava23", |
368 | .val.num = 2, | 381 | .val.num = 2, |
369 | .type = PARSE_EVENTS__TERM_TYPE_NUM, | 382 | .type_val = PARSE_EVENTS__TERM_TYPE_NUM, |
383 | .type_term = PARSE_EVENTS__TERM_TYPE_USER, | ||
370 | }, | 384 | }, |
371 | }; | 385 | }; |
372 | #define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term)) | 386 | #define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term)) |