| from abc import ABC, abstractmethod |
| |
| # Enums are slow |
| THREAD_STATE_RUNNING = 0 |
| THREAD_STATE_IDLE = 1 |
| THREAD_STATE_GIL_WAIT = 2 |
| THREAD_STATE_UNKNOWN = 3 |
| |
| STATUS = { |
| THREAD_STATE_RUNNING: "running", |
| THREAD_STATE_IDLE: "idle", |
| THREAD_STATE_GIL_WAIT: "gil_wait", |
| THREAD_STATE_UNKNOWN: "unknown", |
| } |
| |
| class Collector(ABC): |
| @abstractmethod |
| def collect(self, stack_frames): |
| """Collect profiling data from stack frames.""" |
| |
| @abstractmethod |
| def export(self, filename): |
| """Export collected data to a file.""" |
| |
| def _iter_all_frames(self, stack_frames, skip_idle=False): |
| """Iterate over all frame stacks from all interpreters and threads.""" |
| for interpreter_info in stack_frames: |
| for thread_info in interpreter_info.threads: |
| if skip_idle and thread_info.status != THREAD_STATE_RUNNING: |
| continue |
| frames = thread_info.frame_info |
| if frames: |
| yield frames, thread_info.thread_id |