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 { Args } from '../CommonArgs'; 15import { threadStateList } from '../utils/AllMemoryCache'; 16import { filterDataByGroup } from '../utils/DataFilter'; 17import { TraficEnum, threadStateToNumber } from '../utils/QueryEnum'; 18 19export const chartThreadDataSql = (args: Args):unknown => { 20 return `select B.cpu, max(B.dur) AS dur, B.itid AS id, B.tid AS tid, B.state, B.pid, 21 B.ts - ${args.recordStartNS} AS startTime, ifnull(B.arg_setid, -1) AS argSetId, 22 ((B.ts - ${args.recordStartNS}) / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px 23 from thread_state AS B 24 where B.tid = ${args.tid} 25 and B.pid = ${args.pid} 26 and B.state != 'Running' 27 and startTime + dur >= ${Math.floor(args.startNS)} 28 and startTime <= ${Math.floor(args.endNS)} 29 group by px 30 union all 31 select B.cpu, max(B.dur) AS dur, B.itid AS id, B.tid AS tid, B.state, 32 B.pid, B.ts - ${args.recordStartNS} AS startTime, ifnull(B.arg_setid, -1) AS argSetId, 33 ((B.ts - ${args.recordStartNS}) / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px 34 from thread_state AS B 35 where B.tid = ${args.tid} 36 and B.pid = ${args.pid} 37 and B.state = 'Running' 38 and startTime + dur >= ${Math.floor(args.startNS)} 39 and startTime <= ${Math.floor(args.endNS)} 40 group by px; 41 ;`; 42}; 43 44export const sqlMem = (args: Args): string => { 45 return `select B.cpu, B.dur AS dur, B.itid AS id, B.tid AS tid, B.state, B.pid, B.ts - ${args.recordStartNS} AS startTime, 46 ifnull(B.arg_setid, -1) AS argSetId 47 from thread_state AS B 48 where B.tid = ${args.tid} 49 and B.pid = ${args.pid};`; 50}; 51 52export function threadDataReceiver(data: unknown, proc: Function): void { 53 //@ts-ignore 54 if (data.params.trafic === TraficEnum.Memory) { 55 //@ts-ignore 56 let key = `${data.params.pid}-${data.params.tid}`; 57 if (!threadStateList.has(key)) { 58 //@ts-ignore 59 threadStateList.set(key, proc(sqlMem(data.params))); 60 } 61 let array = threadStateList.get(key) || []; 62 let res = filterDataByGroup( 63 array, 64 'startTime', 65 'dur', //@ts-ignore 66 data.params.startNS, //@ts-ignore 67 data.params.endNS, //@ts-ignore 68 data.params.width, 69 undefined, 70 //@ts-ignore 71 (a) => a.state === 'Running', 72 false 73 ); 74 arrayBufferHandler(data, res, true, array.length === 0); 75 return; 76 } else { 77 //@ts-ignore 78 let sql = chartThreadDataSql(data.params); 79 let res = proc(sql); //@ts-ignore 80 arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer, false); 81 } 82} 83 84function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean, isEmpty: boolean): void { 85 //@ts-ignore 86 let startTime = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startTime); //@ts-ignore 87 let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur); //@ts-ignore 88 let cpu = new Int8Array(transfer ? res.length : data.params.sharedArrayBuffers.cpu); //@ts-ignore 89 let id = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.id); //@ts-ignore 90 let tid = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.tid); //@ts-ignore 91 let state = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.state); //@ts-ignore 92 let pid = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.pid); //@ts-ignore 93 let argSetID = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.argSetID); 94 res.forEach((it, i) => { 95 //@ts-ignore 96 data.params.trafic === TraficEnum.ProtoBuffer && (it = it.processThreadData); //@ts-ignore 97 startTime[i] = it.startTime; //@ts-ignore 98 dur[i] = it.dur; //@ts-ignore 99 cpu[i] = it.cpu; //@ts-ignore 100 id[i] = it.id; //@ts-ignore 101 tid[i] = it.tid; //@ts-ignore 102 state[i] = threadStateToNumber(it.state); //@ts-ignore 103 pid[i] = it.pid; //@ts-ignore 104 argSetID[i] = it.argSetId; 105 }); 106 (self as unknown as Worker).postMessage( 107 { 108 //@ts-ignore 109 id: data.id, //@ts-ignore 110 action: data.action, 111 results: transfer 112 ? { 113 id: id.buffer, 114 tid: tid.buffer, 115 state: state.buffer, 116 startTime: startTime.buffer, 117 dur: dur.buffer, 118 cpu: cpu.buffer, 119 pid: pid.buffer, 120 argSetID: argSetID.buffer, 121 } 122 : {}, 123 len: res.length, 124 transfer: transfer, 125 isEmpty: isEmpty, 126 }, 127 transfer 128 ? [startTime.buffer, dur.buffer, cpu.buffer, id.buffer, tid.buffer, state.buffer, pid.buffer, argSetID.buffer] 129 : [] 130 ); 131} 132