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.c99
1 files changed, 96 insertions, 3 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6e50b914cad4..59f5cf64ef70 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -588,15 +588,60 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
588 return add_event(list, idx, &attr, name); 588 return add_event(list, idx, &attr, name);
589} 589}
590 590
591int 591static int config_term(struct perf_event_attr *attr,
592parse_events_add_numeric(struct list_head *list, int *idx, 592 struct parse_events__term *term)
593 unsigned long type, unsigned long config) 593{
594 switch (term->type) {
595 case PARSE_EVENTS__TERM_TYPE_CONFIG:
596 attr->config = term->val.num;
597 break;
598 case PARSE_EVENTS__TERM_TYPE_CONFIG1:
599 attr->config1 = term->val.num;
600 break;
601 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
602 attr->config2 = term->val.num;
603 break;
604 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
605 attr->sample_period = term->val.num;
606 break;
607 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
608 /*
609 * TODO uncomment when the field is available
610 * attr->branch_sample_type = term->val.num;
611 */
612 break;
613 default:
614 return -EINVAL;
615 }
616 return 0;
617}
618
619static int config_attr(struct perf_event_attr *attr,
620 struct list_head *head, int fail)
621{
622 struct parse_events__term *term;
623
624 list_for_each_entry(term, head, list)
625 if (config_term(attr, term) && fail)
626 return -EINVAL;
627
628 return 0;
629}
630
631int parse_events_add_numeric(struct list_head *list, int *idx,
632 unsigned long type, unsigned long config,
633 struct list_head *head_config)
594{ 634{
595 struct perf_event_attr attr; 635 struct perf_event_attr attr;
596 636
597 memset(&attr, 0, sizeof(attr)); 637 memset(&attr, 0, sizeof(attr));
598 attr.type = type; 638 attr.type = type;
599 attr.config = config; 639 attr.config = config;
640
641 if (head_config &&
642 config_attr(&attr, head_config, 1))
643 return -EINVAL;
644
600 return add_event(list, idx, &attr, 645 return add_event(list, idx, &attr,
601 (char *) __event_name(type, config)); 646 (char *) __event_name(type, config));
602} 647}
@@ -923,3 +968,51 @@ void print_events(const char *event_glob)
923 968
924 print_tracepoint_events(NULL, NULL); 969 print_tracepoint_events(NULL, NULL);
925} 970}
971
972int parse_events__is_hardcoded_term(struct parse_events__term *term)
973{
974 return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX;
975}
976
977int parse_events__new_term(struct parse_events__term **_term, int type,
978 char *config, char *str, long num)
979{
980 struct parse_events__term *term;
981
982 term = zalloc(sizeof(*term));
983 if (!term)
984 return -ENOMEM;
985
986 INIT_LIST_HEAD(&term->list);
987 term->type = type;
988 term->config = config;
989
990 switch (type) {
991 case PARSE_EVENTS__TERM_TYPE_CONFIG:
992 case PARSE_EVENTS__TERM_TYPE_CONFIG1:
993 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
994 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
995 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
996 case PARSE_EVENTS__TERM_TYPE_NUM:
997 term->val.num = num;
998 break;
999 case PARSE_EVENTS__TERM_TYPE_STR:
1000 term->val.str = str;
1001 break;
1002 default:
1003 return -EINVAL;
1004 }
1005
1006 *_term = term;
1007 return 0;
1008}
1009
1010void parse_events__free_terms(struct list_head *terms)
1011{
1012 struct parse_events__term *term, *h;
1013
1014 list_for_each_entry_safe(term, h, terms, list)
1015 free(term);
1016
1017 free(terms);
1018}