| 106 | yield frames, thread_info.thread_id |
| 107 | |
| 108 | def _iter_async_frames(self, awaited_info_list): |
| 109 | # Phase 1: Index tasks and build parent relationships with pre-computed selection |
| 110 | task_map, child_to_parent, all_task_ids, all_parent_ids = self._build_task_graph(awaited_info_list) |
| 111 | |
| 112 | # Phase 2: Find leaf tasks (tasks not awaited by anyone) |
| 113 | leaf_task_ids = self._find_leaf_tasks(all_task_ids, all_parent_ids) |
| 114 | |
| 115 | # Phase 3: Build linear stacks from each leaf to root (optimized - no sorting!) |
| 116 | yield from self._build_linear_stacks(leaf_task_ids, task_map, child_to_parent) |
| 117 | |
| 118 | def _iter_stacks(self, stack_frames, skip_idle=False): |
| 119 | """Yield (frames, thread_id) for all stacks, handling both sync and async modes.""" |