3 # The MIT License (MIT)
5 # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
6 # 2015 - Antoine Busque <abusque@efficios.com>
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to deal
10 # in the Software without restriction, including without limitation the rights
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 # copies of the Software, and to permit persons to whom the Software is
13 # furnished to do so, subject to the following conditions:
15 # The above copyright notice and this permission notice shall be included in
16 # all copies or substantial portions of the Software.
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 class SchedStateProvider(sp
.StateProvider
):
30 def __init__(self
, state
):
32 'sched_switch': self
._process
_sched
_switch
,
33 'sched_migrate_task': self
._process
_sched
_migrate
_task
,
34 'sched_wakeup': self
._process
_sched
_wakeup
,
35 'sched_wakeup_new': self
._process
_sched
_wakeup
,
36 'sched_waking': self
._process
_sched
_wakeup
,
37 'sched_process_fork': self
._process
_sched
_process
_fork
,
38 'sched_process_exec': self
._process
_sched
_process
_exec
,
42 self
._register
_cbs
(cbs
)
44 def process_event(self
, ev
):
45 self
._process
_event
_cb
(ev
)
47 def _fix_process(self
, tid
, pid
, comm
):
48 """Fix a process' pid and comm if it exists, create it otherwise"""
49 if tid
not in self
._state
.tids
:
50 proc
= sv
.Process(tid
, pid
, comm
)
51 self
._state
.tids
[tid
] = proc
53 proc
= self
._state
.tids
[tid
]
57 def _sched_switch_per_cpu(self
, cpu_id
, next_tid
):
58 if cpu_id
not in self
._state
.cpus
:
59 self
._state
.cpus
[cpu_id
] = sv
.CPU(cpu_id
)
61 cpu
= self
._state
.cpus
[cpu_id
]
62 # exclude swapper process
64 cpu
.current_tid
= None
66 cpu
.current_tid
= next_tid
68 def _sched_switch_per_tid(self
, next_tid
, next_comm
, prev_tid
):
69 if next_tid
not in self
._state
.tids
:
71 # special case for the swapper
72 self
._state
.tids
[next_tid
] = sv
.Process(tid
=next_tid
, pid
=0)
74 self
._state
.tids
[next_tid
] = sv
.Process(tid
=next_tid
)
76 next_proc
= self
._state
.tids
[next_tid
]
77 next_proc
.comm
= next_comm
78 next_proc
.prev_tid
= prev_tid
80 def _process_sched_switch(self
, event
):
81 timestamp
= event
.timestamp
82 cpu_id
= event
['cpu_id']
83 next_tid
= event
['next_tid']
84 next_comm
= event
['next_comm']
85 prev_tid
= event
['prev_tid']
86 next_prio
= event
['next_prio']
88 self
._sched
_switch
_per
_cpu
(cpu_id
, next_tid
)
89 self
._sched
_switch
_per
_tid
(next_tid
, next_comm
, prev_tid
)
91 wakee_proc
= self
._state
.tids
[next_tid
]
93 if wakee_proc
.last_waker
is not None:
94 waker_proc
= self
._state
.tids
[wakee_proc
.last_waker
]
96 self
._state
.send_notification_cb('sched_switch_per_cpu',
100 self
._state
.send_notification_cb('sched_switch_per_tid',
105 wakee_proc
=wakee_proc
,
106 wakeup_ts
=wakee_proc
.last_wakeup
,
107 waker_proc
=waker_proc
,
110 wakee_proc
.last_wakeup
= None
111 wakee_proc
.last_waker
= None
113 def _process_sched_migrate_task(self
, event
):
115 if tid
not in self
._state
.tids
:
118 proc
.comm
= event
['comm']
119 self
._state
.tids
[tid
] = proc
121 proc
= self
._state
.tids
[tid
]
123 self
._state
.send_notification_cb('sched_migrate_task', proc
=proc
)
125 def _process_sched_wakeup(self
, event
):
126 target_cpu
= event
['target_cpu']
128 current_cpu
= event
['cpu_id']
130 if target_cpu
not in self
._state
.cpus
:
131 self
._state
.cpus
[target_cpu
] = sv
.CPU(target_cpu
)
133 if current_cpu
not in self
._state
.cpus
:
134 self
._state
.cpus
[current_cpu
] = sv
.CPU(current_cpu
)
136 # If the TID is already executing on a CPU, ignore this wakeup
137 for cpu_id
in self
._state
.cpus
:
138 cpu
= self
._state
.cpus
[cpu_id
]
139 if cpu
.current_tid
== tid
:
142 if tid
not in self
._state
.tids
:
145 self
._state
.tids
[tid
] = proc
146 # a process can be woken up multiple times, only record
148 if self
._state
.tids
[tid
].last_wakeup
is None:
149 self
._state
.tids
[tid
].last_wakeup
= event
.timestamp
150 if self
._state
.cpus
[current_cpu
].current_tid
is not None:
151 self
._state
.tids
[tid
].last_waker
= \
152 self
._state
.cpus
[current_cpu
].current_tid
154 def _process_sched_process_fork(self
, event
):
155 child_tid
= event
['child_tid']
156 child_pid
= event
['child_pid']
157 child_comm
= event
['child_comm']
158 parent_pid
= event
['parent_pid']
159 parent_tid
= event
['parent_pid']
160 parent_comm
= event
['parent_comm']
162 child_proc
= sv
.Process(child_tid
, child_pid
, child_comm
)
164 self
._fix
_process
(parent_tid
, parent_pid
, parent_comm
)
165 parent_proc
= self
._state
.tids
[parent_pid
]
167 for fd
in parent_proc
.fds
:
168 old_fd
= parent_proc
.fds
[fd
]
169 child_proc
.fds
[fd
] = sv
.FD
.new_from_fd(old_fd
)
170 # Note: the parent_proc key in the notification function
171 # refers to the parent of the FD, which in this case is
172 # the child_proc created by the fork
173 self
._state
.send_notification_cb('create_fd',
175 parent_proc
=child_proc
,
176 timestamp
=event
.timestamp
,
177 cpu_id
=event
['cpu_id'])
179 self
._state
.tids
[child_tid
] = child_proc
181 def _process_sched_process_exec(self
, event
):
184 if tid
not in self
._state
.tids
:
187 self
._state
.tids
[tid
] = proc
189 proc
= self
._state
.tids
[tid
]
191 # Use LTTng procname context if available
192 if 'procname' in event
:
193 proc
.comm
= event
['procname']
197 if proc
.fds
[fd
].cloexec
:
200 self
._state
.send_notification_cb('close_fd',
203 timestamp
=event
.timestamp
,
204 cpu_id
=event
['cpu_id'])
This page took 0.03903 seconds and 5 git commands to generate.