1a4e91f50Sopenharmony_ci#!/usr/bin/env python 2a4e91f50Sopenharmony_ci# -*- coding: utf-8 -*- 3a4e91f50Sopenharmony_ci# Copyright (C) 2021 Huawei Device Co., Ltd. 4a4e91f50Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 5a4e91f50Sopenharmony_ci# you may not use this file except in compliance with the License. 6a4e91f50Sopenharmony_ci# You may obtain a copy of the License at 7a4e91f50Sopenharmony_ci# 8a4e91f50Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 9a4e91f50Sopenharmony_ci# 10a4e91f50Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 11a4e91f50Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 12a4e91f50Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4e91f50Sopenharmony_ci# See the License for the specific language governing permissions and 14a4e91f50Sopenharmony_ci# limitations under the License. 15a4e91f50Sopenharmony_ci 16a4e91f50Sopenharmony_ciimport codecs 17a4e91f50Sopenharmony_ciimport sys 18a4e91f50Sopenharmony_ciimport os 19a4e91f50Sopenharmony_ciimport re 20a4e91f50Sopenharmony_ciimport time 21a4e91f50Sopenharmony_ci 22a4e91f50Sopenharmony_cifiles = [] 23a4e91f50Sopenharmony_citrace_regex = "\s*(.*?)-(\d+?)\s+\(\s*(\d+?)\)\s+\[\d+\]\s+(.*?)\s+(.*?):\s+" 24a4e91f50Sopenharmony_ciall_traces_dict = {} # {"deviceName": [(timestamp, line) ...]} 25a4e91f50Sopenharmony_ciall_real_time_dict = {} 26a4e91f50Sopenharmony_cidefault_real_time = 7983849599000 # 2222-12-31 23:59:59 27a4e91f50Sopenharmony_ci 28a4e91f50Sopenharmony_cidef compare_timestamp(time1, time2): 29a4e91f50Sopenharmony_ci return float(time1) < float(time2) 30a4e91f50Sopenharmony_ci 31a4e91f50Sopenharmony_cidef read_files(file, devices_name): 32a4e91f50Sopenharmony_ci traces = [] 33a4e91f50Sopenharmony_ci with codecs.open(file, 'r', encoding='utf-8') as fp: 34a4e91f50Sopenharmony_ci for line in fp: 35a4e91f50Sopenharmony_ci if line.find("binder_transaction") > -1 \ 36a4e91f50Sopenharmony_ci or line.find("tracing_mark_write") > -1: 37a4e91f50Sopenharmony_ci line = line.replace("\n", "") 38a4e91f50Sopenharmony_ci trace_match = re.match(trace_regex, line) 39a4e91f50Sopenharmony_ci if trace_match: 40a4e91f50Sopenharmony_ci traces.append((float(trace_match.group(5)), line)) 41a4e91f50Sopenharmony_ci if line.find("realtime_ts") > -1: 42a4e91f50Sopenharmony_ci time_regex = "{}{}".format(trace_regex, \ 43a4e91f50Sopenharmony_ci "tracing_mark_write:\s+trace_event_clock_sync: realtime_ts=(.*)") 44a4e91f50Sopenharmony_ci time_match = re.match(time_regex, line) 45a4e91f50Sopenharmony_ci all_real_time_dict[devices_name] = { \ 46a4e91f50Sopenharmony_ci "realtime_ts": int(time_match.group(6)), \ 47a4e91f50Sopenharmony_ci "timestamp": float(time_match.group(5))} 48a4e91f50Sopenharmony_ci if (not all_real_time_dict.__contains__(devices_name)) and traces: 49a4e91f50Sopenharmony_ci line = traces[-1][1] 50a4e91f50Sopenharmony_ci trace_match = re.match(trace_regex, line) 51a4e91f50Sopenharmony_ci all_real_time_dict[devices_name] = { \ 52a4e91f50Sopenharmony_ci "realtime_ts": default_real_time, \ 53a4e91f50Sopenharmony_ci "timestamp": float(trace_match.group(5))} 54a4e91f50Sopenharmony_ci return traces 55a4e91f50Sopenharmony_ci 56a4e91f50Sopenharmony_cidef handle_option(): 57a4e91f50Sopenharmony_ci if len(sys.argv) < 2: 58a4e91f50Sopenharmony_ci print("eg: python bytrace_multi.py file1.ftrace file2.ftrace ...") 59a4e91f50Sopenharmony_ci exit(0) 60a4e91f50Sopenharmony_ci for i in range(len(sys.argv)): 61a4e91f50Sopenharmony_ci if i == 0: 62a4e91f50Sopenharmony_ci continue 63a4e91f50Sopenharmony_ci if sys.argv[i] == "-h" or sys.argv[i] == "--help": 64a4e91f50Sopenharmony_ci print("eg: python bytrace_multi.py file1.ftrace file2.ftrace ...") 65a4e91f50Sopenharmony_ci exit(0) 66a4e91f50Sopenharmony_ci elif not os.path.exists(sys.argv[i]): 67a4e91f50Sopenharmony_ci print("Warning: {} is not found.".format(sys.argv[i])) 68a4e91f50Sopenharmony_ci else: 69a4e91f50Sopenharmony_ci files.append(sys.argv[i]) 70a4e91f50Sopenharmony_ci 71a4e91f50Sopenharmony_cidef change_trace_time(all_trace_list, \ 72a4e91f50Sopenharmony_ci base_real_time, \ 73a4e91f50Sopenharmony_ci base_time_stamp, \ 74a4e91f50Sopenharmony_ci target_device): 75a4e91f50Sopenharmony_ci target_real_time = all_real_time_dict[target_device]["realtime_ts"] 76a4e91f50Sopenharmony_ci target_time_stamp = all_real_time_dict[target_device]["timestamp"] 77a4e91f50Sopenharmony_ci if not target_real_time == default_real_time: 78a4e91f50Sopenharmony_ci diff_real_time = float(target_real_time - base_real_time) / 1000 79a4e91f50Sopenharmony_ci target_time_stamp_ = base_time_stamp + diff_real_time 80a4e91f50Sopenharmony_ci diff_time = target_time_stamp - target_time_stamp_ 81a4e91f50Sopenharmony_ci else: 82a4e91f50Sopenharmony_ci # If the file does not have realtime, the difference is 0.5s. 83a4e91f50Sopenharmony_ci diff_real_time = 0.5 84a4e91f50Sopenharmony_ci target_time_stamp_ = base_time_stamp + diff_real_time 85a4e91f50Sopenharmony_ci diff_time = target_time_stamp - target_time_stamp_ 86a4e91f50Sopenharmony_ci traces = all_traces_dict[target_device] 87a4e91f50Sopenharmony_ci for mtuple in traces: 88a4e91f50Sopenharmony_ci timestamp = float(mtuple[0]) 89a4e91f50Sopenharmony_ci line = mtuple[1] 90a4e91f50Sopenharmony_ci timestamp_ = "{:.6f}".format(timestamp - diff_time) 91a4e91f50Sopenharmony_ci line_ = target_device + \ 92a4e91f50Sopenharmony_ci line.replace("{:.6f}".format(timestamp), str(timestamp_)) 93a4e91f50Sopenharmony_ci all_trace_list.append((timestamp_, line_)) 94a4e91f50Sopenharmony_ci 95a4e91f50Sopenharmony_cidef write_to_file(data, file_name): 96a4e91f50Sopenharmony_ci with codecs.open(file_name, 'w+', encoding='utf-8') as fp: 97a4e91f50Sopenharmony_ci fp.write("# tracer: nop\n") 98a4e91f50Sopenharmony_ci fp.write("#\n") 99a4e91f50Sopenharmony_ci fp.write("# _-----=> irqs-off\n") 100a4e91f50Sopenharmony_ci fp.write("# / _----=> need-resched\n") 101a4e91f50Sopenharmony_ci fp.write("# | / _---=> hardirq/softirq\n") 102a4e91f50Sopenharmony_ci fp.write("# || / _--=> preempt-depth\n") 103a4e91f50Sopenharmony_ci fp.write("# ||| / delay\n") 104a4e91f50Sopenharmony_ci fp.write("# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION\n") 105a4e91f50Sopenharmony_ci fp.write("# | | | | |||| | |\n") 106a4e91f50Sopenharmony_ci for mtuple in data: 107a4e91f50Sopenharmony_ci fp.write(mtuple[1]) 108a4e91f50Sopenharmony_ci fp.write("\n") 109a4e91f50Sopenharmony_ci 110a4e91f50Sopenharmony_cidef main(): 111a4e91f50Sopenharmony_ci handle_option() 112a4e91f50Sopenharmony_ci if len(files) == 0: 113a4e91f50Sopenharmony_ci exit(-1) 114a4e91f50Sopenharmony_ci 115a4e91f50Sopenharmony_ci for i, val in enumerate(files): 116a4e91f50Sopenharmony_ci device_name = "[device_{}]".format(str(i)) 117a4e91f50Sopenharmony_ci all_traces_dict[device_name] = read_files(val, device_name) 118a4e91f50Sopenharmony_ci 119a4e91f50Sopenharmony_ci all_time_sorted_list = sorted(all_real_time_dict.items(), key=lambda \ 120a4e91f50Sopenharmony_ci all_real_time_dict: all_real_time_dict[1]["realtime_ts"]) 121a4e91f50Sopenharmony_ci base_real_time = all_time_sorted_list[0][1]["realtime_ts"] 122a4e91f50Sopenharmony_ci base_time_stamp = all_time_sorted_list[0][1]["timestamp"] 123a4e91f50Sopenharmony_ci all_trace_list = [] # [(timestamp, line)] 124a4e91f50Sopenharmony_ci for mtuple in all_time_sorted_list: 125a4e91f50Sopenharmony_ci target_device = mtuple[0] 126a4e91f50Sopenharmony_ci change_trace_time(all_trace_list, \ 127a4e91f50Sopenharmony_ci base_real_time, \ 128a4e91f50Sopenharmony_ci base_time_stamp, \ 129a4e91f50Sopenharmony_ci target_device) 130a4e91f50Sopenharmony_ci # Sort by timestamp from small to large 131a4e91f50Sopenharmony_ci all_trace_sorted_list = sorted(all_trace_list, key=lambda x: x[0]) 132a4e91f50Sopenharmony_ci curtime = time.strftime("%Y%m%d_%H%M%S", time.localtime()) 133a4e91f50Sopenharmony_ci write_to_file(all_trace_sorted_list, "multi_trace_{}.ftrace".format(str(curtime))) 134a4e91f50Sopenharmony_ci 135a4e91f50Sopenharmony_ciif __name__ == '__main__': 136a4e91f50Sopenharmony_ci main() 137