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'; 19 20export const queryPerfFiles = (): Promise<Array<PerfFile>> => 21 query('queryPerfFiles', `select file_id as fileId,symbol,path from perf_files`, {}); 22 23export const queryPerfCallChainName = (): Promise<Array<any>> => 24 query('queryPerfCallChainName', `select callchain_id,depth,name from perf_callchain`, {}); 25 26export const queryPerfProcess = (): Promise<Array<PerfThread>> => 27 query( 28 'queryPerfThread', 29 `select process_id as pid,thread_name as processName from perf_thread where process_id = thread_id`, 30 {} 31 ); 32 33export const queryPerfThread = (): Promise<Array<PerfThread>> => 34 query( 35 'queryPerfThread', 36 `select a.thread_id as tid, 37 a.thread_name as threadName, 38 a.process_id as pid, 39 b.thread_name as processName 40from perf_thread a 41 left join (select distinct process_id, thread_name from perf_thread where process_id = thread_id) b 42 on a.process_id = b.process_id 43order by pid;`, 44 {} 45 ); 46export const queryPerfSampleListByTimeRange = ( 47 leftNs: number, 48 rightNs: number, 49 cpus: Array<number>, 50 processes: Array<number>, 51 threads: Array<number>, 52 eventTypeId?: number 53): Promise<Array<PerfSample>> => { 54 let sql = ` 55select A.callchain_id as sampleId, 56 A.thread_id as tid, 57 C.thread_name as threadName, 58 A.thread_state as state, 59 C.process_id as pid, 60 (timestamp_trace - R.start_ts) as time, 61 cpu_id as core 62from perf_sample A,trace_range R 63left join perf_thread C on A.thread_id = C.thread_id 64where time >= $leftNs and time <= $rightNs and A.thread_id != 0 65 `; 66 if (eventTypeId !== undefined) { 67 sql = `${sql} and event_type_id = ${eventTypeId}`; 68 } 69 if (cpus.length != 0 || processes.length != 0 || threads.length != 0) { 70 let arg1 = cpus.length > 0 ? `or core in (${cpus.join(',')}) ` : ''; 71 let arg2 = processes.length > 0 ? `or pid in (${processes.join(',')}) ` : ''; 72 let arg3 = threads.length > 0 ? `or tid in (${threads.join(',')})` : ''; 73 let arg = `${arg1}${arg2}${arg3}`.substring(3); 74 sql = `${sql} and (${arg})`; 75 } 76 return query('queryPerfSampleListByTimeRange', sql, { 77 $leftNs: leftNs, 78 $rightNs: rightNs, 79 }); 80}; 81 82export const queryPerfSampleIdsByTimeRange = ( 83 leftNs: number, 84 rightNs: number, 85 cpus: Array<number>, 86 processes: Array<number>, 87 threads: Array<number> 88): Promise<Array<PerfSample>> => { 89 let sql = ` 90select A.callchain_id as sampleId 91from perf_sample A,trace_range R 92left join perf_thread C on A.thread_id = C.thread_id 93where (timestamp_trace - R.start_ts) >= $leftNs and (timestamp_trace - R.start_ts) <= $rightNs and A.thread_id != 0 94 `; 95 if (cpus.length != 0 || processes.length != 0 || threads.length != 0) { 96 let arg1 = cpus.length > 0 ? `or A.cpu_id in (${cpus.join(',')}) ` : ''; 97 let arg2 = processes.length > 0 ? `or C.process_id in (${processes.join(',')}) ` : ''; 98 let arg3 = threads.length > 0 ? `or A.thread_id in (${threads.join(',')})` : ''; 99 let arg = `${arg1}${arg2}${arg3}`.substring(3); 100 sql = `${sql} and (${arg})`; 101 } 102 return query('queryPerfSampleIdsByTimeRange', sql, { 103 $leftNs: leftNs, 104 $rightNs: rightNs, 105 }); 106}; 107 108export const queryPerfSampleCallChain = (sampleId: number): Promise<Array<PerfStack>> => 109 query( 110 'queryPerfSampleCallChain', 111 ` 112 select 113 callchain_id as callChainId, 114 callchain_id as sampleId, 115 file_id as fileId, 116 symbol_id as symbolId, 117 vaddr_in_file as vaddrInFile, 118 name as symbol 119from perf_callchain where callchain_id = $sampleId; 120 `, 121 { $sampleId: sampleId } 122 ); 123 124export const queryPerfCmdline = (): Promise<Array<PerfCmdLine>> => 125 query( 126 'queryPerfCmdline', 127 ` 128 select report_value from perf_report where report_type = 'cmdline' 129 `, 130 {} 131 ); 132export const queryPerfEventType = (): Promise<Array<{ id: number; report: string }>> => 133 query( 134 'queryPerfEventType', 135 ` 136 select id,report_value as report from perf_report where id in ( 137select distinct event_type_id from perf_sample); 138 `, 139 {} 140 ); 141/** 142 * HiPerf 143 */ 144export const queryHiPerfEventList = (): Promise<Array<any>> => 145 query('queryHiPerfEventList', `select id,report_value from perf_report where report_type='config_name'`, {}); 146export const queryHiPerfEventListData = (eventTypeId: number): Promise<Array<any>> => 147 query( 148 'queryHiPerfEventListData', 149 ` 150 select s.callchain_id, 151 (s.timestamp_trace-t.start_ts) startNS 152 from perf_sample s,trace_range t 153 where 154 event_type_id=${eventTypeId} 155 and s.thread_id != 0 156 and s.callchain_id != -1; 157`, 158 { $eventTypeId: eventTypeId } 159 ); 160export const queryHiPerfEventData = (eventTypeId: number, cpu: number): Promise<Array<any>> => 161 query( 162 'queryHiPerfEventList', 163 ` 164 select s.callchain_id, 165 (s.timestamp_trace-t.start_ts) startNS 166 from perf_sample s,trace_range t 167 where 168 event_type_id=${eventTypeId} 169 and cpu_id=${cpu} 170 and s.thread_id != 0 171 and s.callchain_id != -1; 172`, 173 { $eventTypeId: eventTypeId, $cpu: cpu } 174 ); 175export const queryHiPerfCpuData = (cpu: number): Promise<Array<any>> => 176 query( 177 'queryHiPerfCpuData', 178 ` 179 select s.callchain_id, 180 (s.timestamp_trace-t.start_ts) startNS, event_count, event_type_id 181 from perf_sample s,trace_range t 182 where 183 cpu_id=${cpu} 184 and s.thread_id != 0;`, 185 { $cpu: cpu } 186 ); 187export const queryHiPerfCpuMergeData = (): Promise<Array<any>> => 188 query( 189 'queryHiPerfCpuData', 190 `select s.callchain_id,(s.timestamp_trace-t.start_ts) startNS, event_count, event_type_id from perf_sample s,trace_range t 191where s.thread_id != 0;`, 192 {} 193 ); 194export const queryHiPerfCpuMergeData2 = (): Promise<Array<any>> => 195 query( 196 'queryHiPerfCpuData2', 197 `select distinct cpu_id from perf_sample where thread_id != 0 order by cpu_id desc;`, 198 {} 199 ); 200 201export const queryHiPerfProcessData = (pid: number): Promise<Array<any>> => 202 query( 203 'queryHiPerfProcessData', 204 ` 205SELECT sp.callchain_id, 206 th.thread_name, 207 th.thread_id tid, 208 th.process_id pid, 209 sp.timestamp_trace - tr.start_ts startNS, 210 event_count, 211 event_type_id 212from perf_sample sp, 213 trace_range tr 214 left join perf_thread th on th.thread_id = sp.thread_id 215where pid = ${pid} and sp.thread_id != 0 `, 216 { $pid: pid } 217 ); 218 219export const queryHiPerfThreadData = (tid: number): Promise<Array<any>> => 220 query( 221 'queryHiPerfThreadData', 222 ` 223SELECT sp.callchain_id, 224 th.thread_name, 225 th.thread_id tid, 226 th.process_id pid, 227 sp.timestamp_trace - tr.start_ts startNS, 228 event_count, 229 event_type_id 230from perf_sample sp, 231 trace_range tr 232 left join perf_thread th on th.thread_id = sp.thread_id 233where tid = ${tid} and sp.thread_id != 0 ;`, 234 { $tid: tid } 235 ); 236export const queryHiSysEventTabData = (leftNs: number, rightNs: number): Promise<Array<HiSysEventStruct>> => 237 query( 238 'queryHiSysEventTabData', 239 `SELECT S.id, 240 D2.data AS domain, 241 D.data AS eventName, 242 type AS eventType, 243 time_zone AS tz, 244 pid, 245 tid, 246 uid, 247 info, 248 level, 249 seq, 250 contents, 251 S.ts - TR.start_ts AS startTs, 252 1 AS dur, 253 CASE 254 WHEN level = 'MINOR' THEN 255 0 256 WHEN level = 'CRITICAL' THEN 257 1 258 END AS depth 259 FROM hisys_all_event AS S ,trace_range AS TR 260 LEFT JOIN data_dict AS D on S.event_name_id = D.id 261 LEFT JOIN data_dict AS D2 on S.domain_id = D2.id 262 WHERE S.id is not null 263 and startTs >= ${Math.floor(leftNs)} 264 and startTs <= ${Math.floor(rightNs)} 265 ORDER BY S.ts` 266 ); 267export const queryHiSysEventData = (): Promise<Array<HiSysEventStruct>> => 268 query( 269 'queryHiSysEventData', 270 `SELECT l.ts - tr.start_ts as startNs FROM hisys_all_event AS l, trace_range tr WHERE startNs > 0 LIMIT 1` 271 ); 272export const queryHiPerfProcessCount = ( 273 leftNs: number, 274 rightNs: number, 275 cpus: Array<number>, 276 threads: Array<number>, 277 processes: Array<number> 278): Promise<Array<any>> => { 279 let str = ''; 280 if (processes.length > 0) { 281 str = ` and C.process_id in (${processes.join(',')})`; 282 } 283 if (threads.length > 0) { 284 str = ` and A.thread_id in (${threads.join(',')}) `; 285 } 286 if (processes.length > 0 && threads.length > 0) { 287 str = ` and (C.process_id in (${processes.join(',')}) or A.thread_id in (${threads.join(',')}))`; 288 } 289 if (cpus.length > 0) { 290 str = ` and A.cpu_id in (${cpus.join(',')})`; 291 } 292 if (cpus.length > 0 && processes.length > 0) { 293 str = ` and (C.process_id in (${processes.join(',')}) or A.cpu_id in (${cpus.join(',')}))`; 294 } 295 return query( 296 'queryHiPerfProcessCount', 297 ` 298 select C.process_id as pid, 299 (A.timestamp_trace - R.start_ts) as time, 300 C.thread_name as threadName, 301 A.thread_id as tid, 302 A.id, 303 A.callchain_id 304 from perf_sample A,trace_range R 305 left join perf_thread C on A.thread_id = C.thread_id and A.thread_id != 0 306 where time >= $leftNs and time <= $rightNs and A.callchain_id > 0 307 ${str} 308 `, 309 { $leftNs: leftNs, $rightNs: rightNs } 310 ); 311}; 312export const queryTransferList = (): Promise<Array<{ id: number; cmdStr: string }>> => 313 query('queryTransferList', `select id, report_value as cmdStr from perf_report where report_type = 'config_name'`); 314export const queryConcurrencyTask = ( 315 itid: number, 316 selectStartTime: number, 317 selectEndTime: number 318): Promise<TaskTabStruct[]> => 319 query<TaskTabStruct>( 320 'queryConcurrencyTask', 321 `SELECT thread.tid, 322 thread.ipid, 323 callstack.name AS funName, 324 callstack.ts AS startTs, 325 (case when callstack.dur = -1 then (SELECT end_ts FROM trace_range) else callstack.dur end) as dur, 326 callstack.id, 327 task_pool.priority, 328 task_pool.allocation_task_row AS allocationTaskRow, 329 task_pool.execute_task_row AS executeTaskRow, 330 task_pool.return_task_row AS returnTaskRow, 331 task_pool.execute_id AS executeId 332 FROM thread 333 LEFT JOIN callstack ON thread.id = callstack.callid 334 LEFT JOIN task_pool ON callstack.id = task_pool.execute_task_row 335 WHERE ipid in (SELECT thread.ipid 336 FROM thread 337 WHERE thread.itid = $itid) 338 AND thread.name = 'TaskWorkThread' 339 AND callstack.name LIKE 'H:Task Perform:%' 340 AND -- 左包含 341 (($selectStartTime <= callstack.ts AND $selectEndTime > callstack.ts) 342 OR -- 右包含 343 ($selectStartTime < callstack.ts + callstack.dur AND $selectEndTime >= callstack.ts + callstack.dur) 344 OR -- 包含 345 ($selectStartTime >= callstack.ts AND $selectEndTime <= callstack.ts + 346 (case when callstack.dur = -1 then (SELECT end_ts FROM trace_range) else callstack.dur end)) 347 OR -- 被包含 348 ($selectStartTime <= callstack.ts AND $selectEndTime >= callstack.ts + callstack.dur)) 349 ORDER BY callstack.ts;`, 350 { $itid: itid, $selectStartTime: selectStartTime, $selectEndTime: selectEndTime } 351 ); 352