def event_intervals(self, name=None, task=None, interval=None, match_exact=True): """Returns event intervals for specified `name` and `task` Name here implies `section` or `counter` name. """ if name is None: intervals = \ IntervalList(sorted_items(self._tmw_intervals_by_name.values())) elif isinstance(name, string_types): if match_exact: intervals = self._tmw_intervals_by_name[name] else: intervals = IntervalList( sorted_items(value for key, value in self._tmw_intervals_by_name.iteritems() if name in key)) else: # assume iterable (must match exact) intervals = IntervalList( sorted_items( value for key, value in self._tmw_intervals_by_name.iteritems() if key in name)) intervals = intervals.slice(interval=interval) if task: intervals = IntervalList( filter(lambda it: it.event.task == task, intervals)) return intervals
def io_request_intervals(self, op=None, interval=None, by='issue'): """Returns event intervals for specified `op` If by ='issue' (default): returns intervals from block issue ==> complete Elif by = 'insert': returns intervals from insert to queue ==> complete For list of io_types (aka ops) see `trace.disk.ops` # TODO: Filter by # of sectors & devices. See `DiskIOType` in `ftrace.io` for op. """ if by == 'insert': interval_dict = self._io_insert_intervals_by_op else: interval_dict = self._io_issue_intervals_by_op if op is None: intervals = \ IntervalList(sorted_items(interval_dict.values())) else: intervals = interval_dict[op] intervals = intervals.slice(interval=interval) return intervals
def pwrstate_intervals(self, device=None, state=None, interval=None): """ Returns pwr state intervals for specified state (if any) on device (if any) over the specified interval (if any). """ try: self._pwrstate_intervals_by_device.keys() except AttributeError: self._pwrstate_events_handler() try: if device is not None: intervals = self._pwrstate_intervals_by_device[device] else: intervals = IntervalList( sorted_items( self._pwrstate_intervals_by_device.values())) if is_list_like(state): filter_func = (lambda ti: ti.state in state) if state else None else: filter_func = (lambda ti: ti.state == state) if state else None return IntervalList(filter(filter_func, intervals.slice(interval=interval))) except: return IntervalList()
def cluster_intervals(self, cluster, interval=None): """Return interval for specified cluster & interval """ try: self._cluster_idle_intervals_by_cluster except AttributeError: _ = self._cluster_idle_events_handler() if cluster is not None: intervals = self._cluster_idle_intervals_by_cluster[cluster] else: intervals = IntervalList(sorted_items(self._cluster_idle_intervals_by_cluster.values())) return intervals.slice(interval=interval)
def cluster_intervals(self, cluster, interval=None): """Return interval for specified cluster & interval """ try: self._cluster_idle_intervals_by_cluster except AttributeError: _ = self._cluster_idle_events_handler() if cluster is not None: intervals = self._cluster_idle_intervals_by_cluster[cluster] else: intervals = IntervalList( sorted_items(self._cluster_idle_intervals_by_cluster.values())) return intervals.slice(interval=interval)
def frequency_intervals(self, device=None, interval=None): """Returns freq intervals for specified interval on device""" try: self._pwrlevel_intervals_by_device.keys() except AttributeError: self._pwrlevel_events_handler() try: if device is not None: intervals = self._pwrlevel_intervals_by_device[device] else: intervals = IntervalList( sorted_items( self._pwrlevel_intervals_by_device.values())) return intervals.slice(interval=interval) except: return IntervalList()
def buslevel_intervals(self, device=None, interval=None): """ """ try: self._buslevel_intervals_by_device.keys() except AttributeError: self._buslevel_events_handler() try: if device is not None: intervals = self._buslevel_intervals_by_device[device] else: intervals = IntervalList( sorted_items( self._buslevel_intervals_by_device.values())) return intervals.slice(interval=interval) except: return IntervalList()
def _input_latency_handler(self, irq_name): """ Returns list of all input events """ self._input_latencies = IntervalList() all_tasks = self._trace.cpu.task_intervals() all_aq_events = self.input_events() touch_irqs = IntervalList( filter_by_task(all_tasks, 'name', irq_name, 'any')) def _input_intervals(): """ Generator that yields intervals when discrete input event(s) are read & decoded by Android `Input Reader`. x__x__x____IR___ID_ID_ID___DI_SU__DI_SU__DI_SU______ x = multiple input IRQs (multi-touch translated by Android Input Framework) IR = Input Reader [read/decodes multiple events @ once] ID = Input Dispatch [dispatches each input event] DI = Deliver Input [ appropriate window consumes input event ] SU = SurfaceFlinger Screen Update due to window handling input event Please note InputReader 'iq' will be set to 1 whenever InputReader had event to process. This could be disabled in some systems. """ last_timestamp = self._trace.interval.start for ir_event in filter_by_task(all_tasks, 'name', 'InputReader', 'any'): yield Interval(last_timestamp, ir_event.interval.end) last_timestamp = ir_event.interval.end for interval in _input_intervals(): irqs = touch_irqs.slice(interval=interval, trimmed=False) # Necessary as we may be interested in different IRQ name if irqs: # Use longest IRQ start_ts = max( irqs, key=lambda x: x.interval.duration).interval.start end_ts = start_ts post_ir_interval = Interval(start_ts, self._trace.duration) di_events = self.event_intervals( name=['deliverInputEvent', 'input'], interval=post_ir_interval) if di_events: # IMPORTANT: If InputDispatcher sythesizes multiple # events to same application, we ignore consequent event # and only parse 1st event. This is because we heuristically # can't determine start of next input event to differentiate. di_event = di_events[0] # necessary in case a synthetic events is cancelled # canceled appropriately when the events are no longer # being resynthesized (because the application or IME is # already handling them or dropping them entirely) # This is done by checking for dumping input latencies when # active input event queue length (aq) is > 1 for same task. # For more details, see # https://android.googlesource.com/platform/frameworks/base.git/+ # /f9e989d5f09e72f5c9a59d713521f37d3fdd93dd%5E!/ # This returns first interval when aq has pending event(s) di_event_name = getattr(di_event, 'name', None) if di_event_name and di_event_name == 'input': pfb_events = self.event_intervals( name='doComposition', interval=post_ir_interval) else: aq_event = filter_by_task( all_aq_events.slice(interval=post_ir_interval), 'pid', di_event.event.task.pid) if aq_event and aq_event.value > 0: post_di_start = aq_event.interval.start else: if aq_event: continue # if AQ event exists. post_di_start = di_events[0].interval.start post_di_interval = Interval(post_di_start, self._trace.duration) pfb_events = self.event_intervals( name='doComposition', interval=post_di_interval) if pfb_events: end_ts = pfb_events[0].interval.end if start_ts != end_ts and end_ts > start_ts and start_ts not in self._input_latencies._start_timestamps: input_interval = Interval(start=start_ts, end=end_ts) self._input_latencies.append( InputLatency(interval=input_interval, latency=input_interval.duration)) return self._input_latencies