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