普通文本  |  111行  |  3.7 KB

# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2015, ARM Limited and contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# pylint: disable=E1101

""" System Status Analaysis Module """

import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt

from analysis_module import AnalysisModule


class StatusAnalysis(AnalysisModule):
    """
    Support for System Status analysis

    :param trace: input Trace object
    :type trace: :mod:`libs.utils.Trace`
    """

    def __init__(self, trace):
        super(StatusAnalysis, self).__init__(trace)


###############################################################################
# DataFrame Getter Methods
###############################################################################

    def _dfg_overutilized(self):
        """
        Get data frame with sched_overutilized data.
        """
        if not self._trace.hasEvents('sched_overutilized'):
            return None

        # Build sequence of overutilization "bands"
        df = self._dfg_trace_event('sched_overutilized')

        # Remove duplicated index events, keep only last event which is the
        # only one with a non null length
        df = df[df.len != 0]
        # This filtering can also be achieved by removing events happening at
        # the same time, but perhaps this filtering is more complex
        # df = df.reset_index()\
        #         .drop_duplicates(subset='Time', keep='last')\
        #         .set_index('Time')

        return df[['len', 'overutilized']]


###############################################################################
# Plotting Methods
###############################################################################

    def plotOverutilized(self, axes=None):
        """
        Draw a plot that shows intervals of time where the system was reported
        as overutilized.

        The optional axes parameter allows to plot the signal on an existing
        graph.

        :param axes: axes on which to plot the signal
        :type axes: :mod:`matplotlib.axes.Axes`
        """
        if not self._trace.hasEvents('sched_overutilized'):
            self._log.warning('Event [sched_overutilized] not found, '
                              'plot DISABLED!')
            return

        df = self._dfg_overutilized()

        # Compute intervals in which the system is reported to be overutilized
        bands = [(t, df['len'][t], df['overutilized'][t]) for t in df.index]

        # If not axis provided: generate a standalone plot
        if not axes:
            gs = gridspec.GridSpec(1, 1)
            plt.figure(figsize=(16, 1))
            axes = plt.subplot(gs[0, 0])
            axes.set_title('System Status {white: EAS mode, '
                           'red: Non EAS mode}')
            axes.set_xlim(self._trace.x_min, self._trace.x_max)
            axes.set_yticklabels([])
            axes.set_xlabel('Time [s]')
            axes.grid(True)

        # Otherwise: draw overutilized bands on top of the specified plot
        for (start, delta, overutilized) in bands:
            if not overutilized:
                continue
            end = start + delta
            axes.axvspan(start, end, facecolor='r', alpha=0.1)

# vim :set tabstop=4 shiftwidth=4 expandtab