diff options
Diffstat (limited to 'meta/recipes-kernel/perf/perf/sort-pmuevents.py')
-rwxr-xr-x | meta/recipes-kernel/perf/perf/sort-pmuevents.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/meta/recipes-kernel/perf/perf/sort-pmuevents.py b/meta/recipes-kernel/perf/perf/sort-pmuevents.py new file mode 100755 index 0000000000..0a87e553ab --- /dev/null +++ b/meta/recipes-kernel/perf/perf/sort-pmuevents.py | |||
@@ -0,0 +1,100 @@ | |||
1 | #!/usr/bin/env python3 | ||
2 | |||
3 | # perf pmu-events sorting tool | ||
4 | # | ||
5 | # Copyright (C) 2021 Bruce Ashfield | ||
6 | # | ||
7 | # SPDX-License-Identifier: MIT | ||
8 | # | ||
9 | |||
10 | import sys | ||
11 | import os | ||
12 | import re | ||
13 | from collections import OrderedDict | ||
14 | |||
15 | if len(sys.argv) < 2: | ||
16 | print( "[ERROR]: input and output pmu files missing" ) | ||
17 | sys.exit(1) | ||
18 | |||
19 | if len(sys.argv) < 3: | ||
20 | print( "[ERROR]: output pmu file missing" ) | ||
21 | sys.exit(1) | ||
22 | |||
23 | infile = sys.argv[1] | ||
24 | outfile = sys.argv[2] | ||
25 | |||
26 | if not os.path.exists(infile): | ||
27 | print( "ERROR. input file does not exist: %s" % infile ) | ||
28 | sys.exit(1) | ||
29 | |||
30 | if os.path.exists(outfile): | ||
31 | print( "WARNING. output file will be overwritten: %s" % infile ) | ||
32 | |||
33 | with open(infile, 'r') as file: | ||
34 | data = file.read() | ||
35 | |||
36 | preamble_regex = re.compile( '^(.*?)^(struct|const struct|static struct|static const struct)', re.MULTILINE | re.DOTALL ) | ||
37 | |||
38 | preamble = re.search( preamble_regex, data ) | ||
39 | struct_block_regex = re.compile(r'^(struct|const struct|static struct|static const struct).*?(\w+) (.*?)\[\] = {(.*?)^};', re.MULTILINE | re.DOTALL ) | ||
40 | field_regex = re.compile(r'{.*?},', re.MULTILINE | re.DOTALL ) | ||
41 | cpuid_regex = re.compile(r'\.cpuid = (.*?),', re.MULTILINE | re.DOTALL ) | ||
42 | name_regex = re.compile(r'\.name = (.*?),', re.MULTILINE | re.DOTALL ) | ||
43 | |||
44 | # create a dictionary structure to store all the structs, their | ||
45 | # types and then their fields. | ||
46 | entry_dict = {} | ||
47 | for struct in re.findall( struct_block_regex, data ): | ||
48 | # print( "struct: %s %s %s" % (struct[0],struct[1],struct[2]) ) | ||
49 | entry_dict[struct[2]] = {} | ||
50 | entry_dict[struct[2]]['type_prefix'] = struct[0] | ||
51 | entry_dict[struct[2]]['type'] = struct[1] | ||
52 | entry_dict[struct[2]]['fields'] = {} | ||
53 | for entry in re.findall( field_regex, struct[3] ): | ||
54 | #print( " entry: %s" % entry ) | ||
55 | cpuid = re.search( cpuid_regex, entry ) | ||
56 | if cpuid: | ||
57 | #print( " cpuid found: %s" % cpuid.group(1) ) | ||
58 | entry_dict[struct[2]]['fields'][cpuid.group(1)] = entry | ||
59 | |||
60 | name = re.search( name_regex, entry ) | ||
61 | if name: | ||
62 | #print( " name found: %s" % name.group(1) ) | ||
63 | entry_dict[struct[2]]['fields'][name.group(1)] = entry | ||
64 | |||
65 | # unmatched entries are most likely array terminators and | ||
66 | # should end up as the last element in the sorted list, which | ||
67 | # is achieved by using '0' as the key | ||
68 | if not cpuid and not name: | ||
69 | entry_dict[struct[2]]['fields']['0'] = entry | ||
70 | |||
71 | # created ordered dictionaries from the captured values. These are ordered by | ||
72 | # a sorted() iteration of the keys. We don't care about the order we read | ||
73 | # things, just the sorted order. Hency why we couldn't create these during | ||
74 | # reading. | ||
75 | # | ||
76 | # yes, there's a more concise way to do this, but our nested dictionaries of | ||
77 | # fields make it complex enough that it becomes unreadable. | ||
78 | entry_dict_sorted = OrderedDict() | ||
79 | for i in sorted(entry_dict.keys()): | ||
80 | entry_dict_sorted[i] = {} | ||
81 | entry_dict_sorted[i]['type_prefix'] = entry_dict[i]['type_prefix'] | ||
82 | entry_dict_sorted[i]['type'] = entry_dict[i]['type'] | ||
83 | entry_dict_sorted[i]['fields'] = {} | ||
84 | for f in sorted(entry_dict[i]['fields'].keys()): | ||
85 | entry_dict_sorted[i]['fields'][f] = entry_dict[i]['fields'][f] | ||
86 | |||
87 | # dump the sorted elements to the outfile | ||
88 | outf = open( outfile, 'w' ) | ||
89 | |||
90 | print( preamble.group(1) ) | ||
91 | outf.write( preamble.group(1) ) | ||
92 | for d in entry_dict_sorted: | ||
93 | outf.write( "%s %s %s[] = {\n" % (entry_dict_sorted[d]['type_prefix'], entry_dict_sorted[d]['type'],d) ) | ||
94 | for f in entry_dict_sorted[d]['fields']: | ||
95 | outf.write( entry_dict_sorted[d]['fields'][f] + '\n' ) | ||
96 | |||
97 | outf.write( "};\n" ) | ||
98 | |||
99 | outf.close() | ||
100 | |||