• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2021 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14import { TraficEnum } from '../utils/QueryEnum';
15
16export const chartHiperfThreadData10MSProtoSql = (args: any): string => {
17  return `select startNS as startNS,
18                 max(event_count)                                                         eventCount,
19                 sample_count as sampleCount,
20                 event_type_id as eventTypeId,
21                 callchain_id as callchainId,
22                 (startNS / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px
23          from (SELECT sp.callchain_id,
24                       (sp.timestamp_trace - ${args.recordStartNS}) / 10000000 * 10000000 startNS,
25                       sum(event_count)                                                   event_count,
26                       count(event_count)                                                 sample_count,
27                       event_type_id
28                from perf_sample sp
29                where sp.thread_id = ${args.tid}
30                  and sp.thread_id != 0 ${args.drawType >= 0 ? 'and event_type_id =' + args.drawType : ''}
31                group by startNS)
32          where startNS + 10000000 >= ${Math.floor(args.startNS)}
33            and startNS <= ${Math.floor(args.endNS)}
34          group by px;`;
35};
36export const chartHiperfThreadDataProtoSql = (args: any): string => {
37  return `SELECT (sp.timestamp_trace - ${args.recordStartNS})          startNS,
38                 event_count as eventCount,
39                 1 as sampleCount,
40                 event_type_id as eventTypeId,
41                 sp.callchain_id as callchainId,
42                 (sp.timestamp_trace - ${args.recordStartNS}) / (${Math.floor(
43    (args.endNS - args.startNS) / args.width
44  )}) AS px
45          from perf_sample sp
46          where sp.thread_id = ${args.tid}
47            and sp.thread_id != 0 ${args.drawType >= 0 ? 'and event_type_id =' + args.drawType : ''}
48            and startNS >= ${Math.floor(args.startNS)}
49            and startNS <= ${Math.floor(args.endNS)}
50          group by px;`;
51};
52
53export function hiperfThreadDataReceiver(data: any, proc: Function): void {
54  let sql: string;
55  if (data.params.scale > 30_000_000) {
56    sql = chartHiperfThreadData10MSProtoSql(data.params);
57  } else {
58    sql = chartHiperfThreadDataProtoSql(data.params);
59  }
60  let res = proc(sql);
61  arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
62}
63
64function arrayBufferHandler(data: any, res: any[], transfer: boolean): void {
65  let maxCpuCount = data.params.maxCpuCount;
66  let intervalPerf = data.params.intervalPerf;
67  let usage = data.params.drawType === -2;
68  let perfThread = new PerfThread(data, transfer, res.length);
69  let maxEventCount = Math.max(
70    ...res.map((it) => {
71      data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiperfData);
72      return it.eventCount;
73    })
74  );
75  res.forEach((it, i) => {
76    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiperfData);
77    perfThread.startNS[i] = it.startNS || it.startNs;
78    perfThread.eventCount[i] = it.eventCount;
79    perfThread.sampleCount[i] = it.sampleCount;
80    perfThread.eventTypeId[i] = it.eventTypeId;
81    perfThread.callChainId[i] = it.callchainId;
82    if (usage) {
83      perfThread.height[i] = maxCpuCount === -1
84        ? Math.floor((it.sampleCount / (10 / intervalPerf)) * 40)
85        : Math.floor((it.sampleCount / (10 / intervalPerf) / maxCpuCount) * 40);
86    } else {
87      perfThread.height[i] = Math.floor((it.eventCount / maxEventCount) * 40);
88    }
89  });
90  postPerfThreadMessage(data, transfer, perfThread, res.length);
91}
92function postPerfThreadMessage(data: any, transfer: boolean, perfThread: PerfThread, len: number) {
93  (self as unknown as Worker).postMessage(
94    {
95      id: data.id,
96      action: data.action,
97      results: transfer
98        ? {
99            startNS: perfThread.startNS.buffer,
100            eventCount: perfThread.eventCount.buffer,
101            sampleCount: perfThread.sampleCount.buffer,
102            eventTypeId: perfThread.eventTypeId.buffer,
103            callChainId: perfThread.callChainId.buffer,
104            height: perfThread.height.buffer,
105          }
106        : {},
107      len: len,
108      transfer: transfer,
109    },
110    transfer
111      ? [
112          perfThread.startNS.buffer,
113          perfThread.eventCount.buffer,
114          perfThread.sampleCount.buffer,
115          perfThread.eventTypeId.buffer,
116          perfThread.callChainId.buffer,
117          perfThread.height.buffer,
118        ]
119      : []
120  );
121}
122class PerfThread {
123  startNS: Float64Array;
124  eventCount: Int32Array;
125  sampleCount: Int32Array;
126  eventTypeId: Int32Array;
127  callChainId: Int32Array;
128  height: Int32Array;
129  constructor(data: any, transfer: boolean, len: number) {
130    this.startNS = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.startNS);
131    this.eventCount = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.eventCount);
132    this.sampleCount = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.sampleCount);
133    this.eventTypeId = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.eventTypeId);
134    this.callChainId = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.callChainId);
135    this.height = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.height);
136  }
137}
138