1#!/usr/bin/env python3 2# 3# Copyright (C) 2023 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import gzip 18import json 19import os 20import sys 21 22from collections import defaultdict 23 24READ_DURATION = [ 25 'soong', 26 'kati build', 27 'ninja', 28 'total', 29] 30 31class Trace: 32 def __init__(self, trace_file): 33 self.duration = dict() 34 self._queue = defaultdict(list) 35 self.target = os.path.splitext(os.path.basename(trace_file))[0] 36 if not os.path.isfile(trace_file): 37 return 38 self._trace_file = gzip.open(trace_file, 'rt', encoding='utf-8') 39 self._trace_data = json.load(self._trace_file) 40 for t in self._trace_data: 41 if 'ph' not in t: 42 continue 43 if t['ph'] == 'X': 44 self.duration[t['name']] = t['dur'] 45 continue 46 if t['ph'] == 'B': 47 self._queue[(t['pid'], t['pid'])].append((t['name'], t['ts'])) 48 continue 49 if t['ph'] == 'E': 50 queue = self._queue[(t['pid'], t['pid'])] 51 if not queue: 52 raise Exception('pid:{}, tid:{} not started'.format(t['pid'], t['pid'])) 53 name, ts = queue.pop() 54 self.duration[name] = t['ts'] - ts 55 continue 56 57 def out_durations(self): 58 out_str = self.target 59 for name in READ_DURATION: 60 if name not in self.duration: 61 continue 62 out_str = '{}, {}'.format(out_str, self.duration[name]) 63 out_str += '\n' 64 sys.stdout.write(out_str) 65 66 67def main(argv): 68 trace = Trace(argv[1]) 69 trace.out_durations() 70 71if __name__ == '__main__': 72 main(sys.argv) 73