• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,
20  getCpuLimitFreqMax,
21  queryCpuFreq,
22  queryCpuFreqData,
23  queryCpuMaxFreq,
24  queryCpuState,
25  queryCpuStateFilter,
26} from '../../database/SqlLite.js';
27import { info } from '../../../log/Log.js';
28import { TraceRow } from '../trace/base/TraceRow.js';
29import { procedurePool } from '../../database/Procedure.js';
30import { ColorUtils } from '../trace/base/ColorUtils.js';
31import { CpuFreqLimitRender, CpuFreqLimitsStruct } from '../../database/ui-worker/ProcedureWorkerCpuFreqLimits.js';
32import { renders } from '../../database/ui-worker/ProcedureWorker.js';
33import { CpuFreqStruct, FreqRender } from '../../database/ui-worker/ProcedureWorkerFreq.js';
34import { CpuStateRender, CpuStateStruct } from '../../database/ui-worker/ProcedureWorkerCpuState.js';
35import { Utils } from '../trace/base/Utils.js';
36
37export class SpFreqChart {
38  private trace: SpSystemTrace;
39
40  constructor(trace: SpSystemTrace) {
41    this.trace = trace;
42  }
43
44  async init() {
45    let cpuFreqStartTime = new Date().getTime();
46    let freqList = await queryCpuFreq();
47    let cpuStateFilterIds = await queryCpuStateFilter();
48    let cpuFreqLimits = await getCpuLimitFreqId();
49    let cpuFreqLimitsMax = await getCpuLimitFreqMax(
50      cpuFreqLimits
51        .map((limit) => {
52          return limit.maxFilterId;
53        })
54        .join(',')
55    );
56    info('Cpu Freq data size is: ', freqList!.length);
57    let freqMaxList = await queryCpuMaxFreq();
58    CpuFreqStruct.maxFreq = freqMaxList[0].maxFreq;
59    let maxFreqObj = Utils.getFrequencyWithUnit(freqMaxList[0].maxFreq);
60    CpuFreqStruct.maxFreq = maxFreqObj.maxFreq;
61    CpuFreqStruct.maxFreqName = maxFreqObj.maxFreqName;
62    for (let i = 0; i < freqList.length; i++) {
63      const it = freqList[i];
64      let traceRow = TraceRow.skeleton<CpuFreqStruct>();
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.focusHandler = (ev) => {
74        this.trace?.displayTip(
75          traceRow,
76          CpuFreqStruct.hoverCpuFreqStruct,
77          `<span>${ColorUtils.formatNumberComma(CpuFreqStruct.hoverCpuFreqStruct?.value!)} kHz</span>`
78        );
79      };
80      traceRow.onThreadHandler = (useCache) => {
81        let context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
82        traceRow.canvasSave(context);
83        (renders['freq'] as FreqRender).renderMainThread(
84          {
85            context: context,
86            useCache: useCache,
87            type: `freq${it.cpu}`,
88          },
89          traceRow
90        );
91        traceRow.canvasRestore(context);
92      };
93      this.trace.rowsEL?.appendChild(traceRow);
94    }
95    let heights = [4, 12, 21, 30];
96    for (let it of cpuStateFilterIds) {
97      let cpuStateRow = TraceRow.skeleton<CpuStateStruct>();
98      cpuStateRow.rowId = `${it.filterId}`;
99      cpuStateRow.rowType = TraceRow.ROW_TYPE_CPU_STATE;
100      cpuStateRow.rowParentId = '';
101      cpuStateRow.style.height = '40px';
102      cpuStateRow.name = `Cpu ${it.cpu} State`;
103      cpuStateRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
104      cpuStateRow.selectChangeHandler = this.trace.selectChangeHandler;
105      cpuStateRow.isHover = true;
106      cpuStateRow.supplier = () =>
107        queryCpuState(it.filterId).then((res) => {
108          res.forEach((r) => {
109            r.height = heights[it.value];
110            r.cpu = it.cpu;
111          });
112          return res;
113        });
114      cpuStateRow.focusHandler = (ev) => {
115        this.trace.displayTip(
116          cpuStateRow,
117          CpuStateStruct.hoverStateStruct,
118          `<span>State: ${CpuStateStruct.hoverStateStruct?.value}</span>`
119        );
120      };
121      cpuStateRow.onThreadHandler = (useCache: boolean) => {
122        let context = cpuStateRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
123        cpuStateRow.canvasSave(context);
124        (renders['cpu-state'] as CpuStateRender).renderMainThread(
125          {
126            cpuStateContext: context,
127            useCache: useCache,
128            type: `cpu-state-${it.cpu}`,
129            cpu: it.cpu,
130          },
131          cpuStateRow
132        );
133        cpuStateRow.canvasRestore(context);
134      };
135      this.trace.rowsEL?.appendChild(cpuStateRow);
136    }
137    let durTime = new Date().getTime() - cpuFreqStartTime;
138    info('The time to load the CpuFreq data is: ', durTime);
139    for (let limit of cpuFreqLimits) {
140      let findMax = Utils.getFrequencyWithUnit(
141        cpuFreqLimitsMax.find((maxLimit) => {
142          return maxLimit.filterId == limit.maxFilterId;
143        })?.maxValue || 0
144      );
145      let cpuFreqLimitRow = TraceRow.skeleton<CpuFreqLimitsStruct>();
146      cpuFreqLimitRow.rowId = `${limit.cpu}`;
147      cpuFreqLimitRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ_LIMIT;
148      cpuFreqLimitRow.rowParentId = '';
149      cpuFreqLimitRow.style.height = '40px';
150      cpuFreqLimitRow.name = `Cpu ${limit.cpu} Freq Limit`;
151      cpuFreqLimitRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
152      cpuFreqLimitRow.selectChangeHandler = this.trace.selectChangeHandler;
153      cpuFreqLimitRow.isHover = true;
154      cpuFreqLimitRow.supplier = () => getCpuLimitFreq(limit.maxFilterId, limit.minFilterId, limit.cpu);
155      cpuFreqLimitRow.focusHandler = (ev) => {
156        this.trace.displayTip(
157          cpuFreqLimitRow,
158          CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct,
159          `<span>Max Freq: ${ColorUtils.formatNumberComma(
160            CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct?.max || 0
161          )} kHz</span><span>Min Freq: ${ColorUtils.formatNumberComma(
162            CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct?.min || 0
163          )} kHz</span>`
164        );
165      };
166      cpuFreqLimitRow.onThreadHandler = (useCache: boolean) => {
167        let context = cpuFreqLimitRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
168        cpuFreqLimitRow.canvasSave(context);
169        (renders['cpu-limit-freq'] as CpuFreqLimitRender).renderMainThread(
170          {
171            context: context,
172            useCache: useCache,
173            type: `cpu-limit-freq-${limit.cpu}`,
174            cpu: limit.cpu,
175            maxFreq: findMax?.maxFreq || 0,
176            maxFreqName: findMax?.maxFreqName || '',
177          },
178          cpuFreqLimitRow
179        );
180        cpuFreqLimitRow.canvasRestore(context);
181      };
182      this.trace.rowsEL?.appendChild(cpuFreqLimitRow);
183    }
184  }
185}
186
187export class CpuFreqRowLimit {
188  cpu: number = 0;
189  maxFilterId: number = 0;
190  minFilterId: number = 0;
191}
192