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';
17import { TraceRow } from '../trace/base/TraceRow';
18import { info } from '../../../log/Log';
19import { renders } from '../../database/ui-worker/ProcedureWorker';
20import { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU';
21import { IrqRender, IrqStruct } from '../../database/ui-worker/ProcedureWorkerIrq';
22import { irqDataSender } from '../../database/data-trafic/IrqDataSender';
23import { queryAllIrqNames, queryIrqList } from '../../database/sql/Irq.sql';
24import { rowThreadHandler } from './SpChartManager';
25import { BaseStruct } from '../../bean/BaseStruct';
26
27export class SpIrqChart {
28  private readonly trace: SpSystemTrace;
29
30  constructor(trace: SpSystemTrace) {
31    this.trace = trace;
32  }
33
34  async init(parentRow?: TraceRow<BaseStruct>, traceId?: string): Promise<void> {
35    let irqStartTime = new Date().getTime();
36    let irqList = await queryIrqList(traceId);
37    if (irqList.length === 0) {
38      return;
39    }
40    let folder = await this.initFolder(traceId);
41    parentRow?.addChildTraceRow(folder);
42    await this.initData(folder, irqStartTime, irqList, traceId);
43  }
44
45  async initData(
46    folder: TraceRow<BaseStruct>,
47    irqStartTime: number,
48    irqList: Array<{ name: string; cpu: number }>,
49    traceId?: string,
50  ): Promise<void> {
51    //加载irq table所有id和name数据
52    let irqNamesArray = await queryAllIrqNames(traceId);
53    let irqNameMap: Map<number, string> = new Map();
54    irqNamesArray.forEach((it) => {
55      irqNameMap.set(it.id, it.ipiName);
56    });
57    info('irqList data size is: ', irqList!.length);
58    if (!traceId) {
59      this.trace.rowsEL?.appendChild(folder);
60    }
61    for (let i = 0; i < irqList.length; i++) {
62      const it = irqList[i];
63      this.addIrqRow(it, i, folder, irqNameMap, traceId);
64    }
65    let durTime = new Date().getTime() - irqStartTime;
66    info('The time to load the ClockData is: ', durTime);
67  }
68
69  addIrqRow(
70    it: { name: string; cpu: number },
71    index: number,
72    folder: TraceRow<BaseStruct>,
73    irqNameMap: Map<number, string>,
74    traceId?: string,
75  ): void {
76    let traceRow = TraceRow.skeleton<IrqStruct>(traceId);
77    traceRow.rowId = it.name + it.cpu;
78    traceRow.rowType = TraceRow.ROW_TYPE_IRQ;
79    traceRow.rowParentId = folder.rowId;
80    traceRow.style.height = '40px';
81    traceRow.name = `${it.name} Cpu ${it.cpu}`;
82    traceRow.rowHidden = !folder.expansion;
83    traceRow.setAttribute('children', '');
84    traceRow.setAttribute('callId', `${it.cpu}`);
85    traceRow.setAttribute('cat', `${it.name}`);
86    traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
87    traceRow.selectChangeHandler = this.trace.selectChangeHandler;
88    traceRow.supplierFrame = (): Promise<IrqStruct[]> => {
89      return irqDataSender(it.cpu, it.name, traceRow).then((irqs) => {
90        irqs.forEach((irq): void => {
91          let irqName = irqNameMap.get(irq.id!);
92          irq.name = irqName || '';
93        });
94        return irqs;
95      });
96    };
97    traceRow.focusHandler = (): void => {
98      this.trace?.displayTip(
99        traceRow,
100        IrqStruct.hoverIrqStruct,
101        `<span>${IrqStruct.hoverIrqStruct?.name || ''}</span>`
102      );
103    };
104    traceRow.findHoverStruct = (): void => {
105      IrqStruct.hoverIrqStruct = traceRow.getHoverStruct();
106    };
107    traceRow.onThreadHandler = rowThreadHandler<IrqRender>(
108      'irq',
109      'context',
110      {
111        type: it.name,
112        index: index,
113      },
114      traceRow,
115      this.trace
116    );
117    folder.addChildTraceRow(traceRow);
118  }
119
120  async initFolder(traceId?: string): Promise<TraceRow<BaseStruct>> {
121    let irqFolder = TraceRow.skeleton(traceId);
122    irqFolder.rowId = 'Irqs';
123    irqFolder.index = 0;
124    irqFolder.rowType = TraceRow.ROW_TYPE_IRQ_GROUP;
125    irqFolder.rowParentId = '';
126    irqFolder.style.height = '40px';
127    irqFolder.folder = true;
128    irqFolder.name = 'Irqs'; /* & I/O Latency */
129    irqFolder.favoriteChangeHandler = this.trace.favoriteChangeHandler;
130    irqFolder.selectChangeHandler = this.trace.selectChangeHandler;
131    irqFolder.supplier = (): Promise<Array<BaseStruct>> => new Promise<Array<BaseStruct>>((resolve) => resolve([]));
132    irqFolder.onThreadHandler = (useCache): void => {
133      irqFolder.canvasSave(this.trace.canvasPanelCtx!);
134      if (irqFolder.expansion) {
135        this.trace.canvasPanelCtx?.clearRect(0, 0, irqFolder.frame.width, irqFolder.frame.height);
136      } else {
137        (renders.empty as EmptyRender).renderMainThread(
138          {
139            context: this.trace.canvasPanelCtx,
140            useCache: useCache,
141            type: '',
142          },
143          irqFolder
144        );
145      }
146      irqFolder.canvasRestore(this.trace.canvasPanelCtx!, this.trace);
147    };
148    return irqFolder;
149  }
150}
151