Skip to content
This repository was archived by the owner on May 29, 2025. It is now read-only.

Commit 73e048f

Browse files
committed
Python 3 compatibility and other fixups
etwpmc_parser.py wouldn't run with Python 3. That is now fixed. It also violated Google Python style guide recommendations in many ways, including excessive use of double quotes. That is also fixed. The summarizing code also didn't print counters after the first two.
1 parent c50d40c commit 73e048f

1 file changed

Lines changed: 52 additions & 37 deletions

File tree

LabScripts/ETWPMCDemo/etwpmc_parser.py

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,17 @@
6262
6363
"""
6464

65+
from __future__ import print_function
66+
6567
import re
6668
import sys
6769

6870
if len(sys.argv) <= 1:
69-
print 'Usage: %s xperfoutput [processname]' % sys.argv[0]
70-
print 'The first parameter is the name of a file containing the results'
71-
print 'of "xperf -i trace.etl". The second (optional) parameter is a'
72-
print 'process name substring filter used to restrict which results are'
73-
print 'shown - only processes that match are displayed.'
71+
print('Usage: %s xperfoutput [processname]' % sys.argv[0])
72+
print('The first parameter is the name of a file containing the results')
73+
print('of "xperf -i trace.etl". The second (optional) parameter is a')
74+
print('process name substring filter used to restrict which results are')
75+
print('shown - only processes that match are displayed.')
7476
sys.exit(0)
7577

7678
xperfoutputfilename = sys.argv[1]
@@ -95,37 +97,39 @@
9597
description = None
9698

9799
for x in range(len(l) - 1):
98-
if l[x].startswith(" Pmc,"):
99-
pmc_parts = l[x].split(",")
100+
if l[x].startswith(' Pmc,'):
101+
pmc_parts = l[x].split(',')
100102
if not description:
101103
# Grab the description of the Pmc counter records, see how many counters
102104
# there are, and print the description.
103105
num_counters = len(pmc_parts) - 3
104106
description = l[x].strip()
105107
continue
106-
counters = map(int, pmc_parts[3:])
108+
counters = list(map(int, pmc_parts[3:]))
109+
assert(len(counters) == num_counters)
107110
# Look for a CSwitch line. Ideally it will be next, but sometimes an Error: line
108111
# might be in-between.
109-
cswitch_line = ""
110-
if l[x+1].startswith(" CSwitch,"):
112+
cswitch_line = ''
113+
if l[x+1].startswith(' CSwitch,'):
111114
cswitch_line = l[x+1]
112-
elif l[x+1].startswith("Error: ") and l[x+2].startswith(" CSwitch,"):
115+
elif l[x+1].startswith('Error: ') and l[x+2].startswith(' CSwitch,'):
113116
cswitch_line = l[x+2]
114117
if cswitch_line:
115-
cswitch_parts = cswitch_line.split(",")
118+
cswitch_parts = cswitch_line.split(',')
116119
CPU = int(cswitch_parts[16].strip())
117120
process = cswitch_parts[2].strip()
118121
timeStamp = int(cswitch_parts[1])
119122
# See if we've got previous Pmc records for this CPU:
120-
if countersByCPU.has_key(CPU):
121-
diffs = map(lambda a,b : a - b, counters, countersByCPU[CPU])
123+
if CPU in countersByCPU:
124+
diffs = list(map(lambda a,b : a - b, counters, countersByCPU[CPU]))
122125
old_process = cswitch_parts[8].strip()
123126
# Sanity checking...
124127
if old_process != processByCPU[CPU]:
125-
print "Old process mismatch at line %d, %s versus %s" % (x, old_process, processByCPU[CPU])
128+
print('Old process mismatch at line %d, %s versus %s' % (x, old_process, processByCPU[CPU]))
126129
sys.exit(0)
127-
if old_process != "Idle ( 0)":
128-
countersByProcess[old_process] = map(lambda x, y: x + y, countersByProcess.get(old_process, num_counters * [0]), diffs)
130+
if old_process != 'Idle ( 0)':
131+
countersByProcess[old_process] = list(map(lambda x, y: x + y, countersByProcess.get(old_process, num_counters * [0]), diffs))
132+
assert(len(countersByProcess[old_process]) == num_counters)
129133
contextSwitchesByProcess[old_process] = contextSwitchesByProcess.get(old_process, 0) + 1
130134
cpuTimeByProcess[old_process] = cpuTimeByProcess.get(old_process, 0) + (timeStamp - lastCSwitchTimeByCPU[CPU])
131135

@@ -134,51 +138,62 @@
134138
countersByCPU[CPU] = counters
135139
lastLineByCPU[CPU] = x
136140
else:
137-
print "Missing cswitch line at line %d" % x
141+
print('Missing cswitch line at line %d' % x)
138142
sys.exit(0)
139143

140144
if len(sys.argv) == 2:
141145
mincounter = 500000
142-
print 'Printing collated data for process names where the second counter exceeds %d' % mincounter
146+
print('Printing collated data for process names where the second counter exceeds %d' % mincounter)
143147
else:
144148
substring = sys.argv[2].lower()
145-
print 'Printing per-process-data for processes that contain "%s"' % substring
149+
print('Printing per-process-data for processes that contain "%s"' % substring)
146150

147-
counterDescription = "<unknown counters>"
151+
counterDescription = '<unknown counters>'
148152
if description:
149153
counterDescription = ',' + ','.join(description.split(',')[3:])
150154

151-
print "%43s: cnt1/cnt2%s" % ("Process name", counterDescription)
155+
format = '%43s: %6.2f%%, [' + ','.join(4 * ['%10d']) + '], %5d context switches, time: %8d'
156+
157+
print('%43s: cnt1/cnt2%s' % ('Process name', counterDescription))
152158
procnameTotals = {}
153159
for process in countersByProcess.keys():
154160
totals = countersByProcess[process]
161+
assert(len(totals) == num_counters)
155162
# Extract the .exe name and separate it from the PID.
156-
match = re.match(r"(.*).exe \(\d+\)", process)
163+
match = re.match(r'(.*).exe \(\d+\)', process)
164+
summarizeByName = True
165+
if len(sys.argv) > 2:
166+
# If we are filtering to a specific process name then we cannot
167+
# also summarize by name.
168+
summarizeByName = False
157169
if match:
158-
procname = match.groups()[0]
159-
counter0, counter1, contextSwitches, cpuTime = procnameTotals.get(procname, (0, 0, 0, 0))
160-
procnameTotals[procname] = (counter0 + totals[0],
161-
counter1 + totals[1],
162-
contextSwitches + contextSwitchesByProcess[process],
163-
cpuTime + cpuTimeByProcess[process])
170+
if summarizeByName:
171+
procname = match.groups()[0]
172+
else:
173+
procname = process
174+
# First num_counters values are the CPU performance counters. The next two are contextSwitches and cpuTime.
175+
data = procnameTotals.get(procname, (num_counters + 2) * [0])
176+
# Extend the totals list so that it also contains contextSwitches and cpuTime
177+
totals += [contextSwitchesByProcess[process], cpuTimeByProcess[process]]
178+
procnameTotals[procname] = list(map(lambda x, y: x + y, data, totals))
164179
# Filter to the specific process substring if requested.
165180
if len(sys.argv) > 2 and process.lower().count(substring) > 0:
166-
print "%43s: %5.2f%%, [%9d,%11d], %5d context switches, time: %8d" % (process,
167-
totals[0] * 100.0 / totals[1], totals[0], totals[1],
168-
contextSwitchesByProcess[process], cpuTimeByProcess[process])
181+
totals0, totals1 = procnameTotals[procname][:2]
182+
args = tuple([procname, totals0 * 100.0 / totals1] + procnameTotals[procname])
183+
print(format % args)
169184

170185
if len(sys.argv) == 2:
171186
# Put one of the values and the keys into tuples, sort by the selected
172187
# value, extract back out into two lists and grab the keys, which are
173188
# now sorted by the specified value. The index in the map lambda specifies
174189
# which of the values from the stored tuple is used for sorting.
175-
sortingValues = map(lambda x: x[3], procnameTotals.values())
176-
orderedKeys = list(zip(*sorted(zip(sortingValues, procnameTotals.keys())))[1])
190+
sortingValues = list(map(lambda x: x[3], procnameTotals.values()))
191+
orderedKeys = list(list(zip(*sorted(zip(sortingValues, procnameTotals.keys()))))[1])
177192
orderedKeys.reverse()
178193

179194
for procname in orderedKeys:
180-
totals0, totals1, contextSwitches, cpuTime = procnameTotals[procname]
195+
totals0, totals1 = procnameTotals[procname][:2]
181196
# Arbitrary filtering to just get the most interesting data.
182197
if totals1 > mincounter:
183-
print "%43s: %5.2f%%, [%9d,%11d], %5d context switches, time: %8d" % (procname,
184-
totals0 * 100.0 / totals1, totals0, totals1, contextSwitches, cpuTime)
198+
args = tuple([procname, totals0 * 100.0 / totals1] + procnameTotals[procname])
199+
print(format % args)

0 commit comments

Comments
 (0)