Implemented qt port + e2e
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
proc_perf.py — Snapshot a live process's CPU time and peak memory from /proc.
|
||||
|
||||
Usage: proc_perf.py <pid> <label> <out.json>
|
||||
|
||||
Reads /proc/<pid>/stat (utime+stime, in clock ticks) and /proc/<pid>/status
|
||||
(VmHWM = peak resident set, VmRSS = current) *while the process is alive* — peak
|
||||
RSS is only legible before the process exits, so the orchestrator calls this just
|
||||
before tearing the stack down. Emits a small JSON record:
|
||||
|
||||
{"label": ..., "avail": true, "cpu_s": float, "peak_rss_kb": int,
|
||||
"rss_kb": int, "threads": int}
|
||||
|
||||
If the process is already gone, writes {"label": ..., "avail": false}.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def _clk_tck():
|
||||
try:
|
||||
return os.sysconf("SC_CLK_TCK") or 100
|
||||
except (ValueError, OSError):
|
||||
return 100
|
||||
|
||||
|
||||
def snapshot(pid):
|
||||
stat_p = f"/proc/{pid}/stat"
|
||||
status_p = f"/proc/{pid}/status"
|
||||
if not os.path.exists(stat_p):
|
||||
return {"avail": False}
|
||||
try:
|
||||
with open(stat_p) as f:
|
||||
raw = f.read()
|
||||
# The comm field is parenthesised and may contain spaces/parens, so split
|
||||
# on the final ')': everything after it is space-separated, with state as
|
||||
# the first token. utime/stime are overall fields 14/15 → indices 11/12
|
||||
# of the post-')' tokens (pid + comm consumed before the split).
|
||||
after = raw[raw.rindex(")") + 1:].split()
|
||||
utime = int(after[11])
|
||||
stime = int(after[12])
|
||||
cpu_s = (utime + stime) / float(_clk_tck())
|
||||
rec: dict = {"avail": True, "cpu_s": cpu_s}
|
||||
with open(status_p) as f:
|
||||
for line in f:
|
||||
if line.startswith("VmHWM:"):
|
||||
rec["peak_rss_kb"] = int(line.split()[1])
|
||||
elif line.startswith("VmRSS:"):
|
||||
rec["rss_kb"] = int(line.split()[1])
|
||||
elif line.startswith("Threads:"):
|
||||
rec["threads"] = int(line.split()[1])
|
||||
return rec
|
||||
except (OSError, ValueError, IndexError):
|
||||
return {"avail": False}
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print("usage: proc_perf.py <pid> <label> <out.json>", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
pid, label, out = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
rec = snapshot(pid)
|
||||
rec["label"] = label
|
||||
with open(out, "w") as f:
|
||||
json.dump(rec, f)
|
||||
if rec.get("avail"):
|
||||
print(f"perf {label}: cpu={rec.get('cpu_s', 0):.2f}s "
|
||||
f"peakRSS={rec.get('peak_rss_kb', 0)/1024:.1f}MB")
|
||||
else:
|
||||
print(f"perf {label}: unavailable (process gone)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user