1# SPDX-License-Identifier: Apache-2.0
2#
3# Copyright (C) 2017, Google, ARM Limited and contributors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18""" IRQ Analysis Module"""
19from analysis_module import AnalysisModule
20import matplotlib.pyplot as plt
21import pylab as pl
22import pandas as pd
23import math
24
25class IRQAnalysis(AnalysisModule):
26    """
27    Support for plotting IRQ Analysis data
28
29    :param trace: input Trace object
30    :type trace: :mod:`libs.utils.Trace`
31    """
32    def __init__(self, trace):
33        super(IRQAnalysis, self).__init__(trace)
34
35    def plotIRQHistogram(self, title="Histogram of IRQ events", irq=None, bin_size_s=0.25):
36        """
37        plot a histogram of irq events.
38        :param title: title to afix to the plot
39        :type  title: str
40
41        :param name: the irq name or number to plot
42        :type  name: str or int
43
44        :param bin_size_s: the size of the bins for the histogram in seconds
45        :type  bin_size_s: float
46        """
47        df = self._dfg_trace_event('irq_handler_entry')
48
49        if len(df) == 0:
50            self._log.warning('no irq events to plot')
51            return
52
53        if type(irq) is int:
54            irqs = df[df.irq == irq]
55        elif type(irq) is str:
56            irqs = df[df.name == irq]
57        else:
58            raise TypeError('must give an irq number or name to plot')
59
60        pd.options.mode.chained_assignment = None
61        irqs['timestamp'] = irqs.index
62
63        fig, axes = plt.subplots()
64        plt.suptitle(title, y=.97, fontsize=16, horizontalalignment='center')
65
66        if len(irqs) > 0:
67            name = irqs.iloc[0]["name"]
68            irq_number = irqs.iloc[0]["irq"]
69
70            bin_range = pl.frange(self._trace.x_min, self._trace.x_max, bin_size_s)
71            irqs.hist(ax=axes, column='timestamp', bins=bin_range,
72                      grid=True, facecolor='green', alpha=0.5, edgecolor="b",
73                      range=(self._trace.x_min, self._trace.x_max))
74        else:
75            self._log.warning('no irq events to plot')
76            return
77
78        axes.set_title("irq_name = " + str(name) + ", bin size (s) " + str(bin_size_s))
79        axes.set_xlim(self._trace.x_min, self._trace.x_max)
80        axes.set_ylabel('number of IRQs')
81        axes.set_xlabel('seconds')
82        axes.grid(True)
83
84        figname = '{}/{}{}.png'\
85            .format(self._trace.plots_dir, self._trace.plots_prefix, "irq_" + str(irq_number) + "_" + str(name))
86        pl.savefig(figname, bbox_inches='tight')
87