aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorZheng Yan <zheng.z.yan@intel.com>2012-06-15 02:31:39 -0400
committerIngo Molnar <mingo@kernel.org>2012-06-18 06:13:24 -0400
commitac20de6fff445d6deb0c44c25946d198f79f2f00 (patch)
tree8d0ec729ea5b5aa8965e46370df50167506b1e61 /tools/perf
parent46010ab2607aed9484816a8f1679c2ec3c8e7dcf (diff)
perf/tool: Make the event parser re-entrant
Make the event parser reentrant by creating separate scanner for each parsing. The scanner is passed to the bison as and argument to the lexer. Signed-off-by: Zheng Yan <zheng.z.yan@intel.com> [ Cleaned up the patch. ] Signed-off-by: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1339741902-8449-11-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/parse-events.c35
-rw-r--r--tools/perf/util/parse-events.h2
-rw-r--r--tools/perf/util/parse-events.l116
-rw-r--r--tools/perf/util/parse-events.y9
4 files changed, 98 insertions, 64 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c71b29ad26e..ca8665e19c0 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -11,6 +11,7 @@
11#include "cache.h" 11#include "cache.h"
12#include "header.h" 12#include "header.h"
13#include "debugfs.h" 13#include "debugfs.h"
14#include "parse-events-bison.h"
14#include "parse-events-flex.h" 15#include "parse-events-flex.h"
15#include "pmu.h" 16#include "pmu.h"
16 17
@@ -26,7 +27,7 @@ struct event_symbol {
26#ifdef PARSER_DEBUG 27#ifdef PARSER_DEBUG
27extern int parse_events_debug; 28extern int parse_events_debug;
28#endif 29#endif
29int parse_events_parse(void *data); 30int parse_events_parse(void *data, void *scanner);
30 31
31#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 32#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
32#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 33#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
@@ -787,26 +788,38 @@ int parse_events_modifier(struct list_head *list, char *str)
787 return 0; 788 return 0;
788} 789}
789 790
790int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) 791static int parse_events__scanner(const char *str, void *data)
791{ 792{
792 struct parse_events_data__events data = {
793 .list = LIST_HEAD_INIT(data.list),
794 .idx = evlist->nr_entries,
795 };
796 YY_BUFFER_STATE buffer; 793 YY_BUFFER_STATE buffer;
794 void *scanner;
797 int ret; 795 int ret;
798 796
799 buffer = parse_events__scan_string(str); 797 ret = parse_events_lex_init(&scanner);
798 if (ret)
799 return ret;
800
801 buffer = parse_events__scan_string(str, scanner);
800 802
801#ifdef PARSER_DEBUG 803#ifdef PARSER_DEBUG
802 parse_events_debug = 1; 804 parse_events_debug = 1;
803#endif 805#endif
804 ret = parse_events_parse(&data); 806 ret = parse_events_parse(data, scanner);
807
808 parse_events__flush_buffer(buffer, scanner);
809 parse_events__delete_buffer(buffer, scanner);
810 parse_events_lex_destroy(scanner);
811 return ret;
812}
805 813
806 parse_events__flush_buffer(buffer); 814int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
807 parse_events__delete_buffer(buffer); 815{
808 parse_events_lex_destroy(); 816 struct parse_events_data__events data = {
817 .list = LIST_HEAD_INIT(data.list),
818 .idx = evlist->nr_entries,
819 };
820 int ret;
809 821
822 ret = parse_events__scanner(str, &data);
810 if (!ret) { 823 if (!ret) {
811 int entries = data.idx - evlist->nr_entries; 824 int entries = data.idx - evlist->nr_entries;
812 perf_evlist__splice_list_tail(evlist, &data.list, entries); 825 perf_evlist__splice_list_tail(evlist, &data.list, entries);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index dc3c83a0ab8..fa2b19b862e 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -88,7 +88,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
88 char *pmu , struct list_head *head_config); 88 char *pmu , struct list_head *head_config);
89void parse_events_update_lists(struct list_head *list_event, 89void parse_events_update_lists(struct list_head *list_event,
90 struct list_head *list_all); 90 struct list_head *list_all);
91void parse_events_error(void *data, char const *msg); 91void parse_events_error(void *data, void *scanner, char const *msg);
92int parse_events__test(void); 92int parse_events__test(void);
93 93
94void print_events(const char *event_glob); 94void print_events(const char *event_glob);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 618a8e78839..329794eea71 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -1,4 +1,6 @@
1 1
2%option reentrant
3%option bison-bridge
2%option prefix="parse_events_" 4%option prefix="parse_events_"
3%option stack 5%option stack
4 6
@@ -8,7 +10,10 @@
8#include "parse-events-bison.h" 10#include "parse-events-bison.h"
9#include "parse-events.h" 11#include "parse-events.h"
10 12
11static int __value(char *str, int base, int token) 13char *parse_events_get_text(yyscan_t yyscanner);
14YYSTYPE *parse_events_get_lval(yyscan_t yyscanner);
15
16static int __value(YYSTYPE *yylval, char *str, int base, int token)
12{ 17{
13 long num; 18 long num;
14 19
@@ -17,35 +22,48 @@ static int __value(char *str, int base, int token)
17 if (errno) 22 if (errno)
18 return PE_ERROR; 23 return PE_ERROR;
19 24
20 parse_events_lval.num = num; 25 yylval->num = num;
21 return token; 26 return token;
22} 27}
23 28
24static int value(int base) 29static int value(yyscan_t scanner, int base)
25{ 30{
26 return __value(parse_events_text, base, PE_VALUE); 31 YYSTYPE *yylval = parse_events_get_lval(scanner);
32 char *text = parse_events_get_text(scanner);
33
34 return __value(yylval, text, base, PE_VALUE);
27} 35}
28 36
29static int raw(void) 37static int raw(yyscan_t scanner)
30{ 38{
31 return __value(parse_events_text + 1, 16, PE_RAW); 39 YYSTYPE *yylval = parse_events_get_lval(scanner);
40 char *text = parse_events_get_text(scanner);
41
42 return __value(yylval, text + 1, 16, PE_RAW);
32} 43}
33 44
34static int str(int token) 45static int str(yyscan_t scanner, int token)
35{ 46{
36 parse_events_lval.str = strdup(parse_events_text); 47 YYSTYPE *yylval = parse_events_get_lval(scanner);
48 char *text = parse_events_get_text(scanner);
49
50 yylval->str = strdup(text);
37 return token; 51 return token;
38} 52}
39 53
40static int sym(int type, int config) 54static int sym(yyscan_t scanner, int type, int config)
41{ 55{
42 parse_events_lval.num = (type << 16) + config; 56 YYSTYPE *yylval = parse_events_get_lval(scanner);
57
58 yylval->num = (type << 16) + config;
43 return PE_VALUE_SYM; 59 return PE_VALUE_SYM;
44} 60}
45 61
46static int term(int type) 62static int term(yyscan_t scanner, int type)
47{ 63{
48 parse_events_lval.num = type; 64 YYSTYPE *yylval = parse_events_get_lval(scanner);
65
66 yylval->num = type;
49 return PE_TERM; 67 return PE_TERM;
50} 68}
51 69
@@ -61,25 +79,25 @@ modifier_event [ukhpGH]{1,8}
61modifier_bp [rwx] 79modifier_bp [rwx]
62 80
63%% 81%%
64cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } 82cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
65stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } 83stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
66stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } 84stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
67instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } 85instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
68cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } 86cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
69cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } 87cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
70branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } 88branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
71branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } 89branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
72bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } 90bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
73ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } 91ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
74cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } 92cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
75task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } 93task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
76page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } 94page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
77minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } 95minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
78major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } 96major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
79context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } 97context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
80cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } 98cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
81alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } 99alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
82emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } 100emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
83 101
84L1-dcache|l1-d|l1d|L1-data | 102L1-dcache|l1-d|l1d|L1-data |
85L1-icache|l1-i|l1i|L1-instruction | 103L1-icache|l1-i|l1i|L1-instruction |
@@ -87,14 +105,14 @@ LLC|L2 |
87dTLB|d-tlb|Data-TLB | 105dTLB|d-tlb|Data-TLB |
88iTLB|i-tlb|Instruction-TLB | 106iTLB|i-tlb|Instruction-TLB |
89branch|branches|bpu|btb|bpc | 107branch|branches|bpu|btb|bpc |
90node { return str(PE_NAME_CACHE_TYPE); } 108node { return str(yyscanner, PE_NAME_CACHE_TYPE); }
91 109
92load|loads|read | 110load|loads|read |
93store|stores|write | 111store|stores|write |
94prefetch|prefetches | 112prefetch|prefetches |
95speculative-read|speculative-load | 113speculative-read|speculative-load |
96refs|Reference|ops|access | 114refs|Reference|ops|access |
97misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } 115misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
98 116
99 /* 117 /*
100 * These are event config hardcoded term names to be specified 118 * These are event config hardcoded term names to be specified
@@ -102,20 +120,20 @@ misses|miss { return str(PE_NAME_CACHE_OP_RESULT); }
102 * so we can put them here directly. In case the we have a conflict 120 * so we can put them here directly. In case the we have a conflict
103 * in future, this needs to go into '//' condition block. 121 * in future, this needs to go into '//' condition block.
104 */ 122 */
105config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } 123config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
106config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } 124config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
107config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } 125config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
108name { return term(PARSE_EVENTS__TERM_TYPE_NAME); } 126name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
109period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } 127period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
110branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } 128branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
111 129
112mem: { BEGIN(mem); return PE_PREFIX_MEM; } 130mem: { BEGIN(mem); return PE_PREFIX_MEM; }
113r{num_raw_hex} { return raw(); } 131r{num_raw_hex} { return raw(yyscanner); }
114{num_dec} { return value(10); } 132{num_dec} { return value(yyscanner, 10); }
115{num_hex} { return value(16); } 133{num_hex} { return value(yyscanner, 16); }
116 134
117{modifier_event} { return str(PE_MODIFIER_EVENT); } 135{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
118{name} { return str(PE_NAME); } 136{name} { return str(yyscanner, PE_NAME); }
119"/" { return '/'; } 137"/" { return '/'; }
120- { return '-'; } 138- { return '-'; }
121, { return ','; } 139, { return ','; }
@@ -123,17 +141,17 @@ r{num_raw_hex} { return raw(); }
123= { return '='; } 141= { return '='; }
124 142
125<mem>{ 143<mem>{
126{modifier_bp} { return str(PE_MODIFIER_BP); } 144{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
127: { return ':'; } 145: { return ':'; }
128{num_dec} { return value(10); } 146{num_dec} { return value(yyscanner, 10); }
129{num_hex} { return value(16); } 147{num_hex} { return value(yyscanner, 16); }
130 /* 148 /*
131 * We need to separate 'mem:' scanner part, in order to get specific 149 * We need to separate 'mem:' scanner part, in order to get specific
132 * modifier bits parsed out. Otherwise we would need to handle PE_NAME 150 * modifier bits parsed out. Otherwise we would need to handle PE_NAME
133 * and we'd need to parse it manually. During the escape from <mem> 151 * and we'd need to parse it manually. During the escape from <mem>
134 * state we need to put the escaping char back, so we dont miss it. 152 * state we need to put the escaping char back, so we dont miss it.
135 */ 153 */
136. { unput(*parse_events_text); BEGIN(INITIAL); } 154. { unput(*yytext); BEGIN(INITIAL); }
137 /* 155 /*
138 * We destroy the scanner after reaching EOF, 156 * We destroy the scanner after reaching EOF,
139 * but anyway just to be sure get back to INIT state. 157 * but anyway just to be sure get back to INIT state.
@@ -143,7 +161,7 @@ r{num_raw_hex} { return raw(); }
143 161
144%% 162%%
145 163
146int parse_events_wrap(void) 164int parse_events_wrap(void *scanner __used)
147{ 165{
148 return 1; 166 return 1;
149} 167}
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index e533bf72ba9..2a93d5c8ccd 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -1,6 +1,8 @@
1 1%pure-parser
2%name-prefix "parse_events_" 2%name-prefix "parse_events_"
3%parse-param {void *_data} 3%parse-param {void *_data}
4%parse-param {void *scanner}
5%lex-param {void* scanner}
4 6
5%{ 7%{
6 8
@@ -11,8 +13,9 @@
11#include "types.h" 13#include "types.h"
12#include "util.h" 14#include "util.h"
13#include "parse-events.h" 15#include "parse-events.h"
16#include "parse-events-bison.h"
14 17
15extern int parse_events_lex (void); 18extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
16 19
17#define ABORT_ON(val) \ 20#define ABORT_ON(val) \
18do { \ 21do { \
@@ -286,7 +289,7 @@ sep_slash_dc: '/' | ':' |
286 289
287%% 290%%
288 291
289void parse_events_error(void *data __used, 292void parse_events_error(void *data __used, void *scanner __used,
290 char const *msg __used) 293 char const *msg __used)
291{ 294{
292} 295}