Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ SELECT
count() AS perf_sample_cnt
FROM perf_sample
WHERE
callsite_id IS NOT NULL
utid IS NOT NULL
GROUP BY
utid;

Expand Down
41 changes: 40 additions & 1 deletion ui/src/plugins/dev.perfetto.LinuxPerf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ import {Flamegraph} from '../../widgets/flamegraph';
import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
import TraceProcessorTrackPlugin from '../dev.perfetto.TraceProcessorTrack';
import {TraceProcessorCounterTrack} from '../dev.perfetto.TraceProcessorTrack/trace_processor_counter_track';
import {createPerfCallsitesTrack} from './perf_samples_profile_track';
import {
createPerfCallsitesTrack,
createProcessNonCallsiteTrack,
} from './perf_samples_profile_track';

const PERF_SAMPLES_PROFILE_TRACK_KIND = 'PerfSamplesProfileTrack';

Expand All @@ -53,6 +56,7 @@ export default class implements PerfettoPlugin {
await this.addProcessPerfSamplesTracks(trace);
await this.addThreadPerfSamplesTracks(trace);
await this.addPerfCounterTracks(trace);
await this.addProcessNonCallstackTracks(trace);

trace.onTraceReady.addListener(async () => {
await selectPerfTracksIfSingleProcess(trace);
Expand Down Expand Up @@ -158,6 +162,41 @@ export default class implements PerfettoPlugin {
});
}

private async addProcessNonCallstackTracks(trace: Trace) {
const pResult = await trace.engine.query(`
SELECT DISTINCT upid
FROM perf_sample
JOIN thread USING (utid)
WHERE
callsite_id IS NULL AND
upid IS NOT NULL
`);
for (const it = pResult.iter({upid: NUM}); it.valid(); it.next()) {
const upid = it.upid;
const uri = `/process_${upid}/perf_samples_other`;

trace.tracks.registerTrack({
uri,
tags: {
kinds: ['PerfOtherSamplesTrack'],
upid,
},
renderer: createProcessNonCallsiteTrack(trace, uri, upid),
});

const otherSamplesTrack = new TrackNode({
uri,
name: `Unclassified perf samples`,
sortOrder: -35,
});

const group = trace.plugins
.getPlugin(ProcessThreadGroupsPlugin)
.getGroupForProcess(upid);
group?.addChildInOrder(otherSamplesTrack);
}
}

private async addThreadPerfSamplesTracks(trace: Trace) {
const tResult = await trace.engine.query(`
SELECT DISTINCT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,36 @@ function renderDetailsPanel(
),
);
}

export function createProcessNonCallsiteTrack(
trace: Trace,
uri: string,
upid: number,
) {
return SliceTrack.create({
trace,
uri,
dataset: new SourceDataset({
schema: {
id: NUM,
ts: LONG,
},
src: `
SELECT
p.id,
ts,
upid
FROM perf_sample AS p
JOIN thread USING (utid)
WHERE callsite_id IS NULL
AND upid = ${upid}
ORDER BY ts
`,
}),
sliceName: () => 'Non-callsite perf sample',
instantStyle: {
width: 8,
render: (ctx, r) => ctx.fillRect(r.x, r.y, r.width, r.height),
},
});
}
Loading