From 107ea0c9786497c2ad7c6fddd5b8ab21ab42f8f5 Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Fri, 16 Jun 2023 11:45:38 +0800 Subject: [PATCH] =?UTF-8?q?=E2=80=98=E7=BA=BF=E7=A8=8B=E6=A0=91=E5=94=A4?= =?UTF-8?q?=E9=86=92=EF=BC=8Ctab=E9=A1=B5=E5=8D=95=E4=BD=8D=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=EF=BC=8C=E6=94=B6=E8=97=8F=E6=B7=BB=E5=8A=A0=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E5=90=8D=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/trace/bean/WakeupBean.ts | 1 + ide/src/trace/component/SpSystemTrace.ts | 111 +++++++++++++++++- .../trace/component/trace/base/ColorUtils.ts | 14 +-- .../trace/sheet/TabPaneCurrentSelection.ts | 80 ++++++++++++- .../trace/sheet/cpu/TabPaneCounterSample.ts | 4 +- .../trace/sheet/cpu/TabPaneFrequencySample.ts | 8 +- ide/src/trace/database/SqlLite.ts | 7 ++ .../database/ui-worker/ProcedureWorkerCPU.ts | 22 ++++ .../ui-worker/ProcedureWorkerCommon.ts | 88 ++++++++++++++ 9 files changed, 316 insertions(+), 19 deletions(-) diff --git a/ide/src/trace/bean/WakeupBean.ts b/ide/src/trace/bean/WakeupBean.ts index 6353d513..616af8cb 100644 --- a/ide/src/trace/bean/WakeupBean.ts +++ b/ide/src/trace/bean/WakeupBean.ts @@ -23,4 +23,5 @@ export class WakeupBean { schedulingLatency: number | undefined; schedulingDesc: string | undefined; ts: number | undefined; + itid: number | undefined; } diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 15e8e290..d7f27ce1 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -35,6 +35,7 @@ import { drawLines, drawLinkLines, drawWakeUp, + drawWakeUpList, isFrameContainPoint, ns2x, ns2xByTimeShaft, @@ -42,7 +43,7 @@ import { Rect, } from '../database/ui-worker/ProcedureWorkerCommon.js'; import { SpChartManager } from './chart/SpChartManager.js'; -import { CpuStruct } from '../database/ui-worker/ProcedureWorkerCPU.js'; +import { CpuStruct, WakeupBean } from '../database/ui-worker/ProcedureWorkerCPU.js'; import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess.js'; import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq.js'; import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; @@ -72,6 +73,7 @@ import { TabPaneSummary } from './trace/sheet/snapshot/TabPaneSummary.js'; import { LitTabs } from '../../base-ui/tabs/lit-tabs.js'; import { SpJsMemoryChart } from './chart/SpJsMemoryChart.js'; import { TraceRowConfig } from './trace/base/TraceRowConfig.js'; +import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.js'; function dpr() { return window.devicePixelRatio || 1; @@ -87,6 +89,7 @@ export class SpSystemTrace extends BaseElement { static DATA_DICT: Map = new Map(); static SDK_CONFIG_MAP: any; static sliceRangeMark: any; + static wakeupList: Array = []; intersectionObserver: IntersectionObserver | undefined; tipEL: HTMLDivElement | undefined | null; rowsEL: HTMLDivElement | undefined | null; @@ -105,6 +108,7 @@ export class SpSystemTrace extends BaseElement { this.observerScrollHeightCallback(); } }); + static btnTimer: any = null; isMousePointInSheet = false; hoverFlag: Flag | undefined | null = undefined; selectFlag: Flag | undefined | null = undefined; @@ -145,6 +149,11 @@ export class SpSystemTrace extends BaseElement { } initElements(): void { + let sideColor = document!.querySelector("body > sp-application")!.shadowRoot!.querySelector!("#main-menu")?. + shadowRoot?.querySelector("div.bottom > div.color"); + let rightButton: HTMLElement | null | undefined = + this.shadowRoot?.querySelector("div > trace-sheet")?.shadowRoot?. + querySelector("#current-selection > tabpane-current-selection")?.shadowRoot?.querySelector("#rightButton") this.rowsEL = this.shadowRoot?.querySelector('.rows'); this.tipEL = this.shadowRoot?.querySelector('.tip'); this.rowsPaneEL = this.shadowRoot?.querySelector('.rows-pane'); @@ -154,6 +163,23 @@ export class SpSystemTrace extends BaseElement { this.traceSheetEL = this.shadowRoot?.querySelector('.trace-sheet'); this.favoriteRowsEL = this.shadowRoot?.querySelector('.favorite-rows'); this.rangeSelect = new RangeSelect(this); + rightButton?.addEventListener('click', (event: any) => { + if (SpSystemTrace.btnTimer) { + return; + } + this.wakeupListNull(); + SpSystemTrace.wakeupList.unshift(CpuStruct.wakeupBean!); + this.queryCPUWakeUpList(CpuStruct.wakeupBean!); + setTimeout(() => { + requestAnimationFrame(() => this.refreshCanvas(false)); + }, 300); + SpSystemTrace.btnTimer = setTimeout(() => { + SpSystemTrace.btnTimer = null; // 2.清空节流阀,方便下次开启定时器 + }, 2000); + }); + sideColor?.addEventListener('click', (event: any) => { + requestAnimationFrame(() => this.refreshCanvas(true)); + }); document?.addEventListener('triangle-flag', (event: any) => { let temporaryTime = this.timerShaftEL?.drawTriangle(event.detail.time, event.detail.type); if (event.detail.timeCallback && temporaryTime) event.detail.timeCallback(temporaryTime); @@ -201,6 +227,19 @@ export class SpSystemTrace extends BaseElement { replaceRow.setAttribute('row-parent-id', currentRow.rowParentId); replaceRow.style.display = 'none'; currentRow.rowHidden = !currentRow.hasAttribute('scene'); + // 添加收藏时,在线程名前面追加父亲ID + let rowParentId = currentRow.rowParentId + if (rowParentId) { + let parentRows = this.shadowRoot?.querySelectorAll>( + `trace-row[row-id='${rowParentId}']` + ); + parentRows?.forEach((parentRow) => { + if (parentRow?.name && parentRow?.name != currentRow.name && !parentRow.rowType!.startsWith('cpu') && !parentRow.rowType!.startsWith('thread')) { + console.log(parentRow.name); + currentRow.name += "(" + parentRow.name + ")" + } + }) + } if (this.rowsEL!.contains(currentRow)) { this.rowsEL!.replaceChild(replaceRow, currentRow); } else { @@ -230,6 +269,15 @@ export class SpSystemTrace extends BaseElement { `div[row-id='${currentRow.rowId}-${currentRow.rowType}']` ); if (replaceRow != null) { + // 取消收藏时,删除父亲ID + let rowNameArr = currentRow.name.split("("); + if (rowNameArr.length > 1) { + let tempName = ""; + tempName += rowNameArr[0]; + currentRow.name = tempName; + } else { + currentRow.name = rowNameArr[0]; + } this.rowsEL!.replaceChild(currentRow, replaceRow); currentRow.style.boxShadow = `0 10px 10px #00000000`; } @@ -1032,7 +1080,39 @@ export class SpSystemTrace extends BaseElement { height: this.canvasFavoritePanel!.clientHeight!, } as Rect ); - + // draw wakeuplist for main canvas + for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) { + if (i + 1 == SpSystemTrace.wakeupList.length) { + return + } + drawWakeUpList( + this.canvasPanelCtx, + SpSystemTrace.wakeupList[i + 1], + TraceRow.range!.startNS, + TraceRow.range!.endNS, + TraceRow.range!.totalNS, + { + x: 0, + y: 0, + width: this.timerShaftEL!.canvas!.clientWidth, + height: this.canvasPanel!.clientHeight!, + } as Rect, + ) + drawWakeUpList( + this.canvasFavoritePanelCtx, + SpSystemTrace.wakeupList[i + 1], + TraceRow.range!.startNS, + TraceRow.range!.endNS, + TraceRow.range!.totalNS, + { + x: 0, + y: 0, + width: this.timerShaftEL!.canvas!.clientWidth, + height: this.canvasFavoritePanel!.clientHeight!, + } as Rect, + ) + }; + // Draw the connection curve if (this.linkNodes) { drawLinkLines(this.canvasPanelCtx!, this.linkNodes, this.timerShaftEL!, false); @@ -1427,6 +1507,7 @@ export class SpSystemTrace extends BaseElement { this.rangeSelect.rangeTraceRow = []; TraceRow.rangeSelectObject = undefined; this.selectStructNull(); + this.wakeupListNull(); this.observerScrollHeightEnable = false; this.selectFlag = null; this.timerShaftEL?.removeTriangle('inverted'); @@ -1479,6 +1560,7 @@ export class SpSystemTrace extends BaseElement { if (!this.loadTraceCompleted) return; this.shadowRoot?.querySelectorAll>('trace-row').forEach((it) => (it.rangeSelect = false)); this.selectStructNull(); + this.wakeupListNull(); let threadClickHandler: any; let cpuClickHandler: any; let jankClickHandler: any; @@ -1501,6 +1583,7 @@ export class SpSystemTrace extends BaseElement { } this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); CpuStruct.hoverCpuStruct = findEntry; CpuStruct.selectCpuStruct = findEntry; this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); @@ -1537,6 +1620,7 @@ export class SpSystemTrace extends BaseElement { } this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); ThreadStruct.hoverThreadStruct = findEntry; ThreadStruct.selectThreadStruct = findEntry; this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); @@ -1586,6 +1670,7 @@ export class SpSystemTrace extends BaseElement { } this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); JankStruct.hoverJankStruct = findJankEntry; JankStruct.selectJankStruct = findJankEntry; this.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted'); @@ -1623,6 +1708,7 @@ export class SpSystemTrace extends BaseElement { let findEntry = snapshotRow!.dataList!.find((dat) => dat.startTs === d.startTs); this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); HeapSnapshotStruct.hoverSnapshotStruct = findEntry; HeapSnapshotStruct.selectSnapshotStruct = findEntry; } @@ -2210,6 +2296,7 @@ export class SpSystemTrace extends BaseElement { }); this.rangeSelect.rangeTraceRow = []; this.selectStructNull(); + this.wakeupListNull(); this.traceSheetEL?.setAttribute('mode', 'hidden'); this.clearPointPair(); TraceRow.range!.refresh = true; @@ -2440,6 +2527,7 @@ export class SpSystemTrace extends BaseElement { let searchEntry = filterRow!.dataList!.find((dat) => dat.startTime === findEntry.startTime); this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); ThreadStruct.hoverThreadStruct = searchEntry; ThreadStruct.selectThreadStruct = searchEntry; this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); @@ -2460,6 +2548,7 @@ export class SpSystemTrace extends BaseElement { } this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); this.onClickHandler(findEntry.rowType!); this.closeAllExpandRows(findEntry.rowParentId); this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); @@ -2472,6 +2561,7 @@ export class SpSystemTrace extends BaseElement { const toTargetDepth = (entry: any) => { this.hoverStructNull(); this.selectStructNull(); + this.wakeupListNull(); FuncStruct.hoverFuncStruct = entry; FuncStruct.selectFuncStruct = entry; this.onClickHandler(TraceRow.ROW_TYPE_FUNC); @@ -2680,6 +2770,7 @@ export class SpSystemTrace extends BaseElement { CpuStruct.wakeupBean = undefined; this.selectStructNull(); this.hoverStructNull(); + this.wakeupListNull(); this.traceSheetEL?.setAttribute('mode', 'hidden'); progress && progress('rest timershaft', 8); this.timerShaftEL?.reset(); @@ -2687,8 +2778,8 @@ export class SpSystemTrace extends BaseElement { HeapDataInterface.getInstance().clearData(); procedurePool.clearCache(); Utils.clearData(); - procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: any) => {}); - procedurePool.submitWithName('logic1', 'clear', {}, undefined, (res: any) => {}); + procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: any) => { }); + procedurePool.submitWithName('logic1', 'clear', {}, undefined, (res: any) => { }); } init = async (param: { buf?: ArrayBuffer; url?: string }, wasmConfigUri: string, progress: Function) => { @@ -2822,6 +2913,18 @@ export class SpSystemTrace extends BaseElement { } } } + queryCPUWakeUpList(data: WakeupBean) { + TabPaneCurrentSelection.queryCPUWakeUpListFromBean(data).then((a: any) => { + if (a === null) { + return null + } + SpSystemTrace.wakeupList.push(a); + this.queryCPUWakeUpList(a); + }); + } + wakeupListNull() { + SpSystemTrace.wakeupList = []; + } initPointToEvent() { this.eventMap = { diff --git a/ide/src/trace/component/trace/base/ColorUtils.ts b/ide/src/trace/component/trace/base/ColorUtils.ts index 0eb82b51..f838e36e 100644 --- a/ide/src/trace/component/trace/base/ColorUtils.ts +++ b/ide/src/trace/component/trace/base/ColorUtils.ts @@ -20,19 +20,19 @@ export class ColorUtils { public static FUNC_COLOR_A: Array = [ '#40b3e7', - '#606e75', + '#23b0e7', '#8d9171', - '#8f8f8f', + '#FF0066', '#7a9160', '#9fafc4', '#8a8a8b', - '#9e8e00', - '#696e35', - '#5c4d21', - '#18a8a1', + '#e05b52', + '#9bb87a', + '#ebc247', + '#c2cc66', '#a16a40', '#a94eb9', - '#886EB4', + '#aa4fba', ]; public static FUNC_COLOR_B: Array = [ '#9785D3', diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts index 4d176497..74e66f85 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts @@ -28,6 +28,7 @@ import { queryThreadStateArgs, queryThreadWakeUp, queryThreadWakeUpFrom, + queryCPUWakeUpIdFromBean, } from '../../../database/SqlLite.js'; import { WakeupBean } from '../../../bean/WakeupBean.js'; import { SpApplication } from '../../../SpApplication.js'; @@ -43,6 +44,7 @@ import { BinderArgBean } from '../../../bean/BinderArgBean.js'; import { JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank.js'; import { LitIcon } from '../../../../base-ui/icon/LitIcon.js'; import { Utils } from '../base/Utils.js'; +import { SpSystemTrace } from '../../SpSystemTrace.js'; const INPUT_WORD = 'This is the interval from when the task became eligible to run \n(e.g.because of notifying a wait queue it was a suspended on) to\n when it started running.'; @@ -166,6 +168,8 @@ export class TabPaneCurrentSelection extends BaseElement { this.currentSelectionTbl!.dataSource = list; let rightArea: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#table-right'); let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle'); + let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton') + ?.shadowRoot?.querySelector("#custom-button"); let threadClick = this.currentSelectionTbl?.shadowRoot?.querySelector('#thread-id'); threadClick?.addEventListener('click', () => { //cpu点击 @@ -181,6 +185,8 @@ export class TabPaneCurrentSelection extends BaseElement { } if (rightTitle != null && rightTitle) { rightTitle.style.visibility = 'visible'; + rightButton!.style.visibility = 'visible'; + SpSystemTrace.btnTimer = null; } this.drawRight(canvas, bean); } else { @@ -190,6 +196,7 @@ export class TabPaneCurrentSelection extends BaseElement { } if (rightTitle != null && rightTitle) { rightTitle.style.visibility = 'hidden'; + rightButton!.style.visibility = 'hidden'; } } }); @@ -332,8 +339,11 @@ export class TabPaneCurrentSelection extends BaseElement { this.initCanvas(); let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle'); let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle'); + let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton') + ?.shadowRoot?.querySelector("#custom-button"); if (rightTitle) { rightTitle.style.visibility = 'hidden'; + rightButton!.style.visibility = 'hidden'; } if (leftTitle) { leftTitle.innerText = leftTitleStr; @@ -383,8 +393,11 @@ export class TabPaneCurrentSelection extends BaseElement { this.setTableHeight('300px'); this.initCanvas(); let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle'); + let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton') + ?.shadowRoot?.querySelector("#custom-button"); if (rightTitle) { rightTitle.style.visibility = 'hidden'; + rightButton!.style.visibility = 'hidden'; } let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle'); if (leftTitle) { @@ -417,8 +430,11 @@ export class TabPaneCurrentSelection extends BaseElement { this.initCanvas(); let leftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle'); let rightTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightTitle'); + let rightButton: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton') + ?.shadowRoot?.querySelector("#custom-button"); if (rightTitle) { rightTitle.style.visibility = 'hidden'; + rightButton!.style.visibility = 'hidden'; } if (leftTitle) { leftTitle.innerText = 'Thread State'; @@ -810,6 +826,10 @@ export class TabPaneCurrentSelection extends BaseElement { if (wf && wf[0]) { wb = wf[0]; if (wb != null) { + let wd = await queryCPUWakeUpIdFromBean(wb.tid); + if (wd && wd[0]) { + wb.itid = wd[0].itid; + } wb.wakeupTime = wakeupTs - recordStartTs; wb.process = Utils.PROCESS_MAP.get(wb.pid!); wb.thread = Utils.THREAD_MAP.get(wb.tid!); @@ -827,6 +847,40 @@ export class TabPaneCurrentSelection extends BaseElement { return wb; } + /** + * 查询出 线程被唤醒的 线程链信息 + * @param data + */ + static async queryCPUWakeUpListFromBean(data: WakeupBean) { + let wb: WakeupBean | null = null; + let wakeup = await queryRunnableTimeByRunning(data.tid!, data.ts!); + if (wakeup && wakeup[0]) { + let wakeupTs = wakeup[0].ts as number; + let recordStartTs = (window as any).recordStartNS; + let wf = await queryThreadWakeUpFrom(data.itid!, wakeupTs); + if (wf && wf[0]) { + wb = wf[0]; + if (wb != null) { + let wd = await queryCPUWakeUpIdFromBean(wb.tid); + if (wd && wd[0]) { + wb.itid = wd[0].itid; + } + wb.wakeupTime = wakeupTs - recordStartTs; + wb.process = Utils.PROCESS_MAP.get(wb.pid!); + wb.thread = Utils.THREAD_MAP.get(wb.tid!); + wb.schedulingLatency = (data.ts || 0) - (wb.wakeupTime || 0); + if (wb.process === null) { + wb.process = wb.thread; + } + if (wb.pid === undefined) { + wb.pid = wb.tid; + } + wb.schedulingDesc = INPUT_WORD; + } + } + } + return wb; + } /** * 查询出 线程唤醒了哪些线程信息 */ @@ -972,13 +1026,29 @@ export class TabPaneCurrentSelection extends BaseElement { width: 100%; display: flex; } - .table-title h2{ + .table-title > h2{ font-size: 16px; font-weight: 400; visibility: visible; width: 50%; padding: 0 10px; } + #rightTitle{ + width: 50%; + display: flex; + justify-content: space-between; + padding: 0 10px; + font-size: 16px; + font-weight: 400; + visibility: visible; + } + #rightTitle > h2{ + font-size: 16px; + font-weight: 400; + } + #rightButton{ + padding-top:12px; + } .scroll-area{ display: flex; flex-direction: row; @@ -997,7 +1067,13 @@ export class TabPaneCurrentSelection extends BaseElement {

-

Scheduling Latency

+
+

Scheduling Latency

+
+ GetWakeupList +
+
diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts index 9600f5f8..8d0d4ccf 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts @@ -91,7 +91,7 @@ export class TabPaneCounterSample extends BaseElement { }); let counterSampleList: Array = []; sampleMap.forEach((a) => { - a.timeStr = Utils.getProbablyTime(a.time); + a.timeStr = parseFloat((a.time / 1000000.0).toFixed(6)); counterSampleList.push(a); }); this.counterSampleSource = counterSampleList; @@ -194,7 +194,7 @@ export class TabPaneCounterSample extends BaseElement { - + diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts index 9634e733..71cf7567 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts @@ -93,7 +93,7 @@ export class TabPaneFrequencySample extends BaseElement { let frqSampleList: Array = []; sampleMap.forEach((a) => { - a.timeStr = Utils.getProbablyTime(a.time); + a.timeStr = parseFloat((a.time / 1000000.0).toFixed(6)); frqSampleList.push(a); }); this.frequencySampleSource = frqSampleList; @@ -126,7 +126,7 @@ export class TabPaneFrequencySample extends BaseElement { sampleMap.set(item.filterId + '-' + item.value, { ...item, counter: 'Cpu ' + item.cpu, - valueStr: ColorUtils.formatNumberComma(item.value) + ' kHz', + valueStr: ColorUtils.formatNumberComma(item.value), }); } }); @@ -194,9 +194,9 @@ export class TabPaneFrequencySample extends BaseElement { - + - + diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index c3a49388..1fa17e88 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -1273,6 +1273,13 @@ export const queryWakeUpThread_Desc = (): Promise> => (e.g.because of notifying a wait queue it was a suspended on) to when it started running.` ); +export const queryCPUWakeUpIdFromBean = (tid: number | undefined): Promise> => { + let sql = ` +select itid from thread where tid=${tid} + `; + return query('queryCPUWakeUpListFromBean', sql, {}); +}; + export const queryThreadWakeUp = (itid: number, startTime: number, dur: number): Promise> => query( 'queryThreadWakeUp', diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts index 3e214eef..75eed2ba 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCPU.ts @@ -22,10 +22,12 @@ import { drawLoading, drawSelection, drawWakeUp, + drawWakeUpList, Render, RequestMessage, } from './ProcedureWorkerCommon.js'; import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { SpSystemTrace } from '../../component/SpSystemTrace.js'; export class EmptyRender extends Render { renderMainThread(req: any, row: TraceRow) { @@ -101,6 +103,24 @@ export class CpuRender { currentCpu, true ); + for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) { + if (i + 1 == SpSystemTrace.wakeupList.length) { + return + } + drawWakeUpList( + req.context, + SpSystemTrace.wakeupList[i + 1], + TraceRow.range!.startNS, + TraceRow.range!.endNS, + TraceRow.range!.totalNS, + row.frame, + req.type == `cpu-data-${SpSystemTrace.wakeupList[i]?.cpu || 0}` + ? SpSystemTrace.wakeupList[i] + : undefined, + currentCpu, + true + ); + }; } render(cpuReq: RequestMessage, list: Array, filter: Array, translateY: number) { @@ -407,6 +427,8 @@ export class WakeupBean { tid: number | undefined; schedulingLatency: number | undefined; schedulingDesc: string | undefined; + ts: number | undefined; + itid: number | undefined; } const textPadding = 2; diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts index cbbd2015..392a8a5f 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts @@ -636,6 +636,94 @@ export function drawWakeUp( } } +export function drawWakeUpList( + context: CanvasRenderingContext2D | any, + wake: WakeupBean | undefined | null, + startNS: number, + endNS: number, + totalNS: number, + frame: Rect, + wakeup: WakeupBean | undefined = undefined, + currentCpu: number | undefined | null = undefined, + noVerticalLine = false, +) { + if (wake) { + let x1 = Math.floor( + ns2x(wake.wakeupTime || 0, startNS, endNS, totalNS, frame) + ); + context.beginPath(); + context.lineWidth = 2; + context.fillStyle = '#000000'; + if (x1 > 0 && x1 < frame.x + frame.width) { + if (!noVerticalLine) { + context.moveTo(x1, frame.y); + context.lineTo(x1, frame.y + frame.height); + } + if (currentCpu == wake.cpu) { + let centerY = Math.floor(frame.y + frame.height / 2); + context.moveTo(x1, centerY - 6); + context.lineTo(x1 + 4, centerY); + context.lineTo(x1, centerY + 6); + context.lineTo(x1 - 4, centerY); + context.lineTo(x1, centerY - 6); + context.fill(); + } + } + if (wakeup) { + let x2 = Math.floor( + ns2x( + wakeup.ts || 0, + startNS, + endNS, + totalNS, + frame + ) + ); + let y = frame.y + frame.height - 10; + context.moveTo(x1, y); + context.lineTo(x2, y); + context.moveTo(x2, y - 25); + context.lineTo(x2, y + 5); + + let s = ns2s( + (wakeup.ts || 0) - (wake.wakeupTime || 0) + ); + let distance = x2 - x1; + if (distance > 12) { + context.moveTo(x1, y); + context.lineTo(x1 + 6, y - 3); + context.moveTo(x1, y); + context.lineTo(x1 + 6, y + 3); + context.moveTo(x2, y); + context.lineTo(x2 - 6, y - 3); + context.moveTo(x2, y); + context.lineTo(x2 - 6, y + 3); + let measure = context.measureText(s); + let tHeight = + measure.actualBoundingBoxAscent + + measure.actualBoundingBoxDescent; + let xStart = x1 + Math.floor(distance / 2 - measure.width / 2); + if (distance > measure.width + 4) { + context.fillStyle = '#ffffff'; + context.fillRect( + xStart - 2, + y - 4 - tHeight, + measure.width + 4, + tHeight + 4 + ); + context.font = '10px solid'; + context.fillStyle = '#000000'; + context.textBaseline = 'bottom'; + context.fillText(s, xStart, y - 2); + } + } + } + context.strokeStyle = '#000000'; + context.stroke(); + context.closePath(); + } +} + const wid = 5; const linkLineColor = '#ff0000'; export function drawLinkLines( -- Gitee