• 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 */
15import { PerfCmdLine, PerfFile, PerfSample, PerfStack, PerfThread } from '../../bean/PerfProfile';
16import { query } from '../SqlLite';
17import { HiSysEventStruct } from '../ui-worker/ProcedureWorkerHiSysEvent';
18import { TaskTabStruct } from '../../component/trace/sheet/task/TabPaneTaskFrames';
19import { GpuCountBean, SearchGpuFuncBean } from '../../bean/GpufreqBean';
20
21export const queryPerfFiles = (): Promise<Array<PerfFile>> =>
22  query('queryPerfFiles', `select file_id as fileId,symbol,path from perf_files`, {});
23
24export const queryPerfCallChainName = (): //@ts-ignore
25Promise<Array<unknown>> => query('queryPerfCallChainName', `select callchain_id,depth,name from perf_callchain`, {});
26
27export const queryPerfProcess = (): Promise<Array<PerfThread>> =>
28  query(
29    'queryPerfThread',
30    `select process_id as pid,thread_name as processName from perf_thread where process_id = thread_id`,
31    {}
32  );
33
34export const queryPerfThread = (): Promise<Array<PerfThread>> =>
35  query(
36    'queryPerfThread',
37    `select a.thread_id as tid,
38       a.thread_name as threadName,
39       a.process_id as pid,
40       b.thread_name as processName
41from perf_thread a
42         left join (select distinct process_id, thread_name from perf_thread where process_id = thread_id) b
43         on a.process_id = b.process_id
44order by pid;`,
45    {}
46  );
47export const queryPerfSampleListByTimeRange = (
48  leftNs: number,
49  rightNs: number,
50  cpus: Array<number>,
51  processes: Array<number>,
52  threads: Array<number>,
53  eventTypeId?: number
54): Promise<Array<PerfSample>> => {
55  let sql = `
56select A.callchain_id as sampleId,
57       A.thread_id as tid,
58       C.thread_name as threadName,
59       A.thread_state as state,
60       C.process_id as pid,
61       (timestamp_trace - R.start_ts) as time,
62       cpu_id as core
63from perf_sample A,trace_range R
64left join perf_thread C on A.thread_id = C.thread_id
65where time >= $leftNs and time <= $rightNs and A.thread_id != 0
66    `;
67  if (eventTypeId !== undefined) {
68    sql = `${sql} and event_type_id = ${eventTypeId}`;
69  }
70  if (cpus.length !== 0 || processes.length !== 0 || threads.length !== 0) {
71    let arg1 = cpus.length > 0 ? `or core in (${cpus.join(',')}) ` : '';
72    let arg2 = processes.length > 0 ? `or pid in (${processes.join(',')}) ` : '';
73    let arg3 = threads.length > 0 ? `or tid in (${threads.join(',')})` : '';
74    let arg = `${arg1}${arg2}${arg3}`.substring(3);
75    sql = `${sql} and (${arg})`;
76  }
77  return query('queryPerfSampleListByTimeRange', sql, {
78    $leftNs: leftNs,
79    $rightNs: rightNs,
80  });
81};
82
83export const queryPerfSampleChildListByTree = (
84  leftNs: number,
85  rightNs: number,
86  pid?: number,
87  tid?: number,
88): Promise<Array<PerfSample>> => {
89  let sql = `
90select A.callchain_id as sampleId,
91       A.thread_id as tid,
92       C.thread_name as threadName,
93       A.thread_state as state,
94       C.process_id as pid,
95       (timestamp_trace - R.start_ts) as time,
96       cpu_id as core
97from perf_sample A,trace_range R
98left join perf_thread C on A.thread_id = C.thread_id
99where time >= $leftNs and time <= $rightNs and A.thread_id != 0
100    `;
101  if (pid) {
102    sql = `${sql} and C.process_id = ${pid}`;
103  }
104  if (pid && tid !== undefined) {
105    sql = `${sql} and A.thread_id = ${tid}`;
106  }
107  return query('queryPerfSampleChildListByTree', sql, {
108    $leftNs: leftNs,
109    $rightNs: rightNs,
110  });
111};
112
113export const queryPerfSampleIdsByTimeRange = (
114  leftNs: number,
115  rightNs: number,
116  cpus: Array<number>,
117  processes: Array<number>,
118  threads: Array<number>
119): Promise<Array<PerfSample>> => {
120  let sql = `
121select A.callchain_id as sampleId
122from perf_sample A,trace_range R
123left join perf_thread C on A.thread_id = C.thread_id
124where (timestamp_trace - R.start_ts) >= $leftNs and (timestamp_trace - R.start_ts) <= $rightNs and A.thread_id != 0
125    `;
126  if (cpus.length !== 0 || processes.length !== 0 || threads.length !== 0) {
127    let arg1 = cpus.length > 0 ? `or A.cpu_id in (${cpus.join(',')}) ` : '';
128    let arg2 = processes.length > 0 ? `or C.process_id in (${processes.join(',')}) ` : '';
129    let arg3 = threads.length > 0 ? `or A.thread_id in (${threads.join(',')})` : '';
130    let arg = `${arg1}${arg2}${arg3}`.substring(3);
131    sql = `${sql} and (${arg})`;
132  }
133  return query('queryPerfSampleIdsByTimeRange', sql, {
134    $leftNs: leftNs,
135    $rightNs: rightNs,
136  });
137};
138
139export const queryPerfSampleCallChain = (sampleId: number): Promise<Array<PerfStack>> =>
140  query(
141    'queryPerfSampleCallChain',
142    `
143    select
144    callchain_id as callChainId,
145    callchain_id as sampleId,
146    file_id as fileId,
147    symbol_id as symbolId,
148    vaddr_in_file as vaddrInFile,
149    source_file_id as sourceId,
150    line_number as lineNumber,
151    name as symbol
152from perf_callchain where callchain_id = $sampleId;
153    `,
154    { $sampleId: sampleId }
155  );
156
157export const queryPerfCmdline = (): Promise<Array<PerfCmdLine>> =>
158  query(
159    'queryPerfCmdline',
160    `
161    select report_value from perf_report  where report_type = 'cmdline'
162    `,
163    {}
164  );
165export const queryPerfEventType = (): Promise<Array<{ id: number; report: string }>> =>
166  query(
167    'queryPerfEventType',
168    `
169    select id,report_value as report from perf_report where id in (
170select distinct event_type_id from perf_sample);
171    `,
172    {}
173  );
174/**
175 * HiPerf
176 */
177export const queryHiPerfEventList = (): //@ts-ignore
178Promise<Array<unknown>> =>
179  query('queryHiPerfEventList', `select id,report_value from perf_report where report_type='config_name'`, {});
180export const queryHiPerfEventListData = (
181  eventTypeId: number
182): //@ts-ignore
183Promise<Array<unknown>> =>
184  query(
185    'queryHiPerfEventListData',
186    `
187        select s.callchain_id,
188               (s.timestamp_trace-t.start_ts) startNS
189        from perf_sample s,trace_range t
190        where
191            event_type_id=${eventTypeId}
192            and s.thread_id != 0
193            and s.callchain_id != -1;
194`,
195    { $eventTypeId: eventTypeId }
196  );
197export const queryHiPerfEventData = (
198  eventTypeId: number,
199  cpu: number
200): //@ts-ignore
201Promise<Array<unknown>> =>
202  query(
203    'queryHiPerfEventList',
204    `
205    select s.callchain_id,
206        (s.timestamp_trace-t.start_ts) startNS
207    from perf_sample s,trace_range t
208    where
209        event_type_id=${eventTypeId}
210        and cpu_id=${cpu}
211        and s.thread_id != 0
212        and s.callchain_id != -1;
213`,
214    { $eventTypeId: eventTypeId, $cpu: cpu }
215  );
216export const queryHiPerfCpuData = (
217  cpu: number
218): //@ts-ignore
219Promise<Array<unknown>> =>
220  query(
221    'queryHiPerfCpuData',
222    `
223    select s.callchain_id,
224        (s.timestamp_trace-t.start_ts) startNS, event_count, event_type_id
225    from perf_sample s,trace_range t
226    where
227        cpu_id=${cpu}
228        and s.thread_id != 0;`,
229    { $cpu: cpu }
230  );
231export const queryHiPerfCpuMergeData = (): //@ts-ignore
232Promise<Array<unknown>> =>
233  query(
234    'queryHiPerfCpuData',
235    `select s.callchain_id,(s.timestamp_trace-t.start_ts) startNS, event_count, event_type_id from perf_sample s,trace_range t
236where s.thread_id != 0;`,
237    {}
238  );
239export const queryHiPerfCpuMergeData2 = (): //@ts-ignore
240Promise<Array<unknown>> =>
241  query(
242    'queryHiPerfCpuData2',
243    `select distinct cpu_id from perf_sample where thread_id != 0 order by cpu_id desc;`,
244    {}
245  );
246
247export const queryHiPerfProcessData = (
248  pid: number
249): //@ts-ignore
250Promise<Array<unknown>> =>
251  query(
252    'queryHiPerfProcessData',
253    `
254SELECT sp.callchain_id,
255       th.thread_name,
256       th.thread_id                     tid,
257       th.process_id                    pid,
258       sp.timestamp_trace - tr.start_ts startNS,
259       event_count,
260       event_type_id
261from perf_sample sp,
262     trace_range tr
263         left join perf_thread th on th.thread_id = sp.thread_id
264where pid = ${pid} and sp.thread_id != 0 `,
265    { $pid: pid }
266  );
267
268export const queryHiPerfThreadData = (
269  tid: number
270): //@ts-ignore
271Promise<Array<unknown>> =>
272  query(
273    'queryHiPerfThreadData',
274    `
275SELECT sp.callchain_id,
276       th.thread_name,
277       th.thread_id                     tid,
278       th.process_id                    pid,
279       sp.timestamp_trace - tr.start_ts startNS,
280       event_count,
281       event_type_id
282from perf_sample sp,
283     trace_range tr
284         left join perf_thread th on th.thread_id = sp.thread_id
285where tid = ${tid} and sp.thread_id != 0 ;`,
286    { $tid: tid }
287  );
288
289export const getGpufreqDataCut = (
290  tIds: string,
291  funcName: string,
292  leftNS: number,
293  rightNS: number,
294  single: boolean,
295  loop: boolean
296): Promise<Array<SearchGpuFuncBean>> => {
297  let queryCondition: string = '';
298  if (single) {
299    queryCondition += `select s.funName,s.startTime,s.dur,s.startTime+s.dur as endTime,s.tid,s.threadName,s.pid from state s
300            where endTime between ${leftNS} and ${rightNS}`;
301  }
302  if (loop) {
303    queryCondition += `select s.funName,s.startTime,s.loopEndTime-s.startTime as dur,s.loopEndTime as endTime,s.tid,s.threadName,s.pid from state s
304            where endTime between ${leftNS} and ${rightNS} `;
305  }
306  return query(
307    'getGpufreqDataCut',
308    `
309            with state as
310              (select
311                 *
312              from
313                 (select
314                    c.name as funName,
315                    c.ts - r.start_ts as startTime,
316                    c.dur,
317                    lead(c.ts - r.start_ts, 1, null) over( order by c.ts - r.start_ts) loopEndTime,
318                    t.tid,
319                    t.name as threadName,
320                    p.pid
321                 from
322                    callstack c
323                 left join
324                    thread t on c.callid = t.id
325                 left join
326                    process p on t.ipid = p.id
327                 left join
328                    trace_range r
329                 where
330                    c.name like '${funcName}%'
331                 and
332                    tid = '${tIds}'
333                 and
334                    startTime between ${leftNS} and ${rightNS}))
335             ${queryCondition}
336          `,
337    { $search: funcName }
338  );
339};
340export const getGpufreqData = (leftNS: number, rightNS: number, earliest: boolean): Promise<Array<GpuCountBean>> => {
341  let queryCondition: string = '';
342  if (!earliest) {
343    queryCondition += ` where  not  ((s.ts - r.start_ts + ifnull(s.dur,0) < ${leftNS}) or (s.ts - r.start_ts > ${rightNS}))`;
344  }
345  return query(
346    'getGpufreqData',
347    `
348            with state as
349              (select
350                 name,
351                 filter_id,
352                 ts,
353                 endts,
354                 endts-ts as dur,
355                 value as val
356               from
357                  (select
358                     measure.filter_id,
359                     clock_event_filter.name,
360                     measure.ts,
361                     lead(ts, 1, null) over( order by measure.ts) endts,
362                     measure.value
363                  from
364                     clock_event_filter,
365                     trace_range
366                  left join
367                     measure
368                  where
369                     clock_event_filter.name = 'gpufreq'
370                  and
371                     clock_event_filter.type = 'clock_set_rate'
372                  and
373                     clock_event_filter.id = measure.filter_id
374                  order by measure.ts)
375               where
376                  endts is not null
377               )
378            select
379                s.name as thread,
380                s.val/1000000 as freq,
381                s.val*s.dur as value,
382                s.val,
383                s.ts-r.start_ts as startNS,
384                s.dur,
385                s.endts- r.start_ts as endTime
386            from
387                state s,
388                trace_range r
389            ${queryCondition}
390            order by ts
391          `,
392    { $leftNS: leftNS, $rightNS: rightNS }
393  );
394};
395
396export const queryHiSysEventTabData = (leftNs: number, rightNs: number): Promise<Array<HiSysEventStruct>> =>
397  query(
398    'queryHiSysEventTabData',
399    `SELECT S.id,
400            D2.data AS domain,
401            D.data AS eventName,
402            type AS eventType,
403            time_zone AS tz,
404            pid,
405            tid,
406            uid,
407            info,
408            level,
409            seq,
410            contents,
411            S.ts - TR.start_ts AS startTs,
412            1 AS dur,
413            CASE
414            WHEN level = 'MINOR' THEN
415             0
416            WHEN level = 'CRITICAL' THEN
417             1
418            END AS depth
419        FROM hisys_all_event AS S ,trace_range AS TR
420        LEFT JOIN data_dict AS D on S.event_name_id = D.id
421        LEFT JOIN data_dict AS D2 on S.domain_id = D2.id
422        WHERE S.id is not null
423         and    startTs >= ${Math.floor(leftNs)}
424         and    startTs <= ${Math.floor(rightNs)}
425        ORDER BY S.ts`
426  );
427export const queryHiSysEventData = (): Promise<Array<HiSysEventStruct>> =>
428  query(
429    'queryHiSysEventData',
430    `SELECT l.ts - tr.start_ts as startNs  FROM hisys_all_event AS l, trace_range tr WHERE startNs  > 0 LIMIT 1`
431  );
432export const queryHiPerfProcessCount = (
433  leftNs: number,
434  rightNs: number,
435  cpus: Array<number>,
436  threads: Array<number>,
437  processes: Array<number>
438): //@ts-ignore
439Promise<Array<unknown>> => {
440  let str = '';
441  if (processes.length > 0) {
442    str = ` and C.process_id in (${processes.join(',')})`;
443  }
444  if (threads.length > 0) {
445    str = ` and A.thread_id in (${threads.join(',')}) `;
446  }
447  if (processes.length > 0 && threads.length > 0) {
448    str = ` and (C.process_id in (${processes.join(',')}) or A.thread_id in (${threads.join(',')}))`;
449  }
450  if (cpus.length > 0) {
451    str = ` and A.cpu_id in (${cpus.join(',')})`;
452  }
453  if (cpus.length > 0 && processes.length > 0) {
454    str = ` and (C.process_id in (${processes.join(',')}) or A.cpu_id in (${cpus.join(',')}))`;
455  }
456  return query(
457    'queryHiPerfProcessCount',
458    `
459    select     C.process_id as pid,
460               (A.timestamp_trace - R.start_ts) as time,
461               C.thread_name as threadName,
462               A.thread_id as tid,
463               A.id,
464               A.callchain_id
465        from perf_sample A,trace_range R
466             left join perf_thread C on A.thread_id = C.thread_id  and  A.thread_id != 0
467        where time >= $leftNs and time <= $rightNs and A.callchain_id > 0
468        ${str}
469    `,
470    { $leftNs: leftNs, $rightNs: rightNs }
471  );
472};
473export const queryTransferList = (): Promise<Array<{ id: number; cmdStr: string }>> =>
474  query('queryTransferList', `select id, report_value as cmdStr from perf_report where report_type = 'config_name'`);
475export const queryConcurrencyTask = (
476  itid: number,
477  selectStartTime: number,
478  selectEndTime: number
479): Promise<TaskTabStruct[]> =>
480  query<TaskTabStruct>(
481    'queryConcurrencyTask',
482    `SELECT thread.tid,
483            thread.ipid,
484            callstack.name                AS funName,
485            callstack.ts                  AS startTs,
486            (case when callstack.dur = -1 then (SELECT end_ts FROM trace_range) else callstack.dur end) as dur,
487            callstack.id,
488            task_pool.priority,
489            task_pool.allocation_task_row AS allocationTaskRow,
490            task_pool.execute_task_row    AS executeTaskRow,
491            task_pool.return_task_row     AS returnTaskRow,
492            task_pool.task_id             AS executeId
493     FROM thread
494            LEFT JOIN callstack ON thread.id = callstack.callid
495            LEFT JOIN task_pool ON callstack.id = task_pool.execute_task_row
496     WHERE ipid in (SELECT thread.ipid
497                   FROM thread
498                   WHERE thread.itid = $itid)
499       AND thread.name LIKE '%TaskWork%'
500       AND callstack.name LIKE 'H:Task Perform:%'
501       AND -- 左包含
502           (($selectStartTime <= callstack.ts AND $selectEndTime > callstack.ts)
503        OR -- 右包含
504       ($selectStartTime < callstack.ts + callstack.dur AND $selectEndTime >= callstack.ts + callstack.dur)
505        OR -- 包含
506       ($selectStartTime >= callstack.ts AND $selectEndTime <= callstack.ts +
507        (case when callstack.dur = -1 then (SELECT end_ts FROM trace_range) else callstack.dur end))
508        OR -- 被包含
509       ($selectStartTime <= callstack.ts AND $selectEndTime >= callstack.ts + callstack.dur))
510     ORDER BY callstack.ts;`,
511    { $itid: itid, $selectStartTime: selectStartTime, $selectEndTime: selectEndTime }
512  );
513