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 { query } from '../SqlLite';
17import { IrqStruct } from '../ui-worker/ProcedureWorkerIrq';
18import { IrqAndSoftirqBean } from '../../component/trace/sheet/irq/irqAndSoftirqBean'
19import { Utils } from '../../component/trace/base/Utils';
20
21export const queryIrqList = (traceId?: string): Promise<Array<{ name: string; cpu: number }>> =>
22  query('queryIrqList',
23  `SELECT 
24  * 
25  FROM
26    (SELECT DISTINCT cat AS name, callid AS cpu FROM irq WHERE cat<>'ipi')
27  ORDER By 
28    name,
29    cpu`
30    , {}, { traceId: traceId });
31
32export const queryAllIrqNames = async (traceId?: string): Promise<Array<{ ipiName: string; name: string; id: number }>> => {
33  let allIrqNamesBuffer = await query(
34    'queryAllIrqNames',
35    `select
36      id,
37      case 
38    when 
39      cat = 'ipi' then 'IPI' || name else name end as ipiName from irq;`,
40    {}, 
41    { traceId: traceId, action: 'exec-buf' }
42  );
43  // @ts-ignore
44  return Utils.convertJSON(allIrqNamesBuffer);
45};
46
47export const queryIrqData = (callid: number, cat: string): Promise<Array<IrqStruct>> => {
48  let sqlSoftIrq = `
49    select i.ts - t.start_ts as startNS,i.dur,i.name,i.depth,argsetid as argSetId,i.id from irq i,
50trace_range t where i.callid = ${callid} and i.cat = 'softirq'
51    `;
52  let sqlIrq = `
53    select i.ts - t.start_ts as startNS,i.dur,
54        case when i.cat = 'ipi' then 'IPI' || i.name else i.name end as name,
55        i.depth,
56        argsetid as argSetId,
57        i.id 
58        from irq i,trace_range t 
59        where i.callid = ${callid} and ((i.cat = 'irq' and i.flag ='1') or i.cat = 'ipi') 
60    `;
61  return query('queryIrqData', cat === 'irq' ? sqlIrq : sqlSoftIrq, {});
62};
63
64export const queryIrqDataBoxSelect = (
65  callIds: Array<number>,
66  startNS: number,
67  endNS: number
68): Promise<Array<unknown>> => {
69  let sqlIrq = `
70select case when i.cat = 'ipi' then 'IPI' || i.name else i.name end as irqName,
71       'irq'                                                        as cat,
72       sum(
73        min(${endNS},(i.ts - t.start_ts + iif(i.dur = -1 or i.dur is null, 0, i.dur))) - max(${startNS},i.ts - t.start_ts)
74        )                                                           as wallDuration,
75       max(dur)                                                     as maxDuration,
76       count(1)                                                     as count,
77       avg(ifnull(dur, 0))                                          as avgDuration
78from irq i,
79     trace_range t
80where ((i.cat = 'irq' and i.flag = '1') or i.cat = 'ipi')
81  and callid in (${callIds.join(',')})
82  and max(i.ts - t.start_ts, ${startNS}) <= min(i.ts - t.start_ts + dur, ${endNS})
83group by irqName;
84    `;
85  return query('queryIrqDataBoxSelect', callIds.length > 0 ? sqlIrq : '', {}, { traceId: Utils.currentSelectTrace });
86};
87
88export const querySoftIrqDataBoxSelect = (
89  callIds: Array<number>,
90  startNS: number,
91  endNS: number
92): Promise<Array<unknown>> => {
93  let sqlIrq = `
94select i.name              as irqName,
95       i.cat,
96       sum(
97         min(${endNS},(i.ts - t.start_ts + iif(i.dur = -1 or i.dur is null, 0, i.dur))) - max(${startNS},i.ts - t.start_ts)
98         )                 as wallDuration,
99       max(dur)            as maxDuration,
100       count(1)            as count,
101       avg(ifnull(dur, 0)) as avgDuration
102from irq i,
103     trace_range t
104where callid in (${callIds.join(',')})
105  and i.cat = 'softirq'
106  and max(i.ts - t.start_ts, ${startNS}) <= min(i.ts - t.start_ts + dur, ${endNS})
107group by irqName;
108    `;
109  return query('querySoftIrqDataBoxSelect', callIds.length > 0 ? sqlIrq : '', {}, { traceId: Utils.currentSelectTrace });
110};
111
112export const queryIrqSelectData = (callIds: Array<number>, startNS: number, endNS: number): Promise<Array<IrqAndSoftirqBean>> =>
113  query(
114    'getIrqSelectData',
115    `
116    SELECT
117        'irq' AS cat,
118        i.callid,
119        CASE
120          WHEN i.cat = 'ipi'
121          THEN 'IPI' || i.name
122          ELSE i.name
123          END AS name,
124        1 As count,
125        true As isFirstObject,
126        2 AS priority, 
127        MAX(${startNS},i.ts - TR.start_ts) AS startTime,
128        MIN(${endNS},(i.ts - TR.start_ts + iif(i.dur = -1 OR i.dur IS NULL, 0, i.dur))) AS endTime,
129        MIN(${endNS},(i.ts - TR.start_ts + iif(i.dur = -1 OR i.dur IS NULL, 0, i.dur))) - MAX(${startNS},i.ts - TR.start_ts) AS wallDuration 
130    FROM
131      irq i 
132    LEFT JOIN
133      trace_range AS TR
134      WHERE
135      i.callid IN (${callIds.join(',')})
136    AND
137      NOT ((i.ts - TR.start_ts + iif(i.dur = -1 OR i.dur IS NULL, 0, i.dur) < ${startNS}) OR (i.ts - TR.start_ts > ${endNS}))
138    AND ( ( i.cat = 'irq' AND i.flag = '1' ) OR i.cat = 'ipi' )`
139  );
140
141export const querySoftirqSelectData = (callIds: Array<number>, startNS: number, endNS: number): Promise<Array<IrqAndSoftirqBean>> =>
142  query(
143    'getSoftirqSelectData',
144    `
145      SELECT
146          'softirq' AS cat,
147          i.callid,
148          i.name,
149          1 As count,
150          true As isFirstObject,
151          1 AS priority, 
152          MAX(${startNS},i.ts - TR.start_ts) AS startTime,
153          MIN(${endNS},(i.ts - TR.start_ts + iif(i.dur = -1 OR i.dur IS NULL, 0, i.dur))) AS endTime,
154          MIN(${endNS},(i.ts - TR.start_ts + iif(i.dur = -1 OR i.dur IS NULL, 0, i.dur))) - MAX(${startNS},i.ts - TR.start_ts) AS wallDuration 
155      FROM
156        irq i 
157      LEFT JOIN
158        trace_range AS TR
159      WHERE
160        i.callid IN (${callIds.join(',')})
161      AND
162        NOT ((i.ts - TR.start_ts + iif(i.dur = -1 OR i.dur IS NULL, 0, i.dur) < ${startNS}) OR (i.ts - TR.start_ts > ${endNS}))
163      AND 
164        i.cat = 'softirq' `
165  );