1 /*******************************************************************************
2 * Copyright (c) 2015 École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.handlers
;
12 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelanalysis
.LinuxValues
;
13 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.model
.HostThread
;
14 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
15 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.building
.LttngKernelExecGraphProvider
;
16 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.building
.LttngKernelExecGraphProvider
.ProcessStatus
;
17 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.model
.EventField
;
18 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.model
.LttngSystemModel
;
19 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.analysis
.graph
.model
.LttngWorker
;
20 import org
.eclipse
.tracecompass
.internal
.lttng2
.kernel
.core
.trace
.layout
.LttngEventLayout
;
21 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
22 import org
.eclipse
.tracecompass
.tmf
.core
.event
.aspect
.TmfCpuAspect
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
26 * Provides the current task running on a CPU according to scheduling events
28 * @author Francis Giraldeau
29 * @author Geneviève Bastien
31 public class TraceEventHandlerSched
extends BaseHandler
{
37 * The parent graph provider
39 public TraceEventHandlerSched(LttngKernelExecGraphProvider provider
) {
44 public void handleEvent(ITmfEvent ev
) {
45 String eventName
= ev
.getName();
46 LttngEventLayout eventLayout
= getProvider().getEventLayout();
48 if (eventName
.equals(eventLayout
.eventSchedSwitch())) {
49 handleSchedSwitch(ev
);
50 } else if (eventName
.equals(eventLayout
.eventSchedProcessTTWU())) {
51 if (traceHasEventSchedTTWU(ev
.getTrace())) {
52 handleSchedWakeup(ev
);
54 } else if (eventName
.equals(eventLayout
.eventSchedProcessWakeup())) {
55 if (!traceHasEventSchedTTWU(ev
.getTrace())) {
56 handleSchedWakeup(ev
);
58 } else if (eventName
.equals(eventLayout
.eventSchedProcessWakeupNew())) {
59 if (!traceHasEventSchedTTWU(ev
.getTrace())) {
60 handleSchedWakeup(ev
);
62 } else if (eventName
.equals(eventLayout
.eventSchedProcessFork())) {
63 handleSchedProcessFork(ev
);
64 } else if (eventName
.equals(eventLayout
.eventSchedProcessExit())) {
65 handleSchedProcessExit(ev
);
66 } else if (eventName
.equals(eventLayout
.eventSchedProcessExec())) {
67 handleSchedProcessExec(ev
);
71 private void handleSchedSwitch(ITmfEvent event
) {
72 Object cpuObj
= TmfTraceUtils
.resolveEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
);
74 throw new NullPointerException();
76 Integer cpu
= (Integer
) cpuObj
;
77 LttngEventLayout eventLayout
= getProvider().getEventLayout();
78 LttngSystemModel system
= getProvider().getSystem();
80 Integer next
= EventField
.getInt(event
, eventLayout
.fieldNextTid());
81 Integer prev
= EventField
.getInt(event
, eventLayout
.fieldPrevTid());
82 long ts
= event
.getTimestamp().getValue();
83 long prev_state
= EventField
.getLong(event
, eventLayout
.fieldPrevState());
84 prev_state
= (long) ((int) prev_state
) & (LinuxValues
.TASK_STATE_RUNNING
| LinuxValues
.TASK_INTERRUPTIBLE
| LinuxValues
.TASK_UNINTERRUPTIBLE
);
85 String host
= event
.getTrace().getHostId();
87 system
.cacheTidOnCpu(cpu
, new HostThread(event
.getTrace().getHostId(), next
));
89 HostThread nextHt
= new HostThread(host
, next
);
90 LttngWorker nextTask
= system
.findWorker(nextHt
);
91 if (nextTask
== null) {
92 String name
= EventField
.getOrDefault(event
, eventLayout
.fieldNextComm(), NonNullUtils
.checkNotNull(Messages
.TraceEventHandlerSched_UnknownThreadName
));
93 nextTask
= new LttngWorker(nextHt
, name
, ts
);
94 system
.addWorker(nextTask
);
96 nextTask
.setStatus(ProcessStatus
.RUN
);
98 HostThread prevHt
= new HostThread(host
, prev
);
99 LttngWorker prevTask
= system
.findWorker(prevHt
);
100 if (prevTask
== null) {
101 String name
= EventField
.getOrDefault(event
, eventLayout
.fieldPrevComm(), NonNullUtils
.checkNotNull(Messages
.TraceEventHandlerSched_UnknownThreadName
));
102 prevTask
= new LttngWorker(prevHt
, name
, ts
);
103 system
.addWorker(prevTask
);
105 /* prev_state == 0 means runnable, thus waits for cpu */
106 if (prev_state
== 0) {
107 prevTask
.setStatus(ProcessStatus
.WAIT_CPU
);
109 prevTask
.setStatus(ProcessStatus
.WAIT_BLOCKED
);
113 private void handleSchedProcessFork(ITmfEvent event
) {
114 String host
= event
.getTrace().getHostId();
115 LttngEventLayout eventLayout
= getProvider().getEventLayout();
116 LttngSystemModel system
= getProvider().getSystem();
118 Integer childTid
= EventField
.getInt(event
, eventLayout
.fieldChildTid());
119 String name
= EventField
.getString(event
, eventLayout
.fieldChildComm());
120 long ts
= event
.getTimestamp().getValue();
122 HostThread childHt
= new HostThread(host
, childTid
);
124 LttngWorker childTask
= system
.findWorker(childHt
);
125 if (childTask
== null) {
126 childTask
= new LttngWorker(childHt
, name
, ts
);
127 system
.addWorker(childTask
);
130 childTask
.setStatus(ProcessStatus
.WAIT_FORK
);
133 private void handleSchedWakeup(ITmfEvent event
) {
134 String host
= event
.getTrace().getHostId();
135 Object cpuObj
= TmfTraceUtils
.resolveEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
);
136 if (cpuObj
== null) {
137 throw new NullPointerException();
139 Integer cpu
= (Integer
) cpuObj
;
140 LttngEventLayout eventLayout
= getProvider().getEventLayout();
141 LttngSystemModel system
= getProvider().getSystem();
143 Integer tid
= EventField
.getInt(event
, eventLayout
.fieldTid());
144 HostThread targetHt
= new HostThread(host
, tid
);
146 LttngWorker target
= system
.findWorker(targetHt
);
147 LttngWorker current
= system
.getWorkerOnCpu(host
, cpu
);
148 if (target
== null) {
149 String name
= EventField
.getOrDefault(event
, eventLayout
.fieldComm(), NonNullUtils
.checkNotNull(Messages
.TraceEventHandlerSched_UnknownThreadName
));
150 target
= new LttngWorker(targetHt
, name
, event
.getTimestamp().getValue());
151 system
.addWorker(target
);
152 target
.setStatus(ProcessStatus
.WAIT_BLOCKED
);
155 ProcessStatus status
= target
.getStatus();
156 if ((current
!= null && target
.getHostThread().equals(current
.getHostThread())) ||
157 status
== ProcessStatus
.WAIT_CPU
) {
160 if (status
== ProcessStatus
.WAIT_BLOCKED
||
161 status
== ProcessStatus
.WAIT_FORK
||
162 status
== ProcessStatus
.UNKNOWN
) {
163 target
.setStatus(ProcessStatus
.WAIT_CPU
);
168 private void handleSchedProcessExit(ITmfEvent event
) {
169 String host
= event
.getTrace().getHostId();
170 LttngEventLayout eventLayout
= getProvider().getEventLayout();
171 LttngSystemModel system
= getProvider().getSystem();
173 Integer tid
= EventField
.getInt(event
, eventLayout
.fieldTid());
174 LttngWorker task
= system
.findWorker(new HostThread(host
, tid
));
178 task
.setStatus(ProcessStatus
.EXIT
);
181 private void handleSchedProcessExec(ITmfEvent event
) {
182 String host
= event
.getTrace().getHostId();
183 Object cpuObj
= TmfTraceUtils
.resolveEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
);
184 if (cpuObj
== null) {
185 throw new NullPointerException();
187 Integer cpu
= (Integer
) cpuObj
;
188 LttngEventLayout eventLayout
= getProvider().getEventLayout();
189 LttngSystemModel system
= getProvider().getSystem();
191 String filename
= EventField
.getString(event
, eventLayout
.fieldFilename());
192 LttngWorker task
= system
.getWorkerOnCpu(host
, cpu
);
196 task
.setName(filename
);