Skip to content

Commit

Permalink
[ui] TableViewer: Add id column types.
Browse files Browse the repository at this point in the history
Add 'utid', 'upid', 'thread_state_id' and 'sched_id' column types,
customising how different ids are rendered, providing links to jump to
the relevant object and showing a more helpful name.

Change-Id: I7549cd70a55950a224d75e98903fb01a0cac410c
  • Loading branch information
Alexander Timin committed Aug 22, 2024
1 parent 6441ab9 commit 66c7fb8
Show file tree
Hide file tree
Showing 16 changed files with 721 additions and 128 deletions.
10 changes: 1 addition & 9 deletions ui/src/core_plugins/chrome_tasks/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,7 @@ export const chromeTasksTable: SqlTableDescription = {
imports: ['chrome.tasks'],
name: 'chrome_tasks',
columns: [
new SliceIdColumn(
{
sliceId: 'id',
ts: 'ts',
dur: 'dur',
trackId: 'track_id',
},
{title: 'ID'},
),
new SliceIdColumn('id', {title: 'ID'}),
new TimestampColumn('ts', {title: 'Timestamp'}),
new DurationColumn('dur', {title: 'Duration'}),
new DurationColumn('thread_dur', {title: 'Thread duration'}),
Expand Down
3 changes: 2 additions & 1 deletion ui/src/core_plugins/process/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import {SqlTableDescription} from '../../frontend/widgets/sql/table/table_description';
import {
ArgSetColumnSet,
ProcessColumn,
StandardColumn,
TimestampColumn,
} from '../../frontend/widgets/sql/table/well_known_columns';
Expand All @@ -28,7 +29,7 @@ export function getProcessTable(): SqlTableDescription {
new StandardColumn('name'),
new TimestampColumn('start_ts'),
new TimestampColumn('end_ts'),
new StandardColumn('parent_upid'),
new ProcessColumn('parent_upid'),
new StandardColumn('uid'),
new StandardColumn('android_appid'),
new StandardColumn('cmdline', {startsHidden: true}),
Expand Down
21 changes: 18 additions & 3 deletions ui/src/core_plugins/sched/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,36 @@
import {SqlTableDescription} from '../../frontend/widgets/sql/table/table_description';
import {
DurationColumn,
ProcessColumn,
SchedIdColumn,
StandardColumn,
ThreadColumn,
TimestampColumn,
} from '../../frontend/widgets/sql/table/well_known_columns';

export function getSchedTable(): SqlTableDescription {
return {
name: 'sched',
columns: [
new StandardColumn('id'),
new SchedIdColumn('id'),
new TimestampColumn('ts'),
new DurationColumn('dur'),
new StandardColumn('cpu'),
new StandardColumn('utid'),
new StandardColumn('end_state'),
new StandardColumn('priority'),
new ThreadColumn('utid', {title: 'Thread'}),
new ProcessColumn(
{
column: 'upid',
source: {
table: 'thread',
joinOn: {
utid: 'utid',
},
},
},
{title: 'Process'},
),
new StandardColumn('end_state'),
new StandardColumn('ucpu'),
],
};
Expand Down
19 changes: 6 additions & 13 deletions ui/src/core_plugins/slice/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import {SqlTableDescription} from '../../frontend/widgets/sql/table/table_descri
import {
ArgSetColumnSet,
DurationColumn,
ProcessColumn,
SliceIdColumn,
StandardColumn,
ThreadColumn,
TimestampColumn,
} from '../../frontend/widgets/sql/table/well_known_columns';

Expand All @@ -27,26 +29,17 @@ export function getSliceTable(): SqlTableDescription {
name: '_slice_with_thread_and_process_info',
displayName: 'slice',
columns: [
new SliceIdColumn({
sliceId: 'id',
ts: 'ts',
dur: 'dur',
trackId: 'track_id',
}),
new SliceIdColumn('id'),
new TimestampColumn('ts', {title: 'Timestamp'}),
new DurationColumn('dur', {title: 'Duration'}),
new DurationColumn('thread_dur', {title: 'Thread duration'}),
new StandardColumn('category', {title: 'Category'}),
new StandardColumn('name', {title: 'Name'}),
new StandardColumn('track_id', {title: 'Track ID', startsHidden: true}),
new StandardColumn('thread_name', {title: 'Thread name'}),
new StandardColumn('utid', {title: 'utid', startsHidden: true}),
new StandardColumn('tid', {title: 'tid'}),
new StandardColumn('process_name', {title: 'Process name'}),
new StandardColumn('upid', {title: 'upid'}),
new StandardColumn('pid', {title: 'pid', startsHidden: true}),
new ThreadColumn('utid', {title: 'Thread'}),
new ProcessColumn('upid', {title: 'Process'}),
new StandardColumn('depth', {title: 'Depth', startsHidden: true}),
new StandardColumn('parent_id', {
new SliceIdColumn('parent_id', {
title: 'Parent slice ID',
startsHidden: true,
}),
Expand Down
3 changes: 2 additions & 1 deletion ui/src/core_plugins/thread/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import {SqlTableDescription} from '../../frontend/widgets/sql/table/table_description';
import {
ProcessColumn,
StandardColumn,
TimestampColumn,
} from '../../frontend/widgets/sql/table/well_known_columns';
Expand All @@ -27,7 +28,7 @@ export function getThreadTable(): SqlTableDescription {
new StandardColumn('name'),
new TimestampColumn('start_ts'),
new TimestampColumn('end_ts'),
new StandardColumn('upid'),
new ProcessColumn('upid'),
new StandardColumn('is_main_thread'),
],
};
Expand Down
25 changes: 20 additions & 5 deletions ui/src/core_plugins/thread_state/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,39 @@
import {SqlTableDescription} from '../../frontend/widgets/sql/table/table_description';
import {
DurationColumn,
ProcessColumn,
StandardColumn,
ThreadColumn,
ThreadStateIdColumn,
TimestampColumn,
} from '../../frontend/widgets/sql/table/well_known_columns';

export function getThreadStateTable(): SqlTableDescription {
return {
name: 'thread_state',
columns: [
new StandardColumn('id'),
new ThreadStateIdColumn('id'),
new TimestampColumn('ts'),
new DurationColumn('dur'),
new StandardColumn('cpu'),
new StandardColumn('utid'),
new StandardColumn('state'),
new StandardColumn('cpu'),
new ThreadColumn('utid', {title: 'Thread'}),
new ProcessColumn(
{
column: 'upid',
source: {
table: 'thread',
joinOn: {
utid: 'utid',
},
},
},
{title: 'Process'},
),
new StandardColumn('io_wait'),
new StandardColumn('blocked_function'),
new StandardColumn('waker_utid'),
new StandardColumn('waker_id'),
new ThreadColumn('waker_utid', {title: 'Waker thread'}),
new ThreadStateIdColumn('waker_id'),
new StandardColumn('irq_context'),
new StandardColumn('ucpu'),
],
Expand Down
32 changes: 16 additions & 16 deletions ui/src/frontend/pivot_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {globals} from './globals';
import {
aggregationIndex,
areaFilters,
extractArgumentExpression,
sliceAggregationColumns,
tables,
} from './pivot_table_query_generator';
Expand All @@ -47,6 +46,8 @@ import {DurationWidget} from './widgets/duration';
import {addSqlTableTab} from './sql_table_tab_command';
import {getSqlTableDescription} from './widgets/sql/table/sql_table_registry';
import {assertExists} from '../base/logging';
import {Filter, SqlColumn} from './widgets/sql/table/column';
import {argSqlColumn} from './widgets/sql/table/well_known_columns';

interface PathItem {
tree: PivotTree;
Expand All @@ -62,31 +63,30 @@ interface DrillFilter {
value: ColumnType;
}

function drillFilterColumnName(column: TableColumn): string {
function drillFilterColumnName(column: TableColumn): SqlColumn {
switch (column.kind) {
case 'argument':
return extractArgumentExpression(
column.argument,
assertExists(getSqlTableDescription('slice')).name,
);
return argSqlColumn('arg_set_id', column.argument);
case 'regular':
return `${column.column}`;
}
}

// Convert DrillFilter to SQL condition to be used in WHERE clause.
function renderDrillFilter(filter: DrillFilter): string {
function renderDrillFilter(filter: DrillFilter): Filter {
const column = drillFilterColumnName(filter.column);
if (filter.value === null) {
return `${column} IS NULL`;
} else if (typeof filter.value === 'number') {
return `${column} = ${filter.value}`;
} else if (filter.value instanceof Uint8Array) {
const value = filter.value;
if (value === null) {
return {op: (cols) => `${cols[0]} IS NULL`, columns: [column]};
} else if (typeof value === 'number' || typeof value === 'bigint') {
return {op: (cols) => `${cols[0]} = ${filter.value}`, columns: [column]};
} else if (value instanceof Uint8Array) {
throw new Error(`BLOB as DrillFilter not implemented`);
} else if (typeof filter.value === 'bigint') {
return `${column} = ${filter.value}`;
}
return `${column} = ${sqliteString(filter.value)}`;
return {
op: (cols) => `${cols[0]} = ${sqliteString(value)}`,
columns: [column],
};
}

function readableColumnName(column: TableColumn) {
Expand Down Expand Up @@ -142,7 +142,7 @@ export class PivotTable implements m.ClassComponent<PivotTableAttrs> {
addSqlTableTab({
table: assertExists(getSqlTableDescription('slice')),
// TODO(altimin): this should properly reference the required columns, but it works for now (until the pivot table is going to be rewritten to be more flexible).
filters: queryFilters.map((f) => ({op: () => f, columns: []})),
filters: queryFilters,
});
},
},
Expand Down
20 changes: 15 additions & 5 deletions ui/src/frontend/pivot_table_query_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,19 @@ function aggregationAlias(aggregationIndex: number): string {
return `agg_${aggregationIndex}`;
}

export function areaFilters(area: Area): string[] {
export function areaFilters(
area: Area,
): {op: (cols: string[]) => string; columns: string[]}[] {
return [
`ts + dur > ${area.start}`,
`ts < ${area.end}`,
`track_id in (${getSelectedTrackKeys(area).join(', ')})`,
{
op: (cols) => `${cols[0]} + ${cols[1]} > ${area.start}`,
columns: ['ts', 'dur'],
},
{op: (cols) => `${cols[0]} < ${area.end}`, columns: ['ts']},
{
op: (cols) => `${cols[0]} in (${getSelectedTrackKeys(area).join(', ')})`,
columns: ['track_id'],
},
];
}

Expand Down Expand Up @@ -156,7 +164,9 @@ export function generateQueryFromState(
}

const whereClause = state.constrainToArea
? `where ${areaFilters(state.selectionArea).join(' and\n')}`
? `where ${areaFilters(state.selectionArea)
.map((f) => f.op(f.columns))
.join(' and\n')}`
: '';
const text = `
INCLUDE PERFETTO MODULE slices.slices;
Expand Down
26 changes: 19 additions & 7 deletions ui/src/frontend/widgets/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {copyToClipboard} from '../../base/clipboard';
import {Icons} from '../../base/semantic_icons';
import {exists} from '../../base/utils';
import {addEphemeralTab} from '../../common/addEphemeralTab';
import {Upid} from '../../trace_processor/sql_utils/core_types';
import {
getProcessInfo,
getProcessName,
Expand All @@ -33,13 +34,14 @@ import {
} from './sql/details/sql_ref_renderer_registry';
import {asUpid} from '../../trace_processor/sql_utils/core_types';

export function renderProcessRef(info: ProcessInfo): m.Children {
export function processRefMenuItems(info: {
upid: Upid;
name?: string;
pid?: number;
}): m.Children {
// We capture a copy to be able to pass it across async boundary to `onclick`.
const name = info.name;
return m(
PopupMenu2,
{
trigger: m(Anchor, getProcessName(info)),
},
return [
exists(name) &&
m(MenuItem, {
icon: Icons.Copy,
Expand All @@ -64,12 +66,22 @@ export function renderProcessRef(info: ProcessInfo): m.Children {
addEphemeralTab(
'processDetails',
new ProcessDetailsTab({
engine: getEngine('processDetails'),
engine: getEngine('ProcessDetails'),
upid: info.upid,
pid: info.pid,
}),
),
}),
];
}

export function renderProcessRef(info: ProcessInfo): m.Children {
return m(
PopupMenu2,
{
trigger: m(Anchor, getProcessName(info)),
},
processRefMenuItems(info),
);
}

Expand Down
Loading

0 comments on commit 66c7fb8

Please sign in to comment.