63 lines
2.1 KiB
Python
63 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""hotips.py — sample thread RIPs aggressively during the render burst to find
|
|
which module code actually executes (the real DSP path)."""
|
|
import collections
|
|
import glob
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
MOD_LO, MOD_HI = 0x180001000, 0x181baa000
|
|
|
|
|
|
def find_host():
|
|
for p in glob.glob('/proc/[0-9]*'):
|
|
pid = int(os.path.basename(p))
|
|
try:
|
|
cmd = open(f'/proc/{pid}/cmdline', 'rb').read().replace(b'\0', b' ').decode('utf8', 'replace')
|
|
maps = open(f'/proc/{pid}/maps').read()
|
|
except Exception:
|
|
continue
|
|
if 'soothe2' in maps and 'reaper' not in cmd:
|
|
return pid
|
|
return None
|
|
|
|
|
|
def main():
|
|
subprocess.run("pkill -9 -x reaper; pkill -9 -f '[y]abridge'; sleep 1", shell=True)
|
|
proc = subprocess.Popen(['/usr/bin/reaper', '-nosplash', '-ignoreerrors',
|
|
'-renderproject', '/home/m/soothe-bt/dual_b1q_0.5.rpp'],
|
|
stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT)
|
|
host = None
|
|
t0 = time.time()
|
|
while time.time() - t0 < 30 and not host:
|
|
host = find_host()
|
|
time.sleep(0.002)
|
|
print('host', host, 'at %.3fs' % (time.time() - t0))
|
|
ips = collections.Counter()
|
|
t_end = time.time() + float(os.environ.get('HOT_DUR', '6'))
|
|
n_ok = n_fail = 0
|
|
while time.time() < t_end:
|
|
for tid_s in glob.glob(f'/proc/{host}/task/*'):
|
|
try:
|
|
parts = open(f'{tid_s}/syscall').read().split()
|
|
ip = int(parts[-1], 16)
|
|
n_ok += 1
|
|
if MOD_LO <= ip < MOD_HI:
|
|
ips[ip] += 1
|
|
except Exception:
|
|
n_fail += 1
|
|
proc.kill()
|
|
print('samples ok=%d fail=%d, in-module=%d' % (n_ok, n_fail, sum(ips.values())))
|
|
# bucket to 64-byte lines, aggregate by function-ish regions
|
|
agg = collections.Counter()
|
|
for ip, c in ips.items():
|
|
agg[(ip >> 6) << 6] += c
|
|
for addr, c in agg.most_common(40):
|
|
print('%#x %d' % (addr, c))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|