#!/usr/bin/env python3
import os
import sys
# ---- EXACT CCD mapping provided by you ----
CCD0_CPUS = set([0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23])
CCD1_CPUS = set([8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31])
def get_ccd(cpu_id):
if cpu_id in CCD0_CPUS:
return "CCD0"
elif cpu_id in CCD1_CPUS:
return "CCD1"
else:
return "Unknown"
def get_process_name(pid):
try:
with open(f"/proc/{pid}/comm") as f:
return f.read().strip()
except Exception:
return "Unknown"
def main():
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <PID>")
sys.exit(1)
pid = sys.argv[1]
task_dir = f"/proc/{pid}/task"
if not os.path.exists(task_dir):
#print(f"PID {pid} does not exist.")
sys.exit(1)
process_name = get_process_name(pid)
threads_info = []
ccds_present = set()
for tid in os.listdir(task_dir):
stat_file = f"{task_dir}/{tid}/stat"
try:
with open(stat_file) as f:
stat = f.read().split()
cpu_id = int(stat[38]) # last CPU the thread ran on
if cpu_id == -1:
continue # ignore idle/unassigned threads
ccd = get_ccd(cpu_id)
threads_info.append((tid, cpu_id, ccd))
ccds_present.add(ccd)
except Exception:
continue
# Only print if threads exist on both CCDs
if "CCD0" in ccds_present and "CCD1" in ccds_present:
print(f"Process '{process_name}' (PID {pid}) has threads active on both CCDs:\n")
print(f"{'TID':>6} {'CPU':>3} {'CCD':>5} {'Process'}")
print("-"*35)
for tid, cpu, ccd in threads_info:
print(f"{tid:>6} {cpu:>3} {ccd:>5} {process_name}")
if __name__ == "__main__":
main()