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