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