~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/pmu-events/jevents.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/perf/pmu-events/jevents.py (Version linux-6.12-rc7) and /tools/perf/pmu-events/jevents.py (Version linux-5.15.171)


  1 #!/usr/bin/env python3                            
  2 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-    
  3 """Convert directories of JSON events to C cod    
  4 import argparse                                   
  5 import csv                                        
  6 from functools import lru_cache                   
  7 import json                                       
  8 import metric                                     
  9 import os                                         
 10 import sys                                        
 11 from typing import (Callable, Dict, Optional,     
 12 import collections                                
 13                                                   
 14 # Global command line arguments.                  
 15 _args = None                                      
 16 # List of regular event tables.                   
 17 _event_tables = []                                
 18 # List of event tables generated from "/sys" d    
 19 _sys_event_tables = []                            
 20 # List of regular metric tables.                  
 21 _metric_tables = []                               
 22 # List of metric tables generated from "/sys"     
 23 _sys_metric_tables = []                           
 24 # Mapping between sys event table names and sy    
 25 _sys_event_table_to_metric_table_mapping = {}     
 26 # Map from an event name to an architecture st    
 27 # JsonEvent. Architecture standard events are     
 28 # f'{_args.starting_dir}/{_args.arch}' directo    
 29 _arch_std_events = {}                             
 30 # Events to write out when the table is closed    
 31 _pending_events = []                              
 32 # Name of events table to be written out          
 33 _pending_events_tblname = None                    
 34 # Metrics to write out when the table is close    
 35 _pending_metrics = []                             
 36 # Name of metrics table to be written out         
 37 _pending_metrics_tblname = None                   
 38 # Global BigCString shared by all structures.     
 39 _bcs = None                                       
 40 # Map from the name of a metric group to a des    
 41 _metricgroups = {}                                
 42 # Order specific JsonEvent attributes will be     
 43 _json_event_attributes = [                        
 44     # cmp_sevent related attributes.              
 45     'name', 'topic', 'desc',                      
 46     # Seems useful, put it early.                 
 47     'event',                                      
 48     # Short things in alphabetical order.         
 49     'compat', 'deprecated', 'perpkg', 'unit',     
 50     # Longer things (the last won't be iterate    
 51     'long_desc'                                   
 52 ]                                                 
 53                                                   
 54 # Attributes that are in pmu_metric rather tha    
 55 _json_metric_attributes = [                       
 56     'metric_name', 'metric_group', 'metric_exp    
 57     'desc', 'long_desc', 'unit', 'compat', 'me    
 58     'default_metricgroup_name', 'aggr_mode', '    
 59 ]                                                 
 60 # Attributes that are bools or enum int values    
 61 _json_enum_attributes = ['aggr_mode', 'depreca    
 62                                                   
 63 def removesuffix(s: str, suffix: str) -> str:     
 64   """Remove the suffix from a string              
 65                                                   
 66   The removesuffix function is added to str in    
 67   compatibility and so provide our own functio    
 68   """                                             
 69   return s[0:-len(suffix)] if s.endswith(suffi    
 70                                                   
 71                                                   
 72 def file_name_to_table_name(prefix: str, paren    
 73                             dirname: str) -> s    
 74   """Generate a C table name from directory na    
 75   tblname = prefix                                
 76   for p in parents:                               
 77     tblname += '_' + p                            
 78   tblname += '_' + dirname                        
 79   return tblname.replace('-', '_')                
 80                                                   
 81                                                   
 82 def c_len(s: str) -> int:                         
 83   """Return the length of s a C string            
 84                                                   
 85   This doesn't handle all escape characters pr    
 86   all \\ are for escaping, it then adjusts as     
 87   \\. The code uses \000 rather than \0 as a t    
 88   number would be folded into a string of \0 (    
 89   equal a terminator followed by the number 5     
 90   \05). The code adjusts for \000 but not prop    
 91   or unicode values.                              
 92   """                                             
 93   try:                                            
 94     utf = s.encode(encoding='utf-8',errors='st    
 95   except:                                         
 96     print(f'broken string {s}')                   
 97     raise                                         
 98   return len(utf) - utf.count(b'\\') + utf.cou    
 99                                                   
100 class BigCString:                                 
101   """A class to hold many strings concatenated    
102                                                   
103   Generating a large number of stand-alone C s    
104   number of relocations in position independen    
105   is a helper for this case. It builds a singl    
106   are all the other C strings (to avoid memory    
107   itself is held as a list of strings). The of    
108   string are recorded and when stored to disk     
109   relocation. To reduce the size of the string    
110   strings are merged. If a longer string ends-    
111   shorter string, these entries are also merge    
112   """                                             
113   strings: Set[str]                               
114   big_string: Sequence[str]                       
115   offsets: Dict[str, int]                         
116   insert_number: int                              
117   insert_point: Dict[str, int]                    
118   metrics: Set[str]                               
119                                                   
120   def __init__(self):                             
121     self.strings = set()                          
122     self.insert_number = 0;                       
123     self.insert_point = {}                        
124     self.metrics = set()                          
125                                                   
126   def add(self, s: str, metric: bool) -> None:    
127     """Called to add to the big string."""        
128     if s not in self.strings:                     
129       self.strings.add(s)                         
130       self.insert_point[s] = self.insert_numbe    
131       self.insert_number += 1                     
132       if metric:                                  
133         self.metrics.add(s)                       
134                                                   
135   def compute(self) -> None:                      
136     """Called once all strings are added to co    
137                                                   
138     folded_strings = {}                           
139     # Determine if two strings can be folded,     
140     # end of another. First reverse all string    
141     sorted_reversed_strings = sorted([x[::-1]     
142                                                   
143     # Strings 'xyz' and 'yz' will now be [ 'zy    
144     # for each string to see if there is a bet    
145     # into, in the example rather than using '    
146     # an offset of 1. We record which string c    
147     # in folded_strings, we don't need to reco    
148     # trivially computed from the string lengt    
149     for pos,s in enumerate(sorted_reversed_str    
150       best_pos = pos                              
151       for check_pos in range(pos + 1, len(sort    
152         if sorted_reversed_strings[check_pos].    
153           best_pos = check_pos                    
154         else:                                     
155           break                                   
156       if pos != best_pos:                         
157         folded_strings[s[::-1]] = sorted_rever    
158                                                   
159     # Compute reverse mappings for debugging.     
160     fold_into_strings = collections.defaultdic    
161     for key, val in folded_strings.items():       
162       if key != val:                              
163         fold_into_strings[val].add(key)           
164                                                   
165     # big_string_offset is the current locatio    
166     # being appended to - comments, etc. don't    
167     # the string contents represented as a lis    
168     # in Python and so appending to one causes    
169     # lists are mutable.                          
170     big_string_offset = 0                         
171     self.big_string = []                          
172     self.offsets = {}                             
173                                                   
174     def string_cmp_key(s: str) -> Tuple[bool,     
175       return (s in self.metrics, self.insert_p    
176                                                   
177     # Emit all strings that aren't folded in a    
178     for s in sorted(self.strings, key=string_c    
179       if s not in folded_strings:                 
180         self.offsets[s] = big_string_offset       
181         self.big_string.append(f'/* offset={bi    
182         self.big_string.append(s)                 
183         self.big_string.append('"')               
184         if s in fold_into_strings:                
185           self.big_string.append(' /* also: '     
186         self.big_string.append('\n')              
187         big_string_offset += c_len(s)             
188         continue                                  
189                                                   
190     # Compute the offsets of the folded string    
191     for s in folded_strings.keys():               
192       assert s not in self.offsets                
193       folded_s = folded_strings[s]                
194       self.offsets[s] = self.offsets[folded_s]    
195                                                   
196 _bcs = BigCString()                               
197                                                   
198 class JsonEvent:                                  
199   """Representation of an event loaded from a     
200                                                   
201   def __init__(self, jd: dict):                   
202     """Constructor passed the dictionary of pa    
203                                                   
204     def llx(x: int) -> str:                       
205       """Convert an int to a string similar to    
206       return str(x) if x >= 0 and x < 10 else     
207                                                   
208     def fixdesc(s: str) -> str:                   
209       """Fix formatting issue for the desc str    
210       if s is None:                               
211         return None                               
212       return removesuffix(removesuffix(removes    
213                                        '. '),     
214                                            '\"    
215                                                   
216     def convert_aggr_mode(aggr_mode: str) -> O    
217       """Returns the aggr_mode_class enum valu    
218       if not aggr_mode:                           
219         return None                               
220       aggr_mode_to_enum = {                       
221           'PerChip': '1',                         
222           'PerCore': '2',                         
223       }                                           
224       return aggr_mode_to_enum[aggr_mode]         
225                                                   
226     def convert_metric_constraint(metric_const    
227       """Returns the metric_event_groups enum     
228       if not metric_constraint:                   
229         return None                               
230       metric_constraint_to_enum = {               
231           'NO_GROUP_EVENTS': '1',                 
232           'NO_GROUP_EVENTS_NMI': '2',             
233           'NO_NMI_WATCHDOG': '2',                 
234           'NO_GROUP_EVENTS_SMT': '3',             
235       }                                           
236       return metric_constraint_to_enum[metric_    
237                                                   
238     def lookup_msr(num: str) -> Optional[str]:    
239       """Converts the msr number, or first in     
240       if not num:                                 
241         return None                               
242       msrmap = {                                  
243           0x3F6: 'ldlat=',                        
244           0x1A6: 'offcore_rsp=',                  
245           0x1A7: 'offcore_rsp=',                  
246           0x3F7: 'frontend=',                     
247       }                                           
248       return msrmap[int(num.split(',', 1)[0],     
249                                                   
250     def real_event(name: str, event: str) -> O    
251       """Convert well known event names to an     
252       fixed = {                                   
253           'inst_retired.any': 'event=0xc0,peri    
254           'inst_retired.any_p': 'event=0xc0,pe    
255           'cpu_clk_unhalted.ref': 'event=0x0,u    
256           'cpu_clk_unhalted.thread': 'event=0x    
257           'cpu_clk_unhalted.core': 'event=0x3c    
258           'cpu_clk_unhalted.thread_any': 'even    
259       }                                           
260       if not name:                                
261         return None                               
262       if name.lower() in fixed:                   
263         return fixed[name.lower()]                
264       return event                                
265                                                   
266     def unit_to_pmu(unit: str) -> Optional[str    
267       """Convert a JSON Unit to Linux PMU name    
268       if not unit:                                
269         return 'default_core'                     
270       # Comment brought over from jevents.c:      
271       # it's not realistic to keep adding thes    
272       table = {                                   
273           'CBO': 'uncore_cbox',                   
274           'QPI LL': 'uncore_qpi',                 
275           'SBO': 'uncore_sbox',                   
276           'iMPH-U': 'uncore_arb',                 
277           'CPU-M-CF': 'cpum_cf',                  
278           'CPU-M-SF': 'cpum_sf',                  
279           'PAI-CRYPTO' : 'pai_crypto',            
280           'PAI-EXT' : 'pai_ext',                  
281           'UPI LL': 'uncore_upi',                 
282           'hisi_sicl,cpa': 'hisi_sicl,cpa',       
283           'hisi_sccl,ddrc': 'hisi_sccl,ddrc',     
284           'hisi_sccl,hha': 'hisi_sccl,hha',       
285           'hisi_sccl,l3c': 'hisi_sccl,l3c',       
286           'imx8_ddr': 'imx8_ddr',                 
287           'imx9_ddr': 'imx9_ddr',                 
288           'L3PMC': 'amd_l3',                      
289           'DFPMC': 'amd_df',                      
290           'UMCPMC': 'amd_umc',                    
291           'cpu_core': 'cpu_core',                 
292           'cpu_atom': 'cpu_atom',                 
293           'ali_drw': 'ali_drw',                   
294           'arm_cmn': 'arm_cmn',                   
295       }                                           
296       return table[unit] if unit in table else    
297                                                   
298     def is_zero(val: str) -> bool:                
299         try:                                      
300             if val.startswith('0x'):              
301                 return int(val, 16) == 0          
302             else:                                 
303                 return int(val) == 0              
304         except e:                                 
305             return False                          
306                                                   
307     def canonicalize_value(val: str) -> str:      
308         try:                                      
309             if val.startswith('0x'):              
310                 return llx(int(val, 16))          
311             return str(int(val))                  
312         except e:                                 
313             return val                            
314                                                   
315     eventcode = 0                                 
316     if 'EventCode' in jd:                         
317       eventcode = int(jd['EventCode'].split(',    
318     if 'ExtSel' in jd:                            
319       eventcode |= int(jd['ExtSel']) << 8         
320     configcode = int(jd['ConfigCode'], 0) if '    
321     eventidcode = int(jd['EventidCode'], 0) if    
322     self.name = jd['EventName'].lower() if 'Ev    
323     self.topic = ''                               
324     self.compat = jd.get('Compat')                
325     self.desc = fixdesc(jd.get('BriefDescripti    
326     self.long_desc = fixdesc(jd.get('PublicDes    
327     precise = jd.get('PEBS')                      
328     msr = lookup_msr(jd.get('MSRIndex'))          
329     msrval = jd.get('MSRValue')                   
330     extra_desc = ''                               
331     if 'Data_LA' in jd:                           
332       extra_desc += '  Supports address when p    
333       if 'Errata' in jd:                          
334         extra_desc += '.'                         
335     if 'Errata' in jd:                            
336       extra_desc += '  Spec update: ' + jd['Er    
337     self.pmu = unit_to_pmu(jd.get('Unit'))        
338     filter = jd.get('Filter')                     
339     self.unit = jd.get('ScaleUnit')               
340     self.perpkg = jd.get('PerPkg')                
341     self.aggr_mode = convert_aggr_mode(jd.get(    
342     self.deprecated = jd.get('Deprecated')        
343     self.metric_name = jd.get('MetricName')       
344     self.metric_group = jd.get('MetricGroup')     
345     self.metricgroup_no_group = jd.get('Metric    
346     self.default_metricgroup_name = jd.get('De    
347     self.event_grouping = convert_metric_const    
348     self.metric_expr = None                       
349     if 'MetricExpr' in jd:                        
350       self.metric_expr = metric.ParsePerfJson(    
351     # Note, the metric formula for the thresho    
352     # and > have incorrect precedence.            
353     self.metric_threshold = jd.get('MetricThre    
354                                                   
355     arch_std = jd.get('ArchStdEvent')             
356     if precise and self.desc and '(Precise Eve    
357       extra_desc += ' (Must be precise)' if pr    
358                                                   
359     event = None                                  
360     if configcode is not None:                    
361       event = f'config={llx(configcode)}'         
362     elif eventidcode is not None:                 
363       event = f'eventid={llx(eventidcode)}'       
364     else:                                         
365       event = f'event={llx(eventcode)}'           
366     event_fields = [                              
367         ('AnyThread', 'any='),                    
368         ('PortMask', 'ch_mask='),                 
369         ('CounterMask', 'cmask='),                
370         ('EdgeDetect', 'edge='),                  
371         ('FCMask', 'fc_mask='),                   
372         ('Invert', 'inv='),                       
373         ('SampleAfterValue', 'period='),          
374         ('UMask', 'umask='),                      
375         ('NodeType', 'type='),                    
376         ('RdWrMask', 'rdwrmask='),                
377         ('EnAllCores', 'enallcores='),            
378         ('EnAllSlices', 'enallslices='),          
379         ('SliceId', 'sliceid='),                  
380         ('ThreadMask', 'threadmask='),            
381     ]                                             
382     for key, value in event_fields:               
383       if key in jd and not is_zero(jd[key]):      
384         event += f',{value}{canonicalize_value    
385     if filter:                                    
386       event += f',{filter}'                       
387     if msr:                                       
388       event += f',{msr}{msrval}'                  
389     if self.desc and extra_desc:                  
390       self.desc += extra_desc                     
391     if self.long_desc and extra_desc:             
392       self.long_desc += extra_desc                
393     if arch_std:                                  
394       if arch_std.lower() in _arch_std_events:    
395         event = _arch_std_events[arch_std.lowe    
396         # Copy from the architecture standard     
397         for attr, value in _arch_std_events[ar    
398           if hasattr(self, attr) and not getat    
399             setattr(self, attr, value)            
400       else:                                       
401         raise argparse.ArgumentTypeError('Cann    
402                                                   
403     self.event = real_event(self.name, event)     
404                                                   
405   def __repr__(self) -> str:                      
406     """String representation primarily for deb    
407     s = '{\n'                                     
408     for attr, value in self.__dict__.items():     
409       if value:                                   
410         s += f'\t{attr} = {value},\n'             
411     return s + '}'                                
412                                                   
413   def build_c_string(self, metric: bool) -> st    
414     s = ''                                        
415     for attr in _json_metric_attributes if met    
416       x = getattr(self, attr)                     
417       if metric and x and attr == 'metric_expr    
418         # Convert parsed metric expressions in    
419         # must be doubled in the file.            
420         x = x.ToPerfJson().replace('\\', '\\\\    
421       if metric and x and attr == 'metric_thre    
422         x = x.replace('\\', '\\\\')               
423       if attr in _json_enum_attributes:           
424         s += x if x else '0'                      
425       else:                                       
426         s += f'{x}\\000' if x else '\\000'        
427     return s                                      
428                                                   
429   def to_c_string(self, metric: bool) -> str:     
430     """Representation of the event as a C stru    
431                                                   
432     s = self.build_c_string(metric)               
433     return f'{{ { _bcs.offsets[s] } }}, /* {s}    
434                                                   
435                                                   
436 @lru_cache(maxsize=None)                          
437 def read_json_events(path: str, topic: str) ->    
438   """Read json events from the specified file.    
439   try:                                            
440     events = json.load(open(path), object_hook    
441   except BaseException as err:                    
442     print(f"Exception processing {path}")         
443     raise                                         
444   metrics: list[Tuple[str, str, metric.Express    
445   for event in events:                            
446     event.topic = topic                           
447     if event.metric_name and '-' not in event.    
448       metrics.append((event.pmu, event.metric_    
449   updates = metric.RewriteMetricsInTermsOfOthe    
450   if updates:                                     
451     for event in events:                          
452       if event.metric_name in updates:            
453         # print(f'Updated {event.metric_name}     
454         #       f'to\n"{updates[event.metric_n    
455         event.metric_expr = updates[event.metr    
456                                                   
457   return events                                   
458                                                   
459 def preprocess_arch_std_files(archpath: str) -    
460   """Read in all architecture standard events.    
461   global _arch_std_events                         
462   for item in os.scandir(archpath):               
463     if item.is_file() and item.name.endswith('    
464       for event in read_json_events(item.path,    
465         if event.name:                            
466           _arch_std_events[event.name.lower()]    
467         if event.metric_name:                     
468           _arch_std_events[event.metric_name.l    
469                                                   
470                                                   
471 def add_events_table_entries(item: os.DirEntry    
472   """Add contents of file to _pending_events t    
473   for e in read_json_events(item.path, topic):    
474     if e.name:                                    
475       _pending_events.append(e)                   
476     if e.metric_name:                             
477       _pending_metrics.append(e)                  
478                                                   
479                                                   
480 def print_pending_events() -> None:               
481   """Optionally close events table."""            
482                                                   
483   def event_cmp_key(j: JsonEvent) -> Tuple[str    
484     def fix_none(s: Optional[str]) -> str:        
485       if s is None:                               
486         return ''                                 
487       return s                                    
488                                                   
489     return (fix_none(j.pmu).replace(',','_'),     
490             fix_none(j.metric_name))              
491                                                   
492   global _pending_events                          
493   if not _pending_events:                         
494     return                                        
495                                                   
496   global _pending_events_tblname                  
497   if _pending_events_tblname.endswith('_sys'):    
498     global _sys_event_tables                      
499     _sys_event_tables.append(_pending_events_t    
500   else:                                           
501     global event_tables                           
502     _event_tables.append(_pending_events_tblna    
503                                                   
504   first = True                                    
505   last_pmu = None                                 
506   last_name = None                                
507   pmus = set()                                    
508   for event in sorted(_pending_events, key=eve    
509     if last_pmu and last_pmu == event.pmu:        
510       assert event.name != last_name, f"Duplic    
511     if event.pmu != last_pmu:                     
512       if not first:                               
513         _args.output_file.write('};\n')           
514       pmu_name = event.pmu.replace(',', '_')      
515       _args.output_file.write(                    
516           f'static const struct compact_pmu_ev    
517       first = False                               
518       last_pmu = event.pmu                        
519       pmus.add((event.pmu, pmu_name))             
520                                                   
521     _args.output_file.write(event.to_c_string(    
522     last_name = event.name                        
523   _pending_events = []                            
524                                                   
525   _args.output_file.write(f"""                    
526 }};                                               
527                                                   
528 const struct pmu_table_entry {_pending_events_    
529 """)                                              
530   for (pmu, tbl_pmu) in sorted(pmus):             
531     pmu_name = f"{pmu}\\000"                      
532     _args.output_file.write(f"""{{                
533      .entries = {_pending_events_tblname}_{tbl    
534      .num_entries = ARRAY_SIZE({_pending_event    
535      .pmu_name = {{ {_bcs.offsets[pmu_name]} /    
536 }},                                               
537 """)                                              
538   _args.output_file.write('};\n\n')               
539                                                   
540 def print_pending_metrics() -> None:              
541   """Optionally close metrics table."""           
542                                                   
543   def metric_cmp_key(j: JsonEvent) -> Tuple[bo    
544     def fix_none(s: Optional[str]) -> str:        
545       if s is None:                               
546         return ''                                 
547       return s                                    
548                                                   
549     return (j.desc is not None, fix_none(j.pmu    
550                                                   
551   global _pending_metrics                         
552   if not _pending_metrics:                        
553     return                                        
554                                                   
555   global _pending_metrics_tblname                 
556   if _pending_metrics_tblname.endswith('_sys')    
557     global _sys_metric_tables                     
558     _sys_metric_tables.append(_pending_metrics    
559   else:                                           
560     global metric_tables                          
561     _metric_tables.append(_pending_metrics_tbl    
562                                                   
563   first = True                                    
564   last_pmu = None                                 
565   pmus = set()                                    
566   for metric in sorted(_pending_metrics, key=m    
567     if metric.pmu != last_pmu:                    
568       if not first:                               
569         _args.output_file.write('};\n')           
570       pmu_name = metric.pmu.replace(',', '_')     
571       _args.output_file.write(                    
572           f'static const struct compact_pmu_ev    
573       first = False                               
574       last_pmu = metric.pmu                       
575       pmus.add((metric.pmu, pmu_name))            
576                                                   
577     _args.output_file.write(metric.to_c_string    
578   _pending_metrics = []                           
579                                                   
580   _args.output_file.write(f"""                    
581 }};                                               
582                                                   
583 const struct pmu_table_entry {_pending_metrics    
584 """)                                              
585   for (pmu, tbl_pmu) in sorted(pmus):             
586     pmu_name = f"{pmu}\\000"                      
587     _args.output_file.write(f"""{{                
588      .entries = {_pending_metrics_tblname}_{tb    
589      .num_entries = ARRAY_SIZE({_pending_metri    
590      .pmu_name = {{ {_bcs.offsets[pmu_name]} /    
591 }},                                               
592 """)                                              
593   _args.output_file.write('};\n\n')               
594                                                   
595 def get_topic(topic: str) -> str:                 
596   if topic.endswith('metrics.json'):              
597     return 'metrics'                              
598   return removesuffix(topic, '.json').replace(    
599                                                   
600 def preprocess_one_file(parents: Sequence[str]    
601                                                   
602   if item.is_dir():                               
603     return                                        
604                                                   
605   # base dir or too deep                          
606   level = len(parents)                            
607   if level == 0 or level > 4:                     
608     return                                        
609                                                   
610   # Ignore other directories. If the file name    
611   # extension, ignore it. It could be a readme    
612   if not item.is_file() or not item.name.endsw    
613     return                                        
614                                                   
615   if item.name == 'metricgroups.json':            
616     metricgroup_descriptions = json.load(open(    
617     for mgroup in metricgroup_descriptions:       
618       assert len(mgroup) > 1, parents             
619       description = f"{metricgroup_description    
620       mgroup = f"{mgroup}\\000"                   
621       _bcs.add(mgroup, metric=True)               
622       _bcs.add(description, metric=True)          
623       _metricgroups[mgroup] = description         
624     return                                        
625                                                   
626   topic = get_topic(item.name)                    
627   for event in read_json_events(item.path, top    
628     pmu_name = f"{event.pmu}\\000"                
629     if event.name:                                
630       _bcs.add(pmu_name, metric=False)            
631       _bcs.add(event.build_c_string(metric=Fal    
632     if event.metric_name:                         
633       _bcs.add(pmu_name, metric=True)             
634       _bcs.add(event.build_c_string(metric=Tru    
635                                                   
636 def process_one_file(parents: Sequence[str], i    
637   """Process a JSON file during the main walk.    
638   def is_leaf_dir_ignoring_sys(path: str) -> b    
639     for item in os.scandir(path):                 
640       if item.is_dir() and item.name != 'sys':    
641         return False                              
642     return True                                   
643                                                   
644   # Model directories are leaves (ignoring pos    
645   # directories). The FTW will walk into the d    
646   # pending events and metrics and update the     
647   # model directory.                              
648   if item.is_dir() and is_leaf_dir_ignoring_sy    
649     print_pending_events()                        
650     print_pending_metrics()                       
651                                                   
652     global _pending_events_tblname                
653     _pending_events_tblname = file_name_to_tab    
654     global _pending_metrics_tblname               
655     _pending_metrics_tblname = file_name_to_ta    
656                                                   
657     if item.name == 'sys':                        
658       _sys_event_table_to_metric_table_mapping    
659     return                                        
660                                                   
661   # base dir or too deep                          
662   level = len(parents)                            
663   if level == 0 or level > 4:                     
664     return                                        
665                                                   
666   # Ignore other directories. If the file name    
667   # extension, ignore it. It could be a readme    
668   if not item.is_file() or not item.name.endsw    
669     return                                        
670                                                   
671   add_events_table_entries(item, get_topic(ite    
672                                                   
673                                                   
674 def print_mapping_table(archs: Sequence[str])     
675   """Read the mapfile and generate the struct     
676   _args.output_file.write("""                     
677 /* Struct used to make the PMU event table imp    
678 struct pmu_events_table {                         
679         const struct pmu_table_entry *pmus;       
680         uint32_t num_pmus;                        
681 };                                                
682                                                   
683 /* Struct used to make the PMU metric table im    
684 struct pmu_metrics_table {                        
685         const struct pmu_table_entry *pmus;       
686         uint32_t num_pmus;                        
687 };                                                
688                                                   
689 /*                                                
690  * Map a CPU to its table of PMU events. The C    
691  * cpuid field, which is an arch-specific iden    
692  * The identifier specified in tools/perf/pmu-    
693  * must match the get_cpuid_str() in tools/per    
694  *                                                
695  * The  cpuid can contain any character other     
696  */                                               
697 struct pmu_events_map {                           
698         const char *arch;                         
699         const char *cpuid;                        
700         struct pmu_events_table event_table;      
701         struct pmu_metrics_table metric_table;    
702 };                                                
703                                                   
704 /*                                                
705  * Global table mapping each known CPU for the    
706  * table of PMU events.                           
707  */                                               
708 const struct pmu_events_map pmu_events_map[] =    
709 """)                                              
710   for arch in archs:                              
711     if arch == 'test':                            
712       _args.output_file.write("""{                
713 \t.arch = "testarch",                             
714 \t.cpuid = "testcpu",                             
715 \t.event_table = {                                
716 \t\t.pmus = pmu_events__test_soc_cpu,             
717 \t\t.num_pmus = ARRAY_SIZE(pmu_events__test_so    
718 \t},                                              
719 \t.metric_table = {                               
720 \t\t.pmus = pmu_metrics__test_soc_cpu,            
721 \t\t.num_pmus = ARRAY_SIZE(pmu_metrics__test_s    
722 \t}                                               
723 },                                                
724 """)                                              
725     else:                                         
726       with open(f'{_args.starting_dir}/{arch}/    
727         table = csv.reader(csvfile)               
728         first = True                              
729         for row in table:                         
730           # Skip the first row or any row begi    
731           if not first and len(row) > 0 and no    
732             event_tblname = file_name_to_table    
733             if event_tblname in _event_tables:    
734               event_size = f'ARRAY_SIZE({event    
735             else:                                 
736               event_tblname = 'NULL'              
737               event_size = '0'                    
738             metric_tblname = file_name_to_tabl    
739             if metric_tblname in _metric_table    
740               metric_size = f'ARRAY_SIZE({metr    
741             else:                                 
742               metric_tblname = 'NULL'             
743               metric_size = '0'                   
744             if event_size == '0' and metric_si    
745               continue                            
746             cpuid = row[0].replace('\\', '\\\\    
747             _args.output_file.write(f"""{{        
748 \t.arch = "{arch}",                               
749 \t.cpuid = "{cpuid}",                             
750 \t.event_table = {{                               
751 \t\t.pmus = {event_tblname},                      
752 \t\t.num_pmus = {event_size}                      
753 \t}},                                             
754 \t.metric_table = {{                              
755 \t\t.pmus = {metric_tblname},                     
756 \t\t.num_pmus = {metric_size}                     
757 \t}}                                              
758 }},                                               
759 """)                                              
760           first = False                           
761                                                   
762   _args.output_file.write("""{                    
763 \t.arch = 0,                                      
764 \t.cpuid = 0,                                     
765 \t.event_table = { 0, 0 },                        
766 \t.metric_table = { 0, 0 },                       
767 }                                                 
768 };                                                
769 """)                                              
770                                                   
771                                                   
772 def print_system_mapping_table() -> None:         
773   """C struct mapping table array for tables f    
774   _args.output_file.write("""                     
775 struct pmu_sys_events {                           
776 \tconst char *name;                               
777 \tstruct pmu_events_table event_table;            
778 \tstruct pmu_metrics_table metric_table;          
779 };                                                
780                                                   
781 static const struct pmu_sys_events pmu_sys_eve    
782 """)                                              
783   printed_metric_tables = []                      
784   for tblname in _sys_event_tables:               
785     _args.output_file.write(f"""\t{{              
786 \t\t.event_table = {{                             
787 \t\t\t.pmus = {tblname},                          
788 \t\t\t.num_pmus = ARRAY_SIZE({tblname})           
789 \t\t}},""")                                       
790     metric_tblname = _sys_event_table_to_metri    
791     if metric_tblname in _sys_metric_tables:      
792       _args.output_file.write(f"""                
793 \t\t.metric_table = {{                            
794 \t\t\t.pmus = {metric_tblname},                   
795 \t\t\t.num_pmus = ARRAY_SIZE({metric_tblname})    
796 \t\t}},""")                                       
797       printed_metric_tables.append(metric_tbln    
798     _args.output_file.write(f"""                  
799 \t\t.name = \"{tblname}\",                        
800 \t}},                                             
801 """)                                              
802   for tblname in _sys_metric_tables:              
803     if tblname in printed_metric_tables:          
804       continue                                    
805     _args.output_file.write(f"""\t{{              
806 \t\t.metric_table = {{                            
807 \t\t\t.pmus = {tblname},                          
808 \t\t\t.num_pmus = ARRAY_SIZE({tblname})           
809 \t\t}},                                           
810 \t\t.name = \"{tblname}\",                        
811 \t}},                                             
812 """)                                              
813   _args.output_file.write("""\t{                  
814 \t\t.event_table = { 0, 0 },                      
815 \t\t.metric_table = { 0, 0 },                     
816 \t},                                              
817 };                                                
818                                                   
819 static void decompress_event(int offset, struc    
820 {                                                 
821 \tconst char *p = &big_c_string[offset];          
822 """)                                              
823   for attr in _json_event_attributes:             
824     _args.output_file.write(f'\n\tpe->{attr} =    
825     if attr in _json_enum_attributes:             
826       _args.output_file.write("*p - '0';\n")      
827     else:                                         
828       _args.output_file.write("(*p == '\\0' ?     
829     if attr == _json_event_attributes[-1]:        
830       continue                                    
831     if attr in _json_enum_attributes:             
832       _args.output_file.write('\tp++;')           
833     else:                                         
834       _args.output_file.write('\twhile (*p++);    
835   _args.output_file.write("""}                    
836                                                   
837 static void decompress_metric(int offset, stru    
838 {                                                 
839 \tconst char *p = &big_c_string[offset];          
840 """)                                              
841   for attr in _json_metric_attributes:            
842     _args.output_file.write(f'\n\tpm->{attr} =    
843     if attr in _json_enum_attributes:             
844       _args.output_file.write("*p - '0';\n")      
845     else:                                         
846       _args.output_file.write("(*p == '\\0' ?     
847     if attr == _json_metric_attributes[-1]:       
848       continue                                    
849     if attr in _json_enum_attributes:             
850       _args.output_file.write('\tp++;')           
851     else:                                         
852       _args.output_file.write('\twhile (*p++);    
853   _args.output_file.write("""}                    
854                                                   
855 static int pmu_events_table__for_each_event_pm    
856                                                   
857                                                   
858                                                   
859 {                                                 
860         int ret;                                  
861         struct pmu_event pe = {                   
862                 .pmu = &big_c_string[pmu->pmu_    
863         };                                        
864                                                   
865         for (uint32_t i = 0; i < pmu->num_entr    
866                 decompress_event(pmu->entries[    
867                 if (!pe.name)                     
868                         continue;                 
869                 ret = fn(&pe, table, data);       
870                 if (ret)                          
871                         return ret;               
872         }                                         
873         return 0;                                 
874  }                                                
875                                                   
876 static int pmu_events_table__find_event_pmu(co    
877                                             co    
878                                             co    
879                                             pm    
880                                             vo    
881 {                                                 
882         struct pmu_event pe = {                   
883                 .pmu = &big_c_string[pmu->pmu_    
884         };                                        
885         int low = 0, high = pmu->num_entries -    
886                                                   
887         while (low <= high) {                     
888                 int cmp, mid = (low + high) /     
889                                                   
890                 decompress_event(pmu->entries[    
891                                                   
892                 if (!pe.name && !name)            
893                         goto do_call;             
894                                                   
895                 if (!pe.name && name) {           
896                         low = mid + 1;            
897                         continue;                 
898                 }                                 
899                 if (pe.name && !name) {           
900                         high = mid - 1;           
901                         continue;                 
902                 }                                 
903                                                   
904                 cmp = strcasecmp(pe.name, name    
905                 if (cmp < 0) {                    
906                         low = mid + 1;            
907                         continue;                 
908                 }                                 
909                 if (cmp > 0) {                    
910                         high = mid - 1;           
911                         continue;                 
912                 }                                 
913   do_call:                                        
914                 return fn ? fn(&pe, table, dat    
915         }                                         
916         return PMU_EVENTS__NOT_FOUND;             
917 }                                                 
918                                                   
919 int pmu_events_table__for_each_event(const str    
920                                     struct per    
921                                     pmu_event_    
922                                     void *data    
923 {                                                 
924         for (size_t i = 0; i < table->num_pmus    
925                 const struct pmu_table_entry *    
926                 const char *pmu_name = &big_c_    
927                 int ret;                          
928                                                   
929                 if (pmu && !pmu__name_match(pm    
930                         continue;                 
931                                                   
932                 ret = pmu_events_table__for_ea    
933                 if (pmu || ret)                   
934                         return ret;               
935         }                                         
936         return 0;                                 
937 }                                                 
938                                                   
939 int pmu_events_table__find_event(const struct     
940                                  struct perf_p    
941                                  const char *n    
942                                  pmu_event_ite    
943                                  void *data)      
944 {                                                 
945         for (size_t i = 0; i < table->num_pmus    
946                 const struct pmu_table_entry *    
947                 const char *pmu_name = &big_c_    
948                 int ret;                          
949                                                   
950                 if (!pmu__name_match(pmu, pmu_    
951                         continue;                 
952                                                   
953                 ret = pmu_events_table__find_e    
954                 if (ret != PMU_EVENTS__NOT_FOU    
955                         return ret;               
956         }                                         
957         return PMU_EVENTS__NOT_FOUND;             
958 }                                                 
959                                                   
960 size_t pmu_events_table__num_events(const stru    
961                                     struct per    
962 {                                                 
963         size_t count = 0;                         
964                                                   
965         for (size_t i = 0; i < table->num_pmus    
966                 const struct pmu_table_entry *    
967                 const char *pmu_name = &big_c_    
968                                                   
969                 if (pmu__name_match(pmu, pmu_n    
970                         count += table_pmu->nu    
971         }                                         
972         return count;                             
973 }                                                 
974                                                   
975 static int pmu_metrics_table__for_each_metric_    
976                                                   
977                                                   
978                                                   
979 {                                                 
980         int ret;                                  
981         struct pmu_metric pm = {                  
982                 .pmu = &big_c_string[pmu->pmu_    
983         };                                        
984                                                   
985         for (uint32_t i = 0; i < pmu->num_entr    
986                 decompress_metric(pmu->entries    
987                 if (!pm.metric_expr)              
988                         continue;                 
989                 ret = fn(&pm, table, data);       
990                 if (ret)                          
991                         return ret;               
992         }                                         
993         return 0;                                 
994 }                                                 
995                                                   
996 int pmu_metrics_table__for_each_metric(const s    
997                                      pmu_metri    
998                                      void *dat    
999 {                                                 
1000         for (size_t i = 0; i < table->num_pmu    
1001                 int ret = pmu_metrics_table__    
1002                                                  
1003                                                  
1004                 if (ret)                         
1005                         return ret;              
1006         }                                        
1007         return 0;                                
1008 }                                                
1009                                                  
1010 static const struct pmu_events_map *map_for_p    
1011 {                                                
1012         static struct {                          
1013                 const struct pmu_events_map *    
1014                 struct perf_pmu *pmu;            
1015         } last_result;                           
1016         static struct {                          
1017                 const struct pmu_events_map *    
1018                 char *cpuid;                     
1019         } last_map_search;                       
1020         static bool has_last_result, has_last    
1021         const struct pmu_events_map *map = NU    
1022         char *cpuid = NULL;                      
1023         size_t i;                                
1024                                                  
1025         if (has_last_result && last_result.pm    
1026                 return last_result.map;          
1027                                                  
1028         cpuid = perf_pmu__getcpuid(pmu);         
1029                                                  
1030         /*                                       
1031          * On some platforms which uses cpus     
1032          * PMUs other than CORE PMUs.            
1033          */                                      
1034         if (!cpuid)                              
1035                 goto out_update_last_result;     
1036                                                  
1037         if (has_last_map_search && !strcmp(la    
1038                 map = last_map_search.map;       
1039                 free(cpuid);                     
1040         } else {                                 
1041                 i = 0;                           
1042                 for (;;) {                       
1043                         map = &pmu_events_map    
1044                                                  
1045                         if (!map->arch) {        
1046                                 map = NULL;      
1047                                 break;           
1048                         }                        
1049                                                  
1050                         if (!strcmp_cpuid_str    
1051                                 break;           
1052                }                                 
1053                free(last_map_search.cpuid);      
1054                last_map_search.cpuid = cpuid;    
1055                last_map_search.map = map;        
1056                has_last_map_search = true;       
1057         }                                        
1058 out_update_last_result:                          
1059         last_result.pmu = pmu;                   
1060         last_result.map = map;                   
1061         has_last_result = true;                  
1062         return map;                              
1063 }                                                
1064                                                  
1065 const struct pmu_events_table *perf_pmu__find    
1066 {                                                
1067         const struct pmu_events_map *map = ma    
1068                                                  
1069         if (!map)                                
1070                 return NULL;                     
1071                                                  
1072         if (!pmu)                                
1073                 return &map->event_table;        
1074                                                  
1075         for (size_t i = 0; i < map->event_tab    
1076                 const struct pmu_table_entry     
1077                 const char *pmu_name = &big_c    
1078                                                  
1079                 if (pmu__name_match(pmu, pmu_    
1080                          return &map->event_t    
1081         }                                        
1082         return NULL;                             
1083 }                                                
1084                                                  
1085 const struct pmu_metrics_table *perf_pmu__fin    
1086 {                                                
1087         const struct pmu_events_map *map = ma    
1088                                                  
1089         if (!map)                                
1090                 return NULL;                     
1091                                                  
1092         if (!pmu)                                
1093                 return &map->metric_table;       
1094                                                  
1095         for (size_t i = 0; i < map->metric_ta    
1096                 const struct pmu_table_entry     
1097                 const char *pmu_name = &big_c    
1098                                                  
1099                 if (pmu__name_match(pmu, pmu_    
1100                            return &map->metri    
1101         }                                        
1102         return NULL;                             
1103 }                                                
1104                                                  
1105 const struct pmu_events_table *find_core_even    
1106 {                                                
1107         for (const struct pmu_events_map *tab    
1108              tables->arch;                       
1109              tables++) {                         
1110                 if (!strcmp(tables->arch, arc    
1111                         return &tables->event    
1112         }                                        
1113         return NULL;                             
1114 }                                                
1115                                                  
1116 const struct pmu_metrics_table *find_core_met    
1117 {                                                
1118         for (const struct pmu_events_map *tab    
1119              tables->arch;                       
1120              tables++) {                         
1121                 if (!strcmp(tables->arch, arc    
1122                         return &tables->metri    
1123         }                                        
1124         return NULL;                             
1125 }                                                
1126                                                  
1127 int pmu_for_each_core_event(pmu_event_iter_fn    
1128 {                                                
1129         for (const struct pmu_events_map *tab    
1130              tables->arch;                       
1131              tables++) {                         
1132                 int ret = pmu_events_table__f    
1133                                                  
1134                                                  
1135                 if (ret)                         
1136                         return ret;              
1137         }                                        
1138         return 0;                                
1139 }                                                
1140                                                  
1141 int pmu_for_each_core_metric(pmu_metric_iter_    
1142 {                                                
1143         for (const struct pmu_events_map *tab    
1144              tables->arch;                       
1145              tables++) {                         
1146                 int ret = pmu_metrics_table__    
1147                                                  
1148                 if (ret)                         
1149                         return ret;              
1150         }                                        
1151         return 0;                                
1152 }                                                
1153                                                  
1154 const struct pmu_events_table *find_sys_event    
1155 {                                                
1156         for (const struct pmu_sys_events *tab    
1157              tables->name;                       
1158              tables++) {                         
1159                 if (!strcmp(tables->name, nam    
1160                         return &tables->event    
1161         }                                        
1162         return NULL;                             
1163 }                                                
1164                                                  
1165 int pmu_for_each_sys_event(pmu_event_iter_fn     
1166 {                                                
1167         for (const struct pmu_sys_events *tab    
1168              tables->name;                       
1169              tables++) {                         
1170                 int ret = pmu_events_table__f    
1171                                                  
1172                                                  
1173                 if (ret)                         
1174                         return ret;              
1175         }                                        
1176         return 0;                                
1177 }                                                
1178                                                  
1179 int pmu_for_each_sys_metric(pmu_metric_iter_f    
1180 {                                                
1181         for (const struct pmu_sys_events *tab    
1182              tables->name;                       
1183              tables++) {                         
1184                 int ret = pmu_metrics_table__    
1185                                                  
1186                 if (ret)                         
1187                         return ret;              
1188         }                                        
1189         return 0;                                
1190 }                                                
1191 """)                                             
1192                                                  
1193 def print_metricgroups() -> None:                
1194   _args.output_file.write("""                    
1195 static const int metricgroups[][2] = {           
1196 """)                                             
1197   for mgroup in sorted(_metricgroups):           
1198     description = _metricgroups[mgroup]          
1199     _args.output_file.write(                     
1200         f'\t{{ {_bcs.offsets[mgroup]}, {_bcs.    
1201     )                                            
1202   _args.output_file.write("""                    
1203 };                                               
1204                                                  
1205 const char *describe_metricgroup(const char *    
1206 {                                                
1207         int low = 0, high = (int)ARRAY_SIZE(m    
1208                                                  
1209         while (low <= high) {                    
1210                 int mid = (low + high) / 2;      
1211                 const char *mgroup = &big_c_s    
1212                 int cmp = strcmp(mgroup, grou    
1213                                                  
1214                 if (cmp == 0) {                  
1215                         return &big_c_string[    
1216                 } else if (cmp < 0) {            
1217                         low = mid + 1;           
1218                 } else {                         
1219                         high = mid - 1;          
1220                 }                                
1221         }                                        
1222         return NULL;                             
1223 }                                                
1224 """)                                             
1225                                                  
1226 def main() -> None:                              
1227   global _args                                   
1228                                                  
1229   def dir_path(path: str) -> str:                
1230     """Validate path is a directory for argpa    
1231     if os.path.isdir(path):                      
1232       return path                                
1233     raise argparse.ArgumentTypeError(f'\'{pat    
1234                                                  
1235   def ftw(path: str, parents: Sequence[str],     
1236           action: Callable[[Sequence[str], os    
1237     """Replicate the directory/file walking b    
1238     for item in sorted(os.scandir(path), key=    
1239       if _args.model != 'all' and item.is_dir    
1240         # Check if the model matches one in _    
1241         if len(parents) == _args.model.split(    
1242           # We're testing the correct directo    
1243           item_path = '/'.join(parents) + ('/    
1244           if 'test' not in item_path and item    
1245             continue                             
1246       action(parents, item)                      
1247       if item.is_dir():                          
1248         ftw(item.path, parents + [item.name],    
1249                                                  
1250   ap = argparse.ArgumentParser()                 
1251   ap.add_argument('arch', help='Architecture     
1252   ap.add_argument('model', help='''Select a m    
1253 reduce the code size.  Normally set to "all".    
1254 ARM64 with an implementor/model, the model mu    
1255 such as "arm/cortex-a34".''',                    
1256                   default='all')                 
1257   ap.add_argument(                               
1258       'starting_dir',                            
1259       type=dir_path,                             
1260       help='Root of tree containing architect    
1261   )                                              
1262   ap.add_argument(                               
1263       'output_file', type=argparse.FileType('    
1264   _args = ap.parse_args()                        
1265                                                  
1266   _args.output_file.write(f"""                   
1267 /* SPDX-License-Identifier: GPL-2.0 */           
1268 /* THIS FILE WAS AUTOGENERATED BY jevents.py     
1269 """)                                             
1270   _args.output_file.write("""                    
1271 #include <pmu-events/pmu-events.h>               
1272 #include "util/header.h"                         
1273 #include "util/pmu.h"                            
1274 #include <string.h>                              
1275 #include <stddef.h>                              
1276                                                  
1277 struct compact_pmu_event {                       
1278         int offset;                              
1279 };                                               
1280                                                  
1281 struct pmu_table_entry {                         
1282         const struct compact_pmu_event *entri    
1283         uint32_t num_entries;                    
1284         struct compact_pmu_event pmu_name;       
1285 };                                               
1286                                                  
1287 """)                                             
1288   archs = []                                     
1289   for item in os.scandir(_args.starting_dir):    
1290     if not item.is_dir():                        
1291       continue                                   
1292     if item.name == _args.arch or _args.arch     
1293       archs.append(item.name)                    
1294                                                  
1295   if len(archs) < 2 and _args.arch != 'none':    
1296     raise IOError(f'Missing architecture dire    
1297                                                  
1298   archs.sort()                                   
1299   for arch in archs:                             
1300     arch_path = f'{_args.starting_dir}/{arch}    
1301     preprocess_arch_std_files(arch_path)         
1302     ftw(arch_path, [], preprocess_one_file)      
1303                                                  
1304   _bcs.compute()                                 
1305   _args.output_file.write('static const char     
1306   for s in _bcs.big_string:                      
1307     _args.output_file.write(s)                   
1308   _args.output_file.write(';\n\n')               
1309   for arch in archs:                             
1310     arch_path = f'{_args.starting_dir}/{arch}    
1311     ftw(arch_path, [], process_one_file)         
1312     print_pending_events()                       
1313     print_pending_metrics()                      
1314                                                  
1315   print_mapping_table(archs)                     
1316   print_system_mapping_table()                   
1317   print_metricgroups()                           
1318                                                  
1319 if __name__ == '__main__':                       
1320   main()                                         
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php