aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c114
1 files changed, 87 insertions, 27 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5b3a0ef4e232..fac7d59309b8 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -23,8 +23,10 @@ struct event_symbol {
23 const char *alias; 23 const char *alias;
24}; 24};
25 25
26int parse_events_parse(struct list_head *list, struct list_head *list_tmp, 26#ifdef PARSER_DEBUG
27 int *idx); 27extern int parse_events_debug;
28#endif
29int parse_events_parse(struct list_head *list, int *idx);
28 30
29#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 31#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
30#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 32#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
@@ -355,20 +357,30 @@ const char *__event_name(int type, u64 config)
355 return "unknown"; 357 return "unknown";
356} 358}
357 359
358static int add_event(struct list_head *list, int *idx, 360static int add_event(struct list_head **_list, int *idx,
359 struct perf_event_attr *attr, char *name) 361 struct perf_event_attr *attr, char *name)
360{ 362{
361 struct perf_evsel *evsel; 363 struct perf_evsel *evsel;
364 struct list_head *list = *_list;
365
366 if (!list) {
367 list = malloc(sizeof(*list));
368 if (!list)
369 return -ENOMEM;
370 INIT_LIST_HEAD(list);
371 }
362 372
363 event_attr_init(attr); 373 event_attr_init(attr);
364 374
365 evsel = perf_evsel__new(attr, (*idx)++); 375 evsel = perf_evsel__new(attr, (*idx)++);
366 if (!evsel) 376 if (!evsel) {
377 free(list);
367 return -ENOMEM; 378 return -ENOMEM;
368 379 }
369 list_add_tail(&evsel->node, list);
370 380
371 evsel->name = strdup(name); 381 evsel->name = strdup(name);
382 list_add_tail(&evsel->node, list);
383 *_list = list;
372 return 0; 384 return 0;
373} 385}
374 386
@@ -390,7 +402,7 @@ static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size)
390 return -1; 402 return -1;
391} 403}
392 404
393int parse_events_add_cache(struct list_head *list, int *idx, 405int parse_events_add_cache(struct list_head **list, int *idx,
394 char *type, char *op_result1, char *op_result2) 406 char *type, char *op_result1, char *op_result2)
395{ 407{
396 struct perf_event_attr attr; 408 struct perf_event_attr attr;
@@ -451,7 +463,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
451 return add_event(list, idx, &attr, name); 463 return add_event(list, idx, &attr, name);
452} 464}
453 465
454static int add_tracepoint(struct list_head *list, int *idx, 466static int add_tracepoint(struct list_head **list, int *idx,
455 char *sys_name, char *evt_name) 467 char *sys_name, char *evt_name)
456{ 468{
457 struct perf_event_attr attr; 469 struct perf_event_attr attr;
@@ -488,7 +500,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
488 return add_event(list, idx, &attr, name); 500 return add_event(list, idx, &attr, name);
489} 501}
490 502
491static int add_tracepoint_multi(struct list_head *list, int *idx, 503static int add_tracepoint_multi(struct list_head **list, int *idx,
492 char *sys_name, char *evt_name) 504 char *sys_name, char *evt_name)
493{ 505{
494 char evt_path[MAXPATHLEN]; 506 char evt_path[MAXPATHLEN];
@@ -519,7 +531,7 @@ static int add_tracepoint_multi(struct list_head *list, int *idx,
519 return ret; 531 return ret;
520} 532}
521 533
522int parse_events_add_tracepoint(struct list_head *list, int *idx, 534int parse_events_add_tracepoint(struct list_head **list, int *idx,
523 char *sys, char *event) 535 char *sys, char *event)
524{ 536{
525 int ret; 537 int ret;
@@ -563,7 +575,7 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
563 return 0; 575 return 0;
564} 576}
565 577
566int parse_events_add_breakpoint(struct list_head *list, int *idx, 578int parse_events_add_breakpoint(struct list_head **list, int *idx,
567 void *ptr, char *type) 579 void *ptr, char *type)
568{ 580{
569 struct perf_event_attr attr; 581 struct perf_event_attr attr;
@@ -593,17 +605,27 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
593static int config_term(struct perf_event_attr *attr, 605static int config_term(struct perf_event_attr *attr,
594 struct parse_events__term *term) 606 struct parse_events__term *term)
595{ 607{
596 switch (term->type) { 608#define CHECK_TYPE_VAL(type) \
609do { \
610 if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \
611 return -EINVAL; \
612} while (0)
613
614 switch (term->type_term) {
597 case PARSE_EVENTS__TERM_TYPE_CONFIG: 615 case PARSE_EVENTS__TERM_TYPE_CONFIG:
616 CHECK_TYPE_VAL(NUM);
598 attr->config = term->val.num; 617 attr->config = term->val.num;
599 break; 618 break;
600 case PARSE_EVENTS__TERM_TYPE_CONFIG1: 619 case PARSE_EVENTS__TERM_TYPE_CONFIG1:
620 CHECK_TYPE_VAL(NUM);
601 attr->config1 = term->val.num; 621 attr->config1 = term->val.num;
602 break; 622 break;
603 case PARSE_EVENTS__TERM_TYPE_CONFIG2: 623 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
624 CHECK_TYPE_VAL(NUM);
604 attr->config2 = term->val.num; 625 attr->config2 = term->val.num;
605 break; 626 break;
606 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: 627 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
628 CHECK_TYPE_VAL(NUM);
607 attr->sample_period = term->val.num; 629 attr->sample_period = term->val.num;
608 break; 630 break;
609 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: 631 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
@@ -612,10 +634,15 @@ static int config_term(struct perf_event_attr *attr,
612 * attr->branch_sample_type = term->val.num; 634 * attr->branch_sample_type = term->val.num;
613 */ 635 */
614 break; 636 break;
637 case PARSE_EVENTS__TERM_TYPE_NAME:
638 CHECK_TYPE_VAL(STR);
639 break;
615 default: 640 default:
616 return -EINVAL; 641 return -EINVAL;
617 } 642 }
643
618 return 0; 644 return 0;
645#undef CHECK_TYPE_VAL
619} 646}
620 647
621static int config_attr(struct perf_event_attr *attr, 648static int config_attr(struct perf_event_attr *attr,
@@ -630,7 +657,7 @@ static int config_attr(struct perf_event_attr *attr,
630 return 0; 657 return 0;
631} 658}
632 659
633int parse_events_add_numeric(struct list_head *list, int *idx, 660int parse_events_add_numeric(struct list_head **list, int *idx,
634 unsigned long type, unsigned long config, 661 unsigned long type, unsigned long config,
635 struct list_head *head_config) 662 struct list_head *head_config)
636{ 663{
@@ -648,7 +675,24 @@ int parse_events_add_numeric(struct list_head *list, int *idx,
648 (char *) __event_name(type, config)); 675 (char *) __event_name(type, config));
649} 676}
650 677
651int parse_events_add_pmu(struct list_head *list, int *idx, 678static int parse_events__is_name_term(struct parse_events__term *term)
679{
680 return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
681}
682
683static char *pmu_event_name(struct perf_event_attr *attr,
684 struct list_head *head_terms)
685{
686 struct parse_events__term *term;
687
688 list_for_each_entry(term, head_terms, list)
689 if (parse_events__is_name_term(term))
690 return term->val.str;
691
692 return (char *) __event_name(PERF_TYPE_RAW, attr->config);
693}
694
695int parse_events_add_pmu(struct list_head **list, int *idx,
652 char *name, struct list_head *head_config) 696 char *name, struct list_head *head_config)
653{ 697{
654 struct perf_event_attr attr; 698 struct perf_event_attr attr;
@@ -669,7 +713,8 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
669 if (perf_pmu__config(pmu, &attr, head_config)) 713 if (perf_pmu__config(pmu, &attr, head_config))
670 return -EINVAL; 714 return -EINVAL;
671 715
672 return add_event(list, idx, &attr, (char *) "pmu"); 716 return add_event(list, idx, &attr,
717 pmu_event_name(&attr, head_config));
673} 718}
674 719
675void parse_events_update_lists(struct list_head *list_event, 720void parse_events_update_lists(struct list_head *list_event,
@@ -681,7 +726,7 @@ void parse_events_update_lists(struct list_head *list_event,
681 * list, for next event definition. 726 * list, for next event definition.
682 */ 727 */
683 list_splice_tail(list_event, list_all); 728 list_splice_tail(list_event, list_all);
684 INIT_LIST_HEAD(list_event); 729 free(list_event);
685} 730}
686 731
687int parse_events_modifier(struct list_head *list, char *str) 732int parse_events_modifier(struct list_head *list, char *str)
@@ -756,10 +801,14 @@ int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
756 801
757 buffer = parse_events__scan_string(str); 802 buffer = parse_events__scan_string(str);
758 803
759 ret = parse_events_parse(&list, &list_tmp, &idx); 804#ifdef PARSER_DEBUG
805 parse_events_debug = 1;
806#endif
807 ret = parse_events_parse(&list, &idx);
760 808
761 parse_events__flush_buffer(buffer); 809 parse_events__flush_buffer(buffer);
762 parse_events__delete_buffer(buffer); 810 parse_events__delete_buffer(buffer);
811 parse_events_lex_destroy();
763 812
764 if (!ret) { 813 if (!ret) {
765 int entries = idx - evlist->nr_entries; 814 int entries = idx - evlist->nr_entries;
@@ -1015,11 +1064,12 @@ void print_events(const char *event_glob)
1015 1064
1016int parse_events__is_hardcoded_term(struct parse_events__term *term) 1065int parse_events__is_hardcoded_term(struct parse_events__term *term)
1017{ 1066{
1018 return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX; 1067 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
1019} 1068}
1020 1069
1021int parse_events__new_term(struct parse_events__term **_term, int type, 1070static int new_term(struct parse_events__term **_term, int type_val,
1022 char *config, char *str, long num) 1071 int type_term, char *config,
1072 char *str, long num)
1023{ 1073{
1024 struct parse_events__term *term; 1074 struct parse_events__term *term;
1025 1075
@@ -1028,15 +1078,11 @@ int parse_events__new_term(struct parse_events__term **_term, int type,
1028 return -ENOMEM; 1078 return -ENOMEM;
1029 1079
1030 INIT_LIST_HEAD(&term->list); 1080 INIT_LIST_HEAD(&term->list);
1031 term->type = type; 1081 term->type_val = type_val;
1082 term->type_term = type_term;
1032 term->config = config; 1083 term->config = config;
1033 1084
1034 switch (type) { 1085 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: 1086 case PARSE_EVENTS__TERM_TYPE_NUM:
1041 term->val.num = num; 1087 term->val.num = num;
1042 break; 1088 break;
@@ -1051,6 +1097,20 @@ int parse_events__new_term(struct parse_events__term **_term, int type,
1051 return 0; 1097 return 0;
1052} 1098}
1053 1099
1100int parse_events__term_num(struct parse_events__term **term,
1101 int type_term, char *config, long num)
1102{
1103 return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term,
1104 config, NULL, num);
1105}
1106
1107int parse_events__term_str(struct parse_events__term **term,
1108 int type_term, char *config, char *str)
1109{
1110 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term,
1111 config, str, 0);
1112}
1113
1054void parse_events__free_terms(struct list_head *terms) 1114void parse_events__free_terms(struct list_head *terms)
1055{ 1115{
1056 struct parse_events__term *term, *h; 1116 struct parse_events__term *term, *h;