[ui]: Add a debug track for a thread's critical path automatically
Added a 'critical path' button to the thread_state_tab that will
automatically generate the critical path for the entire thread
and create a debug track with that info.
The first click in a trace is a bit slow since it imports the
experimental.thread_executing_span stdlib module. But subsequent
clicks are instant.
Test: Manual
Change-Id: I803052606d46187ea6d80061735053cdb11c8743
diff --git a/ui/src/frontend/thread_state_tab.ts b/ui/src/frontend/thread_state_tab.ts
index 485b402..2768393 100644
--- a/ui/src/frontend/thread_state_tab.ts
+++ b/ui/src/frontend/thread_state_tab.ts
@@ -14,8 +14,10 @@
import m from 'mithril';
+import {runQuery} from '../common/queries';
import {Duration, time} from '../common/time';
import {raf} from '../core/raf_scheduler';
+import {addDebugTrack} from '../tracks/debug/slice_track';
import {Anchor} from './anchor';
import {BottomTab, bottomTabRegistry, NewBottomTabArgs} from './bottom_tab';
@@ -33,6 +35,7 @@
ThreadState,
ThreadStateRef,
} from './thread_state';
+import {Button} from './widgets/button';
import {DetailsShell} from './widgets/details_shell';
import {DurationWidget} from './widgets/duration';
import {GridLayout} from './widgets/grid_layout';
@@ -226,10 +229,11 @@
utid: state.thread!.utid,
name,
});
+ const sliceColumns = {ts: 'ts', dur: 'dur', name: 'thread_name'};
const nameForNextOrPrev = (state: ThreadState) =>
`${state.state} for ${Duration.humanise(state.dur)}`;
- return m(
+ return [m(
Tree,
this.relatedStates.waker && m(TreeNode, {
left: 'Waker',
@@ -263,8 +267,27 @@
}),
right: renderRef(
state, getFullThreadName(state.thread)),
- })))),
- );
+ })))),
+ ), m(Button,
+ {
+ label: 'Critical path',
+ onclick: () => runQuery(`SELECT IMPORT('experimental.thread_executing_span');`, this.engine)
+ .then(() => addDebugTrack(
+ this.engine,
+ {
+ sqlSource:
+ `
+ SELECT ts, dur, thread_name, process_name, height
+ FROM experimental_thread_executing_span_critical_path(
+ NULL, ${this.state?.thread?.utid})
+ `,
+ columns: ['ts', 'dur', 'thread_name', 'process_name', 'height']
+ },
+ `${this.state?.thread?.name}`,
+ sliceColumns,
+ ['ts', 'dur', 'thread_name', 'process_name', 'height'])),
+ }
+ )];
}