1 # SPDX-License-Identifier: Apache-2.0 2 # 3 # Copyright (C) 2015, 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 # pylint: disable=E1101 19 20 """ System Status Analaysis Module """ 21 22 import matplotlib.gridspec as gridspec 23 import matplotlib.pyplot as plt 24 25 from analysis_module import AnalysisModule 26 27 28 class StatusAnalysis(AnalysisModule): 29 """ 30 Support for System Status analysis 31 32 :param trace: input Trace object 33 :type trace: :mod:`libs.utils.Trace` 34 """ 35 36 def __init__(self, trace): 37 super(StatusAnalysis, self).__init__(trace) 38 39 40 ############################################################################### 41 # DataFrame Getter Methods 42 ############################################################################### 43 44 def _dfg_overutilized(self): 45 """ 46 Get data frame with sched_overutilized data. 47 """ 48 if not self._trace.hasEvents('sched_overutilized'): 49 return None 50 51 # Build sequence of overutilization "bands" 52 df = self._dfg_trace_event('sched_overutilized') 53 54 # Remove duplicated index events, keep only last event which is the 55 # only one with a non null length 56 df = df[df.len != 0] 57 # This filtering can also be achieved by removing events happening at 58 # the same time, but perhaps this filtering is more complex 59 # df = df.reset_index()\ 60 # .drop_duplicates(subset='Time', keep='last')\ 61 # .set_index('Time') 62 63 return df[['len', 'overutilized']] 64 65 66 ############################################################################### 67 # Plotting Methods 68 ############################################################################### 69 70 def plotOverutilized(self, axes=None): 71 """ 72 Draw a plot that shows intervals of time where the system was reported 73 as overutilized. 74 75 The optional axes parameter allows to plot the signal on an existing 76 graph. 77 78 :param axes: axes on which to plot the signal 79 :type axes: :mod:`matplotlib.axes.Axes` 80 """ 81 if not self._trace.hasEvents('sched_overutilized'): 82 self._log.warning('Event [sched_overutilized] not found, ' 83 'plot DISABLED!') 84 return 85 86 df = self._dfg_overutilized() 87 88 # Compute intervals in which the system is reported to be overutilized 89 bands = [(t, df['len'][t], df['overutilized'][t]) for t in df.index] 90 91 # If not axis provided: generate a standalone plot 92 if not axes: 93 gs = gridspec.GridSpec(1, 1) 94 plt.figure(figsize=(16, 1)) 95 axes = plt.subplot(gs[0, 0]) 96 axes.set_title('System Status {white: EAS mode, ' 97 'red: Non EAS mode}') 98 axes.set_xlim(self._trace.x_min, self._trace.x_max) 99 axes.set_yticklabels([]) 100 axes.set_xlabel('Time [s]') 101 axes.grid(True) 102 103 # Otherwise: draw overutilized bands on top of the specified plot 104 for (start, delta, overutilized) in bands: 105 if not overutilized: 106 continue 107 end = start + delta 108 axes.axvspan(start, end, facecolor='r', alpha=0.1) 109 110 # vim :set tabstop=4 shiftwidth=4 expandtab 111