示例#1
0
    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
示例#2
0
    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
示例#3
0
    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()
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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()
示例#7
0
    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()
示例#8
0
    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