1#    Copyright 2015-2017 ARM Limited
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16
17"""Definitions of scheduler events registered by the FTrace class"""
18
19from trappy.base import Base
20from trappy.dynamic import register_ftrace_parser, register_dynamic_ftrace
21
22class SchedLoadAvgSchedGroup(Base):
23    """Corresponds to Linux kernel trace event sched_load_avg_sched_group"""
24
25    unique_word = "sched_load_avg_sg:"
26    """The unique word that will be matched in a trace line"""
27
28    _cpu_mask_column = "cpus"
29
30    pivot = "cpus"
31    """The Pivot along which the data is orthogonal"""
32
33    def finalize_object(self):
34        """This condition is necessary to force column 'cpus' to be printed
35        as 8 digits w/ leading 0
36        """
37        if self._cpu_mask_column in self.data_frame.columns:
38            dfr = self.data_frame[self._cpu_mask_column].apply('{:0>8}'.format)
39            self.data_frame[self._cpu_mask_column] = dfr
40
41register_ftrace_parser(SchedLoadAvgSchedGroup, "sched")
42
43class SchedLoadAvgTask(Base):
44    """Corresponds to Linux kernel trace event sched_load_avg_task"""
45
46    unique_word = "sched_load_avg_task:"
47    """The unique word that will be matched in a trace line"""
48
49    pivot = "pid"
50    """The Pivot along which the data is orthogonal"""
51
52    def get_pids(self, key=""):
53        """Returns a list of (comm, pid) that contain
54        'key' in their 'comm'."""
55        dfr = self.data_frame.drop_duplicates(subset=['comm', 'pid'])
56        dfr = dfr.ix[:, ['comm', 'pid']]
57
58        return dfr[dfr['comm'].str.contains(key)].values.tolist()
59
60register_ftrace_parser(SchedLoadAvgTask, "sched")
61
62# pylint doesn't like globals that are not ALL_CAPS
63# pylint: disable=invalid-name
64SchedLoadAvgCpu = register_dynamic_ftrace("SchedLoadAvgCpu",
65                                          "sched_load_avg_cpu:", "sched",
66                                          pivot="cpu")
67"""Load and Utilization Signals for CPUs"""
68
69SchedContribScaleFactor = register_dynamic_ftrace("SchedContribScaleFactor",
70                                                  "sched_contrib_scale_f:",
71                                                  "sched")
72"""Event to register tracing of contrib factor"""
73
74class SchedCpuCapacity(Base):
75    """Corresponds to Linux kernel trace event sched/cpu_capacity"""
76
77    unique_word = "cpu_capacity:"
78    """The unique word that will be matched in a trace line"""
79
80    pivot = "cpu"
81    """The Pivot along which the data is orthogonal"""
82
83    def finalize_object(self):
84        """This renaming is necessary because our cpu related pivot is 'cpu'
85        and not 'cpu_id'. Otherwise you cannot 'mix and match' with other
86        classes
87        """
88        self.data_frame.rename(columns={'cpu_id':'cpu'}, inplace=True)
89        self.data_frame.rename(columns={'state' :'capacity'}, inplace=True)
90
91register_ftrace_parser(SchedCpuCapacity, "sched")
92
93SchedWakeup = register_dynamic_ftrace("SchedWakeup", "sched_wakeup:", "sched",
94                                       parse_raw=True)
95"""Register SchedWakeup Event"""
96
97SchedWakeupNew = register_dynamic_ftrace("SchedWakeupNew", "sched_wakeup_new:",
98                                         "sched", parse_raw=True)
99"""Register SchedWakeupNew Event"""
100
101# pylint: enable=invalid-name
102
103class SchedSwitch(Base):
104    """Parse sched_switch"""
105
106    unique_word = "sched_switch:"
107    parse_raw = True
108
109    def __init__(self):
110        super(SchedSwitch, self).__init__(parse_raw=self.parse_raw)
111
112    def create_dataframe(self):
113        self.data_array = [line.replace(" ==> ", " ", 1)
114                           for line in self.data_array]
115
116        super(SchedSwitch, self).create_dataframe()
117
118register_ftrace_parser(SchedSwitch, "sched")
119
120class SchedCpuFrequency(Base):
121    """Corresponds to Linux kernel trace event power/cpu_frequency"""
122
123    unique_word = "cpu_frequency:"
124    """The unique word that will be matched in a trace line"""
125
126    pivot = "cpu"
127    """The Pivot along which the data is orthogonal"""
128
129    def finalize_object(self):
130        """This renaming is necessary because our cpu related pivot is 'cpu'
131        and not 'cpu_id'. Otherwise you cannot 'mix and match' with other
132        classes
133        """
134        self.data_frame.rename(columns={'cpu_id':'cpu'}, inplace=True)
135        self.data_frame.rename(columns={'state' :'frequency'}, inplace=True)
136
137register_ftrace_parser(SchedCpuFrequency, "sched")
138
139register_dynamic_ftrace("SchedMigrateTask", "sched_migrate_task:", "sched")
140