Files

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()