From c225faaa3df1f8ece6331abbde2a88363340b58e Mon Sep 17 00:00:00 2001 From: hanlibin Date: Mon, 30 Oct 2023 15:06:32 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=A7=A3=E5=86=B3TraceSheetConfig.ts?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=BC=96=E8=AF=91=E5=A4=B1=E8=B4=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hanlibin --- ide/src/trace/component/trace/base/TraceSheetConfig.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ide/src/trace/component/trace/base/TraceSheetConfig.ts b/ide/src/trace/component/trace/base/TraceSheetConfig.ts index e636bc563..e2a23f4f4 100644 --- a/ide/src/trace/component/trace/base/TraceSheetConfig.ts +++ b/ide/src/trace/component/trace/base/TraceSheetConfig.ts @@ -639,7 +639,7 @@ export let tabConfig: any = { type: TabPaneFreqDataCut, require: (param: SelectionParam) => param.threadIds.length > 0 && param.threadIds.length < 2, }, - }, //current selection + //current selection 'box-perf-Binary': { title: 'BinaryTree', type: TabpanePerfBinaryTree, -- Gitee From 72fd8bcdf4e02855fd232f0c203e9b277ccd9134 Mon Sep 17 00:00:00 2001 From: hanlibin Date: Tue, 7 Nov 2023 19:51:33 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=97=B6=E9=97=B4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hanlibin --- ide/src/trace/bean/BoxSelection.ts | 7 + ide/src/trace/component/StackBar.ts | 8 +- .../sheet/process/TabPaneThreadStates.ts | 145 +++++++++++++----- .../trace/sheet/process/TabPaneThreadUsage.ts | 92 ++++++++++- ide/src/trace/database/SqlLite.ts | 78 +++++++++- 5 files changed, 280 insertions(+), 50 deletions(-) diff --git a/ide/src/trace/bean/BoxSelection.ts b/ide/src/trace/bean/BoxSelection.ts index 60daf4f47..f717057a1 100644 --- a/ide/src/trace/bean/BoxSelection.ts +++ b/ide/src/trace/bean/BoxSelection.ts @@ -140,6 +140,13 @@ export class SelectionData { max: string = ''; stateJX: string = ''; cpu: number = 0; + + recordStartNs: number = 0; + leftNs: number = 0; + rightNs: number = 0; + threadIds: Array = []; + ts: number = 0; + dur: number = 0; } export class Counter { diff --git a/ide/src/trace/component/StackBar.ts b/ide/src/trace/component/StackBar.ts index 1972638e1..3c74e7d6d 100644 --- a/ide/src/trace/component/StackBar.ts +++ b/ide/src/trace/component/StackBar.ts @@ -14,8 +14,10 @@ */ import { BaseElement, element } from '../../base-ui/BaseElement.js'; -import { SelectionData } from '../bean/BoxSelection.js'; +import { SelectionData, SelectionParam } from '../bean/BoxSelection.js'; +import { getTabRunningPersent, getTabSleepingTime } from '../database/SqlLite.js'; import { Utils } from './trace/base/Utils.js'; +import { judgement } from './trace/sheet/process/TabPaneThreadUsage.js'; @element('stack-bar') export class StackBar extends BaseElement { @@ -31,11 +33,11 @@ export class StackBar extends BaseElement { if (map.has(v.state)) { let sv = map.get(v.state); sv!.value = sv!.value + v.wallDuration; - sv!.state = v.state + ' : ' + sv!.value.toFixed(7) + 'ms'; + sv!.state = v.state + ' : ' + sv!.value.toFixed(5) + 'ms'; } else { let sv = new StackValue(); sv.value = v.wallDuration; - sv.state = v.state + ' : ' + sv.value.toFixed(7) + 'ms'; + sv.state = v.state + ' : ' + sv.value.toFixed(5) + 'ms'; sv.color = Utils.getStateColor(v.stateJX); map.set(v.state, sv); } diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts b/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts index 675a702b2..ed033a6ba 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneThreadStates.ts @@ -17,10 +17,9 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; import { LitTable } from '../../../../../base-ui/table/lit-table.js'; import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; import '../../../StackBar.js'; -import { getTabThreadStates } from '../../../../database/SqlLite.js'; +import { getTabThreadStates, getTabThreadStatesDetail } from '../../../../database/SqlLite.js'; import { Utils } from '../../base/Utils.js'; import { StackBar } from '../../../StackBar.js'; -import { log } from '../../../../../log/Log.js'; import { resizeObserver } from '../SheetUtils.js'; @element('tabpane-thread-states') @@ -43,49 +42,111 @@ export class TabPaneThreadStates extends BaseElement { this.range!.textContent = 'Selected range: ' + ((threadStatesParam.rightNs - threadStatesParam.leftNs) / 1000000.0).toFixed(5) + ' ms'; this.threadStatesTbl!.loading = true; - getTabThreadStates(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then( - (result) => { - if (result != null && result.length > 0) { - log('getTabThreadStates result size : ' + result.length); - let sumWall = 0.0; - let sumOcc = 0; - let targetList = []; - for (let e of result) { - if (threadStatesParam.processIds.includes(e.pid)) { - let process = Utils.PROCESS_MAP.get(e.pid); - let thread = Utils.THREAD_MAP.get(e.tid); - e.process = process == null || process.length == 0 ? '[NULL]' : process; - e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; - sumWall += e.wallDuration; - sumOcc += e.occurrences; - e.stateJX = e.state; - e.state = Utils.getEndState(e.stateJX); - e.wallDuration = parseFloat((e.wallDuration / 1000000.0).toFixed(5)); - e.avgDuration = parseFloat((e.avgDuration / 1000000.0).toFixed(5)); - targetList.push(e); - } - } - if (targetList.length > 0) { - let count: any = {}; - count.process = ' '; - count.state = ' '; - count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(5)); - count.occurrences = sumOcc; - targetList.splice(0, 0, count); - } - this.threadStatesTblSource = targetList; - this.threadStatesTbl!.recycleDataSource = targetList; - this.stackBar!.data = targetList; - } else { - this.threadStatesTblSource = []; - this.stackBar!.data = []; - this.threadStatesTbl!.recycleDataSource = []; + this.initThreadStates(threadStatesParam); + } + + async initThreadStates(threadStatesParam: SelectionParam | any){ + + let leftStartNs = threadStatesParam.leftNs + threadStatesParam.recordStartNs; + let rightEndNs = threadStatesParam.rightNs + threadStatesParam.recordStartNs; + + let threadStates = await getTabThreadStates(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs); + let threadStatesDetail = await getTabThreadStatesDetail(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs); + + let targetListTemp = this.updateThreadStates(threadStates,threadStatesDetail, leftStartNs, rightEndNs); + + let compare = function(threadState1: SelectionData, threadState2: SelectionData){ + let wallDuration1 = threadState1.wallDuration; + let wallDuration2 = threadState2.wallDuration; + if(wallDuration1 < wallDuration2){ + return 1; + }else if(wallDuration1 > wallDuration2){ + return -1; + }else { + return 0 + } + } + targetListTemp.sort(compare); + + this.addSumLine(threadStatesParam, targetListTemp); + + } + + updateThreadStates(threadStates: Array, threadStatesDetail: Array, leftStartNs:number, rightEndNs:number ): Array { + let targetListTemp = []; + if (threadStates.length > 0 && threadStatesDetail.length >0 ){ + let firstState = threadStatesDetail[0]; + let lastState = threadStatesDetail[threadStatesDetail.length-1]; + for (let e of threadStates) { + + if(firstState.ts < leftStartNs + && e.process == firstState.process + && e.thread == firstState.thread + && e.state == firstState.state){ + + e.wallDuration = e.wallDuration - ( leftStartNs - firstState.ts ); + e.avgDuration = e.wallDuration / e.occurrences; } - this.threadStatesTbl!.loading = false; - } - ); + + if( lastState.ts < rightEndNs + && e.process == lastState.process + && e.thread == lastState.thread + && e.state == lastState.state ){ + + e.wallDuration = e.wallDuration - ( lastState.ts + lastState.dur - rightEndNs ); + e.avgDuration = e.wallDuration / e.occurrences; + } + targetListTemp.push(e); + } + } + return targetListTemp; } + addSumLine(threadStatesParam : SelectionParam | any,targetListTemp: Array): void { + + console.log(targetListTemp); + + if (targetListTemp != null && targetListTemp.length > 0) { + console.log('getTabThreadStates result size : ' + targetListTemp.length); + let sumWall = 0.0; + let sumOcc = 0; + let targetList = []; + + for (let e of targetListTemp) { + if (threadStatesParam.processIds.includes(e.pid)) { + let process = Utils.PROCESS_MAP.get(e.pid); + let thread = Utils.THREAD_MAP.get(e.tid); + e.process = process == null || process.length == 0 ? '[NULL]' : process; + e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; + + e.stateJX = e.state; + e.state = Utils.getEndState(e.stateJX); + e.wallDuration = parseFloat((e.wallDuration / 1000000.0).toFixed(5)); + e.avgDuration = parseFloat((e.avgDuration / 1000000.0).toFixed(5)); + sumWall += e.wallDuration; + sumOcc += e.occurrences; + targetList.push(e); + } + } + if (targetList.length > 0) { + let count: any = {}; + count.process = ' '; + count.state = ' '; + count.wallDuration = parseFloat(sumWall.toFixed(5)); + count.occurrences = sumOcc; + targetList.splice(0, 0, count); + } + this.threadStatesTblSource = targetList; + this.threadStatesTbl!.recycleDataSource = targetList; + this.stackBar!.data = targetList; + } else { + this.threadStatesTblSource = []; + this.stackBar!.data = []; + this.threadStatesTbl!.recycleDataSource = []; + } + this.threadStatesTbl!.loading = false; + } + initElements(): void { this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-thread-states'); this.range = this.shadowRoot?.querySelector('#thread-states-time-range'); diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts b/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts index fa8822633..b4777d6bd 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneThreadUsage.ts @@ -17,7 +17,7 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; import { LitTable } from '../../../../../base-ui/table/lit-table.js'; import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; import '../../../StackBar.js'; -import { getTabThreadStatesCpu } from '../../../../database/SqlLite.js'; +import { getTabRunningPersent, getTabThreadStatesCpu } from '../../../../database/SqlLite.js'; import { StackBar } from '../../../StackBar.js'; import { log } from '../../../../../log/Log.js'; import { getProbablyTime } from '../../../../database/logic-worker/ProcedureLogicWorkerCommon.js'; @@ -59,8 +59,23 @@ export class TabPaneThreadUsage extends BaseElement { this.threadUsageTbl?.shadowRoot?.querySelector('.table')?.style?.height = this.parentElement!.clientHeight - 45 + 'px'; // // @ts-ignore - this.range!.textContent = - 'Selected range: ' + ((threadUsageParam.rightNs - threadUsageParam.leftNs) / 1000000.0).toFixed(5) + ' ms'; + + // 框选区域内running的时间 + getTabRunningPersent(threadUsageParam.threadIds,threadUsageParam.leftNs, threadUsageParam.rightNs).then( + (result)=>{ + // 数组套对象 + console.log('这是result:',result); + // 开始的时间leftStartNs + let leftStartNs=threadUsageParam.leftNs+threadUsageParam.recordStartNs + // 结束的时间rightEndNs + let rightEndNs=threadUsageParam.rightNs+threadUsageParam.recordStartNs + console.log('开始的时间:',threadUsageParam.leftNs,'结束的时间:',threadUsageParam.rightNs); + console.log('从头开始的时间:',leftStartNs,'结束的时间:',rightEndNs); + let sum =judgement(result,leftStartNs,rightEndNs) + this.range!.textContent = + 'Selected range: ' + (sum / 1000000.0).toFixed(5) + ' ms'; + } + ) this.threadUsageTbl!.loading = true; getTabThreadStatesCpu(threadUsageParam.threadIds, threadUsageParam.leftNs, threadUsageParam.rightNs).then( (result) => { @@ -204,3 +219,74 @@ export class TabPaneThreadUsage extends BaseElement { this.threadUsageTbl!.recycleDataSource = this.threadUsageSource; } } + +export function judgement(result:Array,leftStart:any,rightEnd:any){ + let sum=0 + if(result!=null && result.length>0){ + log('getTabRunningTime result size : ' + result.length); + let rightEndNs=rightEnd + let leftStartNs=leftStart + // 尾部running的结束时间 + let RunningEnds=result[result.length-1].dur-(rightEndNs-result[result.length-1].ts)+rightEndNs + // 如果截取了开头和结尾的长度 + let beigin=result[0].dur-(leftStartNs-result[0].ts) + let end=rightEndNs-result[result.length-1].ts + // 用来存储数据的新数组 + let arr=[] + console.log('尾部running的结束时间:',RunningEnds); + console.log('开头框选部分的长度:',beigin); + console.log('结尾框选部分的长度:',end) + // 如果开头和结尾都截取了 + if(leftStartNs>result[0].ts && rightEndNs { + return total+item.dur + },0) + sum=beginAndEnd+res + console.log('这是中间截取部分的数组arr:',arr); + console.log('这是截取的res和sum',res,sum) + // this.range!.textContent = + // 'Selected range: ' + (sum / 1000000.0).toFixed(5) + ' ms'; + }else if(leftStartNs>result[0].ts){ + // 如果只是截取了开头 + arr=result.slice(1) + let res=arr.reduce((total,item)=>{ + return total+item.dur + },0) + sum=beigin+res + console.log('这是截取了开头的数组arr:',arr); + console.log('这是截取的res和sum',res,sum) + // this.range!.textContent = + // 'Selected range: ' + (sum / 1000000.0).toFixed(5) + ' ms'; + + }else if(rightEndNs { + return total+item.dur + },0) + sum=end+res + console.log('这是截取了结尾的数组arr:',arr); + console.log('这是截取的res和sum',res,sum) + // this.range!.textContent = + // 'Selected range: ' + (sum / 1000000.0).toFixed(5) + ' ms'; + }else{ + // 如果都没截取 + for(let i of result){ + sum+=i.dur + console.log('这是正常的sum值:',sum); + // ts是事件开始的时间 + console.log('这是i和ts:',i,i.ts); + console.log('这是result2:',result,1111111); + // this.range!.textContent = + // 'Selected range: ' + (sum / 1000000.0).toFixed(5) + ' ms'; + } + } + } + return sum +} \ No newline at end of file diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index 9fdde25ff..255e9a5ac 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -925,8 +925,29 @@ export const getTabSlicesAsyncFunc = ( wallDuration desc;`, { $leftNS: leftNS, $rightNS: rightNS } ); - -export const getTabThreadStates = (tIds: Array, leftNS: number, rightNS: number): Promise> => +// 鏌ヨ绾跨▼鐘舵佽缁嗕俊鎭 +export const getTabThreadStatesDetail = (tIds: Array, leftNS: number, rightNS: number): Promise> => + query( + 'getTabThreadStates', + `select + B.pid, + B.tid, + B.state, + B.ts, + B.dur + from + thread_state AS B + left join + trace_range AS TR + where + B.tid in (${tIds.join(',')}) + and + not ((B.ts - TR.start_ts + ifnull(B.dur,0) < $leftNS) or (B.ts - TR.start_ts > $rightNS)) + order by ts;`, + { $leftNS: leftNS, $rightNS: rightNS } + ); +// 鏌ヨ绾跨▼鐘舵佷俊鎭 + export const getTabThreadStates = (tIds: Array, leftNS: number, rightNS: number): Promise> => query( 'getTabThreadStates', ` @@ -952,6 +973,59 @@ export const getTabThreadStates = (tIds: Array, leftNS: number, rightNS: { $leftNS: leftNS, $rightNS: rightNS } ); + // 妗嗛夊尯鍩熷唴running鐨勬椂闂 +export const getTabRunningPersent = (tIds: Array, leftNS: number, rightNS: number): Promise> => +query( + 'getTabRunningPersent', + ` + select + B.pid, + B.tid, + B.state, + B.cpu, + B.dur, + B.ts + from + thread_state AS B + left join + trace_range AS TR + where + B.tid in (${tIds.join(',')}) + and + B.state='Running' + and + not ((B.ts - TR.start_ts + ifnull(B.dur,0) < ${leftNS}) or (B.ts - TR.start_ts > ${rightNS})) + order by + ts;`, + { $leftNS: leftNS, $rightNS: rightNS } +); +// 妗嗛夊尯鍩熷唴sleeping鐨勬椂闂 +export const getTabSleepingTime=(tIds: Array, leftNS: number, rightNS: number): Promise>=> +query( +'getTabRunningPersent', +` +select + B.pid, + B.tid, + B.state, + B.cpu, + B.dur, + B.ts +from + thread_state AS B +left join + trace_range AS TR +where + B.tid in (${tIds.join(',')}) +and + B.state='Sleeping' +and + not ((B.ts - TR.start_ts + ifnull(B.dur,0) < ${leftNS}) or (B.ts - TR.start_ts > ${rightNS})) +order by + ts;`, +{ $leftNS: leftNS, $rightNS: rightNS } +); + export const getTabThreadStatesCpu = (tIds: Array, leftNS: number, rightNS: number): Promise> => { let sql = ` select -- Gitee