1484543d1Sopenharmony_ci#!/usr/bin/env python3 2484543d1Sopenharmony_ci# -*- coding: UTF-8 -*- 3484543d1Sopenharmony_ci 4484543d1Sopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 5484543d1Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 6484543d1Sopenharmony_ci# you may not use this file except in compliance with the License. 7484543d1Sopenharmony_ci# You may obtain a copy of the License at 8484543d1Sopenharmony_ci# 9484543d1Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 10484543d1Sopenharmony_ci# 11484543d1Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 12484543d1Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 13484543d1Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14484543d1Sopenharmony_ci# See the License for the specific language governing permissions and 15484543d1Sopenharmony_ci# limitations under the License. 16484543d1Sopenharmony_ci 17484543d1Sopenharmony_ciimport os 18484543d1Sopenharmony_ciimport re 19484543d1Sopenharmony_ciimport argparse 20484543d1Sopenharmony_ciimport stat 21484543d1Sopenharmony_ciimport copy 22484543d1Sopenharmony_cifrom ffrt_trace_process import extract_process_id 23484543d1Sopenharmony_ci 24484543d1Sopenharmony_ci 25484543d1Sopenharmony_cidef extract_timestamp_str(log): 26484543d1Sopenharmony_ci """ 27484543d1Sopenharmony_ci extract timestamp(us) from trace line 28484543d1Sopenharmony_ci """ 29484543d1Sopenharmony_ci m = re.search(r" (\d+)\.(\d+): ", log) 30484543d1Sopenharmony_ci if m is None: 31484543d1Sopenharmony_ci return 0 32484543d1Sopenharmony_ci 33484543d1Sopenharmony_ci match = m.group() 34484543d1Sopenharmony_ci 35484543d1Sopenharmony_ci return match.strip()[:-1] 36484543d1Sopenharmony_ci 37484543d1Sopenharmony_ci 38484543d1Sopenharmony_cidef extract_cpu_id_str(log): 39484543d1Sopenharmony_ci """ 40484543d1Sopenharmony_ci extract #cpu from trace line 41484543d1Sopenharmony_ci """ 42484543d1Sopenharmony_ci m = re.search(r"\) \[.*\]", log) 43484543d1Sopenharmony_ci if m is None: 44484543d1Sopenharmony_ci return -1 45484543d1Sopenharmony_ci 46484543d1Sopenharmony_ci match = m.group() 47484543d1Sopenharmony_ci 48484543d1Sopenharmony_ci return match.split(']')[0].split('[')[-1] 49484543d1Sopenharmony_ci 50484543d1Sopenharmony_ci 51484543d1Sopenharmony_cidef make_costart_fake_log(mark, pid, label, gid, tid, tname, prio): 52484543d1Sopenharmony_ci """ 53484543d1Sopenharmony_ci when ffrt task start running, make a fake log that sched_switch from ffrt thread -> ffrt task 54484543d1Sopenharmony_ci """ 55484543d1Sopenharmony_ci timestamp = extract_timestamp_str(mark) 56484543d1Sopenharmony_ci cpu_id = extract_cpu_id_str(mark) 57484543d1Sopenharmony_ci fake_log = mark + "\n %s-%d (%7d) [%s] .... %s: sched_switch: prev_comm=%s prev_pid=%d prev_prio=%d prev_state=S ==> next_comm=%s next_pid=%d0%d next_prio=%d\n" % ( 58484543d1Sopenharmony_ci tname, tid, pid, cpu_id, timestamp, tname, tid, prio, label, pid, gid, prio) 59484543d1Sopenharmony_ci 60484543d1Sopenharmony_ci return fake_log 61484543d1Sopenharmony_ci 62484543d1Sopenharmony_ci 63484543d1Sopenharmony_cidef make_coyield_fake_log(mark, pid, label, gid, tid, tname, prio): 64484543d1Sopenharmony_ci """ 65484543d1Sopenharmony_ci when ffrt task leave running, make a fake log that sched_switch from ffrt task -> ffrt thread 66484543d1Sopenharmony_ci """ 67484543d1Sopenharmony_ci timestamp = extract_timestamp_str(mark) 68484543d1Sopenharmony_ci cpu_id = extract_cpu_id_str(mark) 69484543d1Sopenharmony_ci fake_log = " %s-%d0%d (%7d) [%s] .... %s: sched_switch: prev_comm=%s prev_pid=%d0%d prev_prio=%d prev_state=S ==> next_comm=%s next_pid=%d next_prio=%d\n" % ( 70484543d1Sopenharmony_ci label, pid, gid, pid, cpu_id, timestamp, label, pid, gid, prio, tname, tid, prio) 71484543d1Sopenharmony_ci 72484543d1Sopenharmony_ci if "|B|" in mark or "|H:B " in mark: 73484543d1Sopenharmony_ci fake_log = " %s-%d0%d (%7d) [%s] .... %s: tracing_mark_write: E|%d\n" % \ 74484543d1Sopenharmony_ci (label, pid, gid, pid, cpu_id, timestamp, pid) + fake_log 75484543d1Sopenharmony_ci 76484543d1Sopenharmony_ci return fake_log 77484543d1Sopenharmony_ci 78484543d1Sopenharmony_ci 79484543d1Sopenharmony_cidef replace_sched_switch_log(fake_log, mark, pid, label, gid, tid): 80484543d1Sopenharmony_ci """ 81484543d1Sopenharmony_ci replace ffrt worker sched_swtich log with ffrt task 82484543d1Sopenharmony_ci """ 83484543d1Sopenharmony_ci if "prev_pid=%d" % tid in mark: 84484543d1Sopenharmony_ci index = re.search("\(.+\)\s+\[\d", fake_log).span()[0] 85484543d1Sopenharmony_ci fake_log = " %s-%d0%d " % (label, pid, gid) + fake_log[index:] 86484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("prev_comm=")] + "prev_comm=%s " % label + \ 87484543d1Sopenharmony_ci fake_log[fake_log.index("prev_pid="):] 88484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("prev_pid=")] + "prev_pid=%d0%d " % (pid, gid) + \ 89484543d1Sopenharmony_ci fake_log[fake_log.index("prev_prio="):] 90484543d1Sopenharmony_ci elif "next_pid=%d" % tid in mark: 91484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("next_comm=")] + "next_comm=%s " % label + \ 92484543d1Sopenharmony_ci fake_log[fake_log.index("next_pid="):] 93484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("next_pid=")] + "next_pid=%d0%d " % (pid, gid) + \ 94484543d1Sopenharmony_ci fake_log[fake_log.index("next_prio="):] 95484543d1Sopenharmony_ci 96484543d1Sopenharmony_ci return fake_log 97484543d1Sopenharmony_ci 98484543d1Sopenharmony_ci 99484543d1Sopenharmony_cidef replace_sched_wake_log(fake_log, label, pid, gid): 100484543d1Sopenharmony_ci """ 101484543d1Sopenharmony_ci replace ffrt worker sched_wake log with ffrt task 102484543d1Sopenharmony_ci """ 103484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("comm=")] + "comm=%s " % label + fake_log[fake_log.index("pid="):] 104484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("pid=")] + "pid=%d0%d " % (pid, gid) + fake_log[fake_log.index("prio="):] 105484543d1Sopenharmony_ci 106484543d1Sopenharmony_ci return fake_log 107484543d1Sopenharmony_ci 108484543d1Sopenharmony_ci 109484543d1Sopenharmony_cidef replace_sched_block_log(fake_log, pid, gid): 110484543d1Sopenharmony_ci """ 111484543d1Sopenharmony_ci replace ffrt worker sched_block log with ffrt task 112484543d1Sopenharmony_ci """ 113484543d1Sopenharmony_ci fake_log = fake_log[:fake_log.index("pid=")] + "pid=%d0%d " % (pid, gid) + fake_log[fake_log.index("iowait="):] 114484543d1Sopenharmony_ci 115484543d1Sopenharmony_ci return fake_log 116484543d1Sopenharmony_ci 117484543d1Sopenharmony_ci 118484543d1Sopenharmony_cidef replace_tracing_mark_log(fake_log, label, pid, gid): 119484543d1Sopenharmony_ci """ 120484543d1Sopenharmony_ci replace ffrt worker normal tracing log with ffrt task 121484543d1Sopenharmony_ci """ 122484543d1Sopenharmony_ci index = re.search("\(.+\)\s+\[\d", fake_log).span()[0] 123484543d1Sopenharmony_ci fake_log = " %s-%d0%d " % (label, pid, gid) + fake_log[index:] 124484543d1Sopenharmony_ci 125484543d1Sopenharmony_ci return fake_log 126484543d1Sopenharmony_ci 127484543d1Sopenharmony_ci 128484543d1Sopenharmony_cidef convert_worker_log_to_task(mark, pid, label, gid, tid): 129484543d1Sopenharmony_ci """ 130484543d1Sopenharmony_ci convert ffrt worker trace logs to ffrt task trace logs 131484543d1Sopenharmony_ci """ 132484543d1Sopenharmony_ci fake_log = mark 133484543d1Sopenharmony_ci 134484543d1Sopenharmony_ci if "sched_switch: " in mark: 135484543d1Sopenharmony_ci return replace_sched_switch_log(fake_log, mark, pid, label, gid, tid) 136484543d1Sopenharmony_ci 137484543d1Sopenharmony_ci if ": sched_wak" in mark: 138484543d1Sopenharmony_ci return replace_sched_wake_log(fake_log, label, pid, gid) 139484543d1Sopenharmony_ci 140484543d1Sopenharmony_ci if "sched_blocked_reason: " in mark: 141484543d1Sopenharmony_ci return replace_sched_block_log(fake_log, pid, gid) 142484543d1Sopenharmony_ci 143484543d1Sopenharmony_ci return replace_tracing_mark_log(fake_log, label, pid, gid) 144484543d1Sopenharmony_ci 145484543d1Sopenharmony_ci 146484543d1Sopenharmony_cidef find_ffrt_process_and_classify_logs(log, lineno, trace_map, ffrt_pids): 147484543d1Sopenharmony_ci """ 148484543d1Sopenharmony_ci find ffrt related process and threads (ffrtwk/ffrt_io), and classify logs for threads 149484543d1Sopenharmony_ci """ 150484543d1Sopenharmony_ci if "prev_comm=ffrt" in log: 151484543d1Sopenharmony_ci pid = extract_process_id(log) 152484543d1Sopenharmony_ci if pid not in ffrt_pids.keys(): 153484543d1Sopenharmony_ci ffrt_pids[pid] = {} 154484543d1Sopenharmony_ci tname = log[log.index("prev_comm="):].split("prev_pid=")[0].split('=')[-1].rstrip() 155484543d1Sopenharmony_ci tid = int(log[log.index("prev_pid="):].split(' ')[0].split('=')[-1]) 156484543d1Sopenharmony_ci if tid not in ffrt_pids[pid].keys(): 157484543d1Sopenharmony_ci ffrt_pids[pid][tid] = {"name": tname, "logs": []} 158484543d1Sopenharmony_ci 159484543d1Sopenharmony_ci if "sched_switch: " in log: 160484543d1Sopenharmony_ci prev_tid = int(log[log.index("prev_pid="):].split(' ')[0].split('=')[-1]) 161484543d1Sopenharmony_ci next_tid = int(log[log.index("next_pid="):].split(' ')[0].split('=')[-1]) 162484543d1Sopenharmony_ci if prev_tid not in trace_map.keys(): 163484543d1Sopenharmony_ci trace_map[prev_tid] = [] 164484543d1Sopenharmony_ci trace_map[prev_tid].append(lineno) 165484543d1Sopenharmony_ci if next_tid not in trace_map.keys(): 166484543d1Sopenharmony_ci trace_map[next_tid] = [] 167484543d1Sopenharmony_ci trace_map[next_tid].append(lineno) 168484543d1Sopenharmony_ci return 169484543d1Sopenharmony_ci 170484543d1Sopenharmony_ci if ": sched_wak" in log or "sched_blocked_reason: " in log: 171484543d1Sopenharmony_ci tid = int(log[log.index("pid="):].split(' ')[0].split('=')[-1]) 172484543d1Sopenharmony_ci if tid not in trace_map.keys(): 173484543d1Sopenharmony_ci trace_map[tid] = [] 174484543d1Sopenharmony_ci trace_map[tid].append(lineno) 175484543d1Sopenharmony_ci return 176484543d1Sopenharmony_ci 177484543d1Sopenharmony_ci match = re.search(" \(.+\)\s+\[\d", log) 178484543d1Sopenharmony_ci if match is not None: 179484543d1Sopenharmony_ci tid = int(log[:match.span()[0]].split('-')[-1]) 180484543d1Sopenharmony_ci if tid not in trace_map.keys(): 181484543d1Sopenharmony_ci trace_map[tid] = [] 182484543d1Sopenharmony_ci trace_map[tid].append(lineno) 183484543d1Sopenharmony_ci 184484543d1Sopenharmony_ci return 185484543d1Sopenharmony_ci 186484543d1Sopenharmony_ci 187484543d1Sopenharmony_cidef classify_logs_for_ffrt_worker(logs): 188484543d1Sopenharmony_ci """ 189484543d1Sopenharmony_ci split traces that written in the same line and classify logs based on ffrt worker 190484543d1Sopenharmony_ci """ 191484543d1Sopenharmony_ci trace_map = {} 192484543d1Sopenharmony_ci ffrt_pids = {} 193484543d1Sopenharmony_ci 194484543d1Sopenharmony_ci lineno = 0 195484543d1Sopenharmony_ci while lineno < len(logs): 196484543d1Sopenharmony_ci log = logs[lineno] 197484543d1Sopenharmony_ci 198484543d1Sopenharmony_ci indexs = [m.span()[0] for m in re.finditer("\S+-\d+\s+\(", log)] 199484543d1Sopenharmony_ci 200484543d1Sopenharmony_ci if len(indexs) > 1: 201484543d1Sopenharmony_ci del logs[lineno] 202484543d1Sopenharmony_ci for j in range(len(indexs)): 203484543d1Sopenharmony_ci begin = indexs[j] 204484543d1Sopenharmony_ci end = indexs[j + 1] if j + 1 < len(indexs) else len(log) 205484543d1Sopenharmony_ci log_split = log[begin:end] 206484543d1Sopenharmony_ci if j + 1 < len(indexs): 207484543d1Sopenharmony_ci log_split = "%s\n" % log_split 208484543d1Sopenharmony_ci logs.insert(lineno + j, log_split) 209484543d1Sopenharmony_ci 210484543d1Sopenharmony_ci find_ffrt_process_and_classify_logs(logs[lineno + j], lineno + j, trace_map, ffrt_pids) 211484543d1Sopenharmony_ci if "<faulted>" in logs[lineno + j]: 212484543d1Sopenharmony_ci pid = extract_process_id(logs[lineno + j]) 213484543d1Sopenharmony_ci logs[lineno + j] = logs[lineno + j][:logs[lineno + j].index("<faulted>")] + "E|%d\n" % pid 214484543d1Sopenharmony_ci 215484543d1Sopenharmony_ci lineno += len(indexs) - 1 216484543d1Sopenharmony_ci else: 217484543d1Sopenharmony_ci find_ffrt_process_and_classify_logs(logs[lineno], lineno, trace_map, ffrt_pids) 218484543d1Sopenharmony_ci if "<faulted>" in logs[lineno]: 219484543d1Sopenharmony_ci pid = extract_process_id(logs[lineno]) 220484543d1Sopenharmony_ci logs[lineno] = logs[lineno][:logs[lineno].index("<faulted>")] + "E|%d\n" % pid 221484543d1Sopenharmony_ci 222484543d1Sopenharmony_ci lineno += 1 223484543d1Sopenharmony_ci 224484543d1Sopenharmony_ci for pid, tids in ffrt_pids.items(): 225484543d1Sopenharmony_ci for tid in tids.keys(): 226484543d1Sopenharmony_ci ffrt_pids[pid][tid]["logs"] = trace_map[tid] 227484543d1Sopenharmony_ci 228484543d1Sopenharmony_ci return ffrt_pids 229484543d1Sopenharmony_ci 230484543d1Sopenharmony_ci 231484543d1Sopenharmony_cidef convert_ffrt_thread_to_ffrt_task(logs, ffrt_pids): 232484543d1Sopenharmony_ci """ 233484543d1Sopenharmony_ci convert tracing mark of ffrt worker to ffrt task 234484543d1Sopenharmony_ci """ 235484543d1Sopenharmony_ci task_labels = {} 236484543d1Sopenharmony_ci 237484543d1Sopenharmony_ci for pid, tids in ffrt_pids.items(): 238484543d1Sopenharmony_ci task_labels[pid] = {} 239484543d1Sopenharmony_ci for tid, info in ffrt_pids[pid].items(): 240484543d1Sopenharmony_ci tname = info["name"] 241484543d1Sopenharmony_ci linenos = info["logs"] 242484543d1Sopenharmony_ci prio = 120 243484543d1Sopenharmony_ci 244484543d1Sopenharmony_ci switch_in_fake_log = False 245484543d1Sopenharmony_ci switch_out_fake_log = False 246484543d1Sopenharmony_ci ffbk_mark_remove = False 247484543d1Sopenharmony_ci task_running = None 248484543d1Sopenharmony_ci for lineno in linenos: 249484543d1Sopenharmony_ci mark = logs[lineno] 250484543d1Sopenharmony_ci 251484543d1Sopenharmony_ci if "sched_switch: " in mark: 252484543d1Sopenharmony_ci if "prev_pid=%d" % tid in mark: 253484543d1Sopenharmony_ci prio = int(mark[mark.index("prev_prio="):].split(' ')[0].split('=')[-1]) 254484543d1Sopenharmony_ci elif "next_pid=%d" % tid in mark: 255484543d1Sopenharmony_ci prio = int(mark[mark.index("next_prio="):].split(' ')[0].split('=')[-1]) 256484543d1Sopenharmony_ci 257484543d1Sopenharmony_ci # FFRT Task Running 258484543d1Sopenharmony_ci if "FFRT::[" in mark: 259484543d1Sopenharmony_ci miss_log = None 260484543d1Sopenharmony_ci if task_running is not None: # trace end missing 261484543d1Sopenharmony_ci miss_log = make_coyield_fake_log(mark, pid, task_labels[pid][task_running], task_running, 262484543d1Sopenharmony_ci tid, tname, prio) 263484543d1Sopenharmony_ci timestamp = extract_timestamp_str(mark) 264484543d1Sopenharmony_ci cpu_id = extract_cpu_id_str(mark) 265484543d1Sopenharmony_ci miss_log += " %s-%d (%7d) [%s] .... %s: tracing_mark_write: E|%d\n" % ( 266484543d1Sopenharmony_ci tname, tid, pid, cpu_id, timestamp, pid) 267484543d1Sopenharmony_ci 268484543d1Sopenharmony_ci label = mark.split('[')[-1].split(']')[0] 269484543d1Sopenharmony_ci try: 270484543d1Sopenharmony_ci gid = int(mark.split('|')[-1]) 271484543d1Sopenharmony_ci except ValueError: 272484543d1Sopenharmony_ci continue 273484543d1Sopenharmony_ci if gid not in task_labels[pid].keys(): 274484543d1Sopenharmony_ci task_labels[pid][gid] = label 275484543d1Sopenharmony_ci 276484543d1Sopenharmony_ci task_running = gid 277484543d1Sopenharmony_ci fake_log = make_costart_fake_log(mark, pid, task_labels[pid][task_running], task_running, 278484543d1Sopenharmony_ci tid, tname, prio) 279484543d1Sopenharmony_ci logs[lineno] = fake_log 280484543d1Sopenharmony_ci 281484543d1Sopenharmony_ci if miss_log is not None: 282484543d1Sopenharmony_ci logs[lineno] = miss_log + logs[lineno] 283484543d1Sopenharmony_ci 284484543d1Sopenharmony_ci switch_in_fake_log = True 285484543d1Sopenharmony_ci continue 286484543d1Sopenharmony_ci 287484543d1Sopenharmony_ci if task_running is not None: 288484543d1Sopenharmony_ci # Remove FFRT Supplemented Log for CoSwitch 289484543d1Sopenharmony_ci if re.search(r" F\|(\d+)\|Co\|(\d+)", mark) is not None or \ 290484543d1Sopenharmony_ci re.search(r" F\|(\d+)\|H:Co\s(\d+)", mark) is not None: 291484543d1Sopenharmony_ci logs[lineno] = "\n" 292484543d1Sopenharmony_ci if switch_in_fake_log is True: 293484543d1Sopenharmony_ci switch_in_fake_log = False 294484543d1Sopenharmony_ci continue 295484543d1Sopenharmony_ci else: 296484543d1Sopenharmony_ci switch_out_fake_log = True 297484543d1Sopenharmony_ci continue 298484543d1Sopenharmony_ci if switch_in_fake_log is True and "tracing_mark_write: B" in mark: 299484543d1Sopenharmony_ci logs[lineno] = "\n" 300484543d1Sopenharmony_ci continue 301484543d1Sopenharmony_ci if switch_out_fake_log is True and "tracing_mark_write: E" in mark: 302484543d1Sopenharmony_ci logs[lineno] = "\n" 303484543d1Sopenharmony_ci continue 304484543d1Sopenharmony_ci 305484543d1Sopenharmony_ci # FFRT Task Blocked/Finished Marks 306484543d1Sopenharmony_ci if re.search(r" F\|(\d+)\|[BF]\|(\d+)", mark) is not None or \ 307484543d1Sopenharmony_ci re.search(r" F\|(\d+)\|H:[BF]\s(\d+)", mark) is not None: 308484543d1Sopenharmony_ci fake_log = make_coyield_fake_log(mark, pid, task_labels[pid][task_running], task_running, 309484543d1Sopenharmony_ci tid, tname, prio) 310484543d1Sopenharmony_ci logs[lineno] = fake_log 311484543d1Sopenharmony_ci task_running = None 312484543d1Sopenharmony_ci 313484543d1Sopenharmony_ci if switch_out_fake_log is True: 314484543d1Sopenharmony_ci switch_out_fake_log = False 315484543d1Sopenharmony_ci 316484543d1Sopenharmony_ci continue 317484543d1Sopenharmony_ci 318484543d1Sopenharmony_ci if ffbk_mark_remove is True and "tracing_mark_write: E" in mark: 319484543d1Sopenharmony_ci logs[lineno] = "\n" 320484543d1Sopenharmony_ci ffbk_mark_remove = False 321484543d1Sopenharmony_ci continue 322484543d1Sopenharmony_ci 323484543d1Sopenharmony_ci fake_log = convert_worker_log_to_task(mark, pid, task_labels[pid][task_running], task_running, 324484543d1Sopenharmony_ci tid) 325484543d1Sopenharmony_ci 326484543d1Sopenharmony_ci # FFRT Blocked Reason 327484543d1Sopenharmony_ci if "FFBK[" in fake_log: 328484543d1Sopenharmony_ci if "[dep]" in fake_log: 329484543d1Sopenharmony_ci fake_log = "\n" 330484543d1Sopenharmony_ci elif "[chd]" in fake_log: 331484543d1Sopenharmony_ci fake_log = "%sFFBK[wait_child]%s" % ( 332484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 333484543d1Sopenharmony_ci elif "[dat]" in fake_log: 334484543d1Sopenharmony_ci fake_log = "%sFFBK[wait_data]%s" % ( 335484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 336484543d1Sopenharmony_ci elif "[fd]" in fake_log: 337484543d1Sopenharmony_ci fake_log = "%sFFBK[wait_fd]%s" % ( 338484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 8:]) 339484543d1Sopenharmony_ci elif "[mtx]" in fake_log: 340484543d1Sopenharmony_ci fake_log = "%sFFBK[mutex]%s" % ( 341484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 342484543d1Sopenharmony_ci elif "[slp]" in fake_log: 343484543d1Sopenharmony_ci fake_log = "%sFFBK[sleep]%s" % ( 344484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 345484543d1Sopenharmony_ci elif "[yld]" in fake_log: 346484543d1Sopenharmony_ci fake_log = "%sFFBK[yield]%s" % ( 347484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 348484543d1Sopenharmony_ci elif "[cnd]" in fake_log: 349484543d1Sopenharmony_ci fake_log = "%sFFBK[cond_wait]%s" % ( 350484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 351484543d1Sopenharmony_ci elif "[cnt]" in fake_log: 352484543d1Sopenharmony_ci fake_log = "%sFFBK[cond_timedwait]%s" % ( 353484543d1Sopenharmony_ci fake_log[:fake_log.index("FFBK[")], fake_log[fake_log.index("FFBK[") + 9:]) 354484543d1Sopenharmony_ci 355484543d1Sopenharmony_ci ffbk_mark_remove = True 356484543d1Sopenharmony_ci 357484543d1Sopenharmony_ci logs[lineno] = fake_log 358484543d1Sopenharmony_ci continue 359484543d1Sopenharmony_ci 360484543d1Sopenharmony_ci return 361484543d1Sopenharmony_ci 362484543d1Sopenharmony_ci 363484543d1Sopenharmony_cidef supplement_ffrt_block_and_wake_info(logs): 364484543d1Sopenharmony_ci """ 365484543d1Sopenharmony_ci supplement ffrt block slice and link ffrt wake with ffrt block 366484543d1Sopenharmony_ci """ 367484543d1Sopenharmony_ci task_labels = {} 368484543d1Sopenharmony_ci 369484543d1Sopenharmony_ci for lineno in range(len(logs)): 370484543d1Sopenharmony_ci log = logs[lineno] 371484543d1Sopenharmony_ci 372484543d1Sopenharmony_ci if "FFBK[" in log: 373484543d1Sopenharmony_ci pid = extract_process_id(log) 374484543d1Sopenharmony_ci gid = int(log.split('|')[-1]) 375484543d1Sopenharmony_ci 376484543d1Sopenharmony_ci if pid not in task_labels.keys(): 377484543d1Sopenharmony_ci task_labels[pid] = {} 378484543d1Sopenharmony_ci if gid not in task_labels[pid].keys(): 379484543d1Sopenharmony_ci task_labels[pid][gid] = { 380484543d1Sopenharmony_ci "state": "none", 381484543d1Sopenharmony_ci "prev_wake_lineno": None, 382484543d1Sopenharmony_ci "prev_wake_log": None, 383484543d1Sopenharmony_ci } 384484543d1Sopenharmony_ci 385484543d1Sopenharmony_ci ready_end_log = None 386484543d1Sopenharmony_ci if task_labels[pid][gid]["state"] == "ready": # abnormal scene: ready -> block, running missed 387484543d1Sopenharmony_ci timestamp = extract_timestamp_str(log) 388484543d1Sopenharmony_ci cpu_id = extract_cpu_id_str(log) 389484543d1Sopenharmony_ci ready_end_log = " <...>-%d0%d (%7d) [%s] .... %s: tracing_mark_write: E|%d\n" % ( 390484543d1Sopenharmony_ci pid, gid, pid, cpu_id, timestamp, pid) 391484543d1Sopenharmony_ci 392484543d1Sopenharmony_ci task_labels[pid][gid]["state"] = "block" 393484543d1Sopenharmony_ci 394484543d1Sopenharmony_ci logs[lineno] = "%s\n" % logs[lineno][:logs[lineno].rfind('|')] 395484543d1Sopenharmony_ci 396484543d1Sopenharmony_ci if ready_end_log is not None: 397484543d1Sopenharmony_ci logs[lineno] = ready_end_log + logs[lineno] 398484543d1Sopenharmony_ci 399484543d1Sopenharmony_ci continue 400484543d1Sopenharmony_ci 401484543d1Sopenharmony_ci if "FFWK|" in log: 402484543d1Sopenharmony_ci pid = extract_process_id(log) 403484543d1Sopenharmony_ci gid = int(log.split('|')[-1]) 404484543d1Sopenharmony_ci 405484543d1Sopenharmony_ci if pid in task_labels.keys() and gid in task_labels[pid].keys(): 406484543d1Sopenharmony_ci timestamp = extract_timestamp_str(log) 407484543d1Sopenharmony_ci cpu_id = extract_cpu_id_str(log) 408484543d1Sopenharmony_ci if "H:FFWK" in log: 409484543d1Sopenharmony_ci ready_begin_log = " <...>-%d0%d (%7d) [%s] .... %s: tracing_mark_write: B|%d|H:FFREADY\n" % ( 410484543d1Sopenharmony_ci pid, gid, pid, cpu_id, timestamp, pid) 411484543d1Sopenharmony_ci else: 412484543d1Sopenharmony_ci ready_begin_log = " <...>-%d0%d (%7d) [%s] .... %s: tracing_mark_write: B|%d|FFREADY\n" % ( 413484543d1Sopenharmony_ci pid, gid, pid, cpu_id, timestamp, pid) 414484543d1Sopenharmony_ci logs[lineno] = ready_begin_log + logs[lineno] 415484543d1Sopenharmony_ci 416484543d1Sopenharmony_ci if task_labels[pid][gid]["state"] == "ready": # abnormal scene: ready -> ready, running & block missed 417484543d1Sopenharmony_ci logs[task_labels[pid][gid]["prev_wake_lineno"]] = logs[task_labels[pid][gid]["prev_wake_lineno"]][ 418484543d1Sopenharmony_ci logs[task_labels[pid][gid][ 419484543d1Sopenharmony_ci "prev_wake_lineno"]].index("FFREADY") + 8:] 420484543d1Sopenharmony_ci 421484543d1Sopenharmony_ci task_labels[pid][gid]["state"] = "ready" 422484543d1Sopenharmony_ci task_labels[pid][gid]["prev_wake_log"] = copy.copy(log) 423484543d1Sopenharmony_ci task_labels[pid][gid]["prev_wake_lineno"] = lineno 424484543d1Sopenharmony_ci 425484543d1Sopenharmony_ci continue 426484543d1Sopenharmony_ci 427484543d1Sopenharmony_ci if "FFRT::[" in log: 428484543d1Sopenharmony_ci pid = extract_process_id(log) 429484543d1Sopenharmony_ci try: 430484543d1Sopenharmony_ci gid = int([e for e in log.split('\n') if "FFRT::[" in e][0].split('|')[-1]) 431484543d1Sopenharmony_ci except ValueError: 432484543d1Sopenharmony_ci continue 433484543d1Sopenharmony_ci 434484543d1Sopenharmony_ci if pid in task_labels.keys() and gid in task_labels[pid].keys(): 435484543d1Sopenharmony_ci if task_labels[pid][gid]["state"] == "ready": 436484543d1Sopenharmony_ci timestamp = extract_timestamp_str(log) 437484543d1Sopenharmony_ci cpu_id = extract_cpu_id_str(log) 438484543d1Sopenharmony_ci 439484543d1Sopenharmony_ci switch_log = log.split('\n')[-2] 440484543d1Sopenharmony_ci task_comm = switch_log[switch_log.index("next_comm="):].split("next_pid=")[0].split('=')[ 441484543d1Sopenharmony_ci -1].rstrip() 442484543d1Sopenharmony_ci task_pid = int(switch_log[switch_log.index("next_pid="):].split(' ')[0].split('=')[-1]) 443484543d1Sopenharmony_ci task_prio = int(switch_log[switch_log.index("next_prio="):].split('=')[-1]) 444484543d1Sopenharmony_ci cpu_id_wake = extract_cpu_id_str(switch_log) 445484543d1Sopenharmony_ci waking_log = task_labels[pid][gid]["prev_wake_log"][:task_labels[pid][gid]["prev_wake_log"].index( 446484543d1Sopenharmony_ci "tracing_mark_write:")] + "sched_waking: comm=%s pid=%d prio=%d target_cpu=%s\n" % ( 447484543d1Sopenharmony_ci task_comm, task_pid, task_prio, cpu_id_wake) 448484543d1Sopenharmony_ci wakeup_log = task_labels[pid][gid]["prev_wake_log"][ 449484543d1Sopenharmony_ci :task_labels[pid][gid]["prev_wake_log"].index("tracing_mark_write:")] + \ 450484543d1Sopenharmony_ci "sched_wakeup: comm=%s pid=%d prio=%d target_cpu=%s\n" % ( 451484543d1Sopenharmony_ci task_comm, task_pid, task_prio, cpu_id_wake) 452484543d1Sopenharmony_ci logs[task_labels[pid][gid]["prev_wake_lineno"]] += waking_log + wakeup_log 453484543d1Sopenharmony_ci 454484543d1Sopenharmony_ci ready_end_log = " <...>-%d0%d (%7d) [%s] .... %s: tracing_mark_write: E|%d\n" % ( 455484543d1Sopenharmony_ci pid, gid, pid, cpu_id, timestamp, pid) 456484543d1Sopenharmony_ci logs[lineno] = ready_end_log + logs[lineno] 457484543d1Sopenharmony_ci 458484543d1Sopenharmony_ci task_labels[pid][gid]["state"] = "none" 459484543d1Sopenharmony_ci 460484543d1Sopenharmony_ci continue 461484543d1Sopenharmony_ci 462484543d1Sopenharmony_ci return 463484543d1Sopenharmony_ci 464484543d1Sopenharmony_ci 465484543d1Sopenharmony_cidef trace_recover(file): 466484543d1Sopenharmony_ci with open(file, 'r', encoding="gb18030", errors="ignore") as infile: 467484543d1Sopenharmony_ci logs = infile.readlines() 468484543d1Sopenharmony_ci 469484543d1Sopenharmony_ci ffrt_pids = classify_logs_for_ffrt_worker(logs) 470484543d1Sopenharmony_ci 471484543d1Sopenharmony_ci convert_ffrt_thread_to_ffrt_task(logs, ffrt_pids) 472484543d1Sopenharmony_ci 473484543d1Sopenharmony_ci supplement_ffrt_block_and_wake_info(logs) 474484543d1Sopenharmony_ci 475484543d1Sopenharmony_ci file_name, file_ext = os.path.splitext(file)[0], os.path.splitext(file)[1] 476484543d1Sopenharmony_ci 477484543d1Sopenharmony_ci with os.fdopen(os.open("%s_ffrt_recover%s" % (file_name, file_ext), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 478484543d1Sopenharmony_ci stat.S_IWUSR | stat.S_IRUSR), 'w', encoding="gb18030", errors="ignore") as outfile: 479484543d1Sopenharmony_ci outfile.writelines(logs) 480484543d1Sopenharmony_ci outfile.close() 481484543d1Sopenharmony_ci 482484543d1Sopenharmony_ci infile.close() 483484543d1Sopenharmony_ci 484484543d1Sopenharmony_ci return 485484543d1Sopenharmony_ci 486484543d1Sopenharmony_ci 487484543d1Sopenharmony_cidef main(): 488484543d1Sopenharmony_ci parser = argparse.ArgumentParser(description="parse") 489484543d1Sopenharmony_ci parser.add_argument('--file', '-f', type=str, required=True, help="input trace file path") 490484543d1Sopenharmony_ci 491484543d1Sopenharmony_ci args = parser.parse_args() 492484543d1Sopenharmony_ci 493484543d1Sopenharmony_ci if not os.path.isfile(args.file): 494484543d1Sopenharmony_ci exit(1) 495484543d1Sopenharmony_ci 496484543d1Sopenharmony_ci trace_recover(args.file) 497484543d1Sopenharmony_ci 498484543d1Sopenharmony_ci return 499484543d1Sopenharmony_ci 500484543d1Sopenharmony_ci 501484543d1Sopenharmony_ciif __name__ == "__main__": 502484543d1Sopenharmony_ci main()