1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {SpSystemTrace} from "../SpSystemTrace.js"; 17import { 18 getCpuLimitFreq, 19 getCpuLimitFreqId, getCpuLimitFreqMax, 20 queryCpuFreq, 21 queryCpuFreqData, 22 queryCpuMaxFreq, 23 queryCpuState, 24 queryCpuStateFilter 25} from "../../database/SqlLite.js"; 26import {info} from "../../../log/Log.js"; 27import {CpuFreqStruct} from "../../bean/CpuFreqStruct.js"; 28import {TraceRow} from "../trace/base/TraceRow.js"; 29import {procedurePool} from "../../database/Procedure.js"; 30import {CpuStruct} from "../../bean/CpuStruct.js"; 31import { ColorUtils } from "../trace/base/ColorUtils.js"; 32import {CpuFreqLimitsStruct} from "../../database/ui-worker/ProcedureWorkerCpuFreqLimits.js"; 33 34export class SpFreqChart { 35 private trace: SpSystemTrace; 36 static hoverStateStruct:any; 37 static selectStateStruct:any; 38 39 constructor(trace: SpSystemTrace) { 40 this.trace = trace; 41 } 42 43 async init() { 44 let cpuFreqStartTime = new Date().getTime(); 45 let freqList = await queryCpuFreq(); 46 let cpuStateFilterIds = await queryCpuStateFilter(); 47 let cpuFreqLimits = await getCpuLimitFreqId() 48 let cpuFreqLimitsMax = await getCpuLimitFreqMax(cpuFreqLimits.map((limit)=>{ 49 return limit.maxFilterId 50 }).join(",")) 51 info("Cpu Freq data size is: ", freqList!.length) 52 let freqMaxList = await queryCpuMaxFreq(); 53 CpuFreqStruct.maxFreq = freqMaxList[0].maxFreq; 54 let maxFreqObj = this.math(freqMaxList[0].maxFreq); 55 CpuFreqStruct.maxFreq = maxFreqObj.maxFreq; 56 CpuFreqStruct.maxFreqName = maxFreqObj.maxFreqName; 57 for (let i = 0; i < freqList.length; i++) { 58 const it = freqList[i]; 59 let traceRow = new TraceRow<CpuFreqStruct>({ 60 canvasNumber: 1, 61 alpha: true, 62 contextId: '2d', 63 isOffScreen: SpSystemTrace.isCanvasOffScreen 64 }); 65 traceRow.rowId = `${it.filterId}` 66 traceRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ 67 traceRow.rowParentId = '' 68 traceRow.style.height = '40px' 69 traceRow.name = `Cpu ${it.cpu} Frequency`; 70 traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 71 traceRow.selectChangeHandler = this.trace.selectChangeHandler; 72 traceRow.supplier = () => queryCpuFreqData(it.cpu) 73 traceRow.onThreadHandler = (useCache) => { 74 procedurePool.submitWithName(`freq${it.cpu % procedurePool.freqLen.length}`, `freq${it.cpu}`, { 75 list: traceRow.must ? traceRow.dataList : undefined, 76 offscreen: !traceRow.isTransferCanvas ? traceRow.offscreen[0] : undefined, 77 xs: TraceRow.range?.xs, 78 dpr: traceRow.dpr, 79 isHover: traceRow.isHover, 80 flagMoveInfo: this.trace.hoverFlag, 81 flagSelectedInfo: this.trace.selectFlag, 82 hoverX: traceRow.hoverX, 83 hoverY: traceRow.hoverY, 84 canvasWidth: traceRow.canvasWidth, 85 canvasHeight: traceRow.canvasHeight, 86 hoverCpuFreqStruct: CpuFreqStruct.hoverCpuFreqStruct, 87 selectCpuFreqStruct: CpuFreqStruct.selectCpuFreqStruct, 88 wakeupBean: CpuStruct.wakeupBean, 89 isRangeSelect: traceRow.rangeSelect, 90 rangeSelectObject: TraceRow.rangeSelectObject, 91 maxFreq: CpuFreqStruct.maxFreq, 92 maxFreqName: CpuFreqStruct.maxFreqName, 93 useCache: useCache, 94 lineColor: traceRow.getLineColor(), 95 startNS: TraceRow.range?.startNS || 0, 96 endNS: TraceRow.range?.endNS || 0, 97 totalNS: TraceRow.range?.totalNS || 0, 98 slicesTime: TraceRow.range?.slicesTime, 99 range: TraceRow.range, 100 frame: traceRow.frame 101 }, traceRow.getTransferArray(), (res: any, hover: any) => { 102 traceRow.must = false; 103 if (traceRow.args.isOffScreen == true) { 104 if (traceRow.isHover) { 105 CpuFreqStruct.hoverCpuFreqStruct = hover; 106 this.trace.visibleRows.filter(it => it.rowType === TraceRow.ROW_TYPE_CPU_FREQ && it.name !== traceRow.name).forEach(it => it.draw(true)); 107 } 108 return; 109 } 110 }) 111 traceRow.isTransferCanvas = true; 112 } 113 this.trace.rowsEL?.appendChild(traceRow) 114 } 115 for (let it of cpuStateFilterIds) { 116 let cpuStateRow = new TraceRow(); 117 cpuStateRow.rowId = `${cpuStateFilterIds[it.cpu].filterId}` 118 cpuStateRow.rowType = TraceRow.ROW_TYPE_CPU_STATE 119 cpuStateRow.rowParentId = '' 120 cpuStateRow.style.height = '40px' 121 cpuStateRow.name = `Cpu ${it.cpu} State` 122 cpuStateRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 123 cpuStateRow.selectChangeHandler = this.trace.selectChangeHandler; 124 cpuStateRow.isHover = true; 125 cpuStateRow.supplier = () => queryCpuState(cpuStateFilterIds[it.cpu].filterId); 126 cpuStateRow.onThreadHandler = ((useCache: boolean) => { 127 procedurePool.submitWithName(`process${it.cpu % procedurePool.cpusLen.length}`, `cpu-state-${it.cpu}`, cpuStateRow.buildArgs({ 128 flagMoveInfo: this.trace.hoverFlag, 129 flagSelectedInfo: this.trace.selectFlag, 130 cpu:it.cpu, 131 useCache: useCache, 132 wakeupBean: CpuStruct.wakeupBean, 133 selectStateStruct:SpFreqChart.selectStateStruct, 134 lineColor: cpuStateRow.getLineColor(), 135 chartColor:ColorUtils.colorForTid(it.cpu), 136 }), cpuStateRow.getTransferArray(), (res: any, hover: any) => { 137 cpuStateRow.must = false; 138 if (cpuStateRow.isHover) { 139 SpFreqChart.hoverStateStruct = hover; 140 } 141 }) 142 cpuStateRow.isTransferCanvas = true; 143 }) 144 this.trace.rowsEL?.appendChild(cpuStateRow); 145 } 146 let durTime = new Date().getTime() - cpuFreqStartTime; 147 info('The time to load the CpuFreq data is: ', durTime) 148 for(let limit of cpuFreqLimits){ 149 let findMax = this.math(cpuFreqLimitsMax.find((maxLimit)=>{ 150 return maxLimit.filterId == limit.maxFilterId 151 })?.maxValue||0) 152 let cpuFreqLimitRow = new TraceRow(); 153 cpuFreqLimitRow.rowId = `${limit.cpu}` 154 cpuFreqLimitRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ_LIMIT 155 cpuFreqLimitRow.rowParentId = '' 156 cpuFreqLimitRow.style.height = '40px' 157 cpuFreqLimitRow.name = `Cpu ${limit.cpu} Freq Limit` 158 cpuFreqLimitRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 159 cpuFreqLimitRow.selectChangeHandler = this.trace.selectChangeHandler; 160 cpuFreqLimitRow.isHover = true; 161 cpuFreqLimitRow.supplier = () => getCpuLimitFreq(limit.maxFilterId,limit.minFilterId,limit.cpu); 162 cpuFreqLimitRow.onThreadHandler = ((useCache: boolean) => { 163 procedurePool.submitWithName(`process${limit.cpu % procedurePool.cpusLen.length}`, `cpu-limit-freq-${limit.cpu}`, cpuFreqLimitRow.buildArgs({ 164 flagMoveInfo: this.trace.hoverFlag, 165 flagSelectedInfo: this.trace.selectFlag, 166 wakeupBean: CpuStruct.wakeupBean, 167 cpu:limit.cpu, 168 useCache: useCache, 169 maxFreq: findMax?.maxFreq||0, 170 maxFreqName: findMax?.maxFreqName||"", 171 selectCpuFreqLimitsStruct:CpuFreqLimitsStruct.selectCpuFreqLimitsStruct, 172 hoverCpuFreqLimitsStruct:CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct, 173 lineColor: cpuFreqLimitRow.getLineColor(), 174 chartColor:ColorUtils.colorForTid(limit.cpu), 175 }), cpuFreqLimitRow.getTransferArray(), (res: any, hover: any) => { 176 cpuFreqLimitRow.must = false; 177 if (cpuFreqLimitRow.isHover) { 178 CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = hover; 179 } 180 }) 181 cpuFreqLimitRow.isTransferCanvas = true; 182 }) 183 this.trace.rowsEL?.appendChild(cpuFreqLimitRow); 184 } 185 } 186 187 math = (maxFreq:number) => { 188 let maxFreqObj = { 189 maxFreqName:" ", 190 maxFreq:0 191 } 192 let units: Array<string> = ["", "K", "M", "G", "T", "E"]; 193 let sb = " "; 194 if (maxFreq > 0) { 195 let log10: number = Math.ceil(Math.log10(maxFreq)); 196 let pow10: number = Math.pow(10, log10); 197 let afterCeil: number = Math.ceil(maxFreq / (pow10 / 4)) * (pow10 / 4); 198 maxFreqObj.maxFreq = afterCeil; 199 let unitIndex: number = Math.floor(log10 / 3); 200 sb = `${afterCeil / Math.pow(10, unitIndex * 3)}${units[unitIndex + 1]}hz` 201 } 202 maxFreqObj.maxFreqName = sb.toString(); 203 return maxFreqObj; 204 } 205} 206 207export class CpuFreqRowLimit { 208 cpu: number = 0; 209 maxFilterId: number = 0; 210 minFilterId: number = 0; 211}