1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 2a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 3a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch# found in the LICENSE file. 4a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)import telemetry.timeline.event as timeline_event 6a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 8a3f7b4e666c476898878fa745f637129375cd889Ben Murdochclass Slice(timeline_event.TimelineEvent): 9a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch """A Slice represents an interval of time plus parameters associated 10a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch with that interval. 11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 12a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch NOTE: The Sample class implements the same interface as 13a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch Slice. These must be kept in sync. 14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 15a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch All time units are stored in milliseconds. 16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch """ 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) def __init__(self, parent_thread, category, name, timestamp, duration=0, 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) thread_timestamp=None, thread_duration=None, args=None): 19a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch super(Slice, self).__init__( 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) category, name, timestamp, duration, thread_timestamp, thread_duration, 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) args) 22a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.parent_thread = parent_thread 23a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.parent_slice = None 24a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.sub_slices = [] 25a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.did_not_finish = False 26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def AddSubSlice(self, sub_slice): 28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch assert sub_slice.parent_slice == self 29a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch self.sub_slices.append(sub_slice) 30a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def IterEventsInThisContainerRecrusively(self, stack=None): 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # This looks awkward, but it lets us create only a single iterator instead 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # of having to create one iterator for every subslice found. 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if stack == None: 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stack = [] 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else: 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch assert len(stack) == 0 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stack.extend(reversed(self.sub_slices)) 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while len(stack): 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch s = stack.pop() 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch yield s 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stack.extend(reversed(s.sub_slices)) 43a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 44a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch @property 45a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def self_time(self): 46a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch """Time spent in this function less any time spent in child events.""" 47a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch child_total = sum( 48a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch [e.duration for e in self.sub_slices]) 49a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return self.duration - child_total 50a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @property 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) def self_thread_time(self): 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """Thread (scheduled) time spent in this function less any thread time spent 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) in child events. Returns None if the slice or any of its children does not 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) have a thread_duration value. 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) """ 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not self.thread_duration: 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return None 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) child_total = 0 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for e in self.sub_slices: 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if e.thread_duration == None: 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return None 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) child_total += e.thread_duration 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return self.thread_duration - child_total 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 68a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def _GetSubSlicesRecursive(self): 69a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for sub_slice in self.sub_slices: 70a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for s in sub_slice.GetAllSubSlices(): 71a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch yield s 72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch yield sub_slice 73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def GetAllSubSlices(self): 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return list(self._GetSubSlicesRecursive()) 76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch def GetAllSubSlicesOfName(self, name): 78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return [e for e in self.GetAllSubSlices() if e.name == name] 79