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 Integer cpu
= NonNullUtils
.checkNotNull(TmfTraceUtils
.resolveIntEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
));
73 LttngEventLayout eventLayout
= getProvider().getEventLayout();
74 LttngSystemModel system
= getProvider().getSystem();
76 Integer next
= EventField
.getInt(event
, eventLayout
.fieldNextTid());
77 Integer prev
= EventField
.getInt(event
, eventLayout
.fieldPrevTid());
78 long ts
= event
.getTimestamp().getValue();
79 long prev_state
= EventField
.getLong(event
, eventLayout
.fieldPrevState());
80 prev_state
= (long) ((int) prev_state
) & (LinuxValues
.TASK_STATE_RUNNING
| LinuxValues
.TASK_INTERRUPTIBLE
| LinuxValues
.TASK_UNINTERRUPTIBLE
);
81 String host
= event
.getTrace().getHostId();
83 system
.cacheTidOnCpu(cpu
, new HostThread(event
.getTrace().getHostId(), next
));
85 HostThread nextHt
= new HostThread(host
, next
);
86 LttngWorker nextTask
= system
.findWorker(nextHt
);
87 if (nextTask
== null) {
88 String name
= EventField
.getOrDefault(event
, eventLayout
.fieldNextComm(), NonNullUtils
.checkNotNull(Messages
.TraceEventHandlerSched_UnknownThreadName
));
89 nextTask
= new LttngWorker(nextHt
, name
, ts
);
90 system
.addWorker(nextTask
);
92 nextTask
.setStatus(ProcessStatus
.RUN
);
94 HostThread prevHt
= new HostThread(host
, prev
);
95 LttngWorker prevTask
= system
.findWorker(prevHt
);
96 if (prevTask
== null) {
97 String name
= EventField
.getOrDefault(event
, eventLayout
.fieldPrevComm(), NonNullUtils
.checkNotNull(Messages
.TraceEventHandlerSched_UnknownThreadName
));
98 prevTask
= new LttngWorker(prevHt
, name
, ts
);
99 system
.addWorker(prevTask
);
101 /* prev_state == 0 means runnable, thus waits for cpu */
102 if (prev_state
== 0) {
103 prevTask
.setStatus(ProcessStatus
.WAIT_CPU
);
105 prevTask
.setStatus(ProcessStatus
.WAIT_BLOCKED
);
109 private void handleSchedProcessFork(ITmfEvent event
) {
110 String host
= event
.getTrace().getHostId();
111 LttngEventLayout eventLayout
= getProvider().getEventLayout();
112 LttngSystemModel system
= getProvider().getSystem();
114 Integer childTid
= EventField
.getInt(event
, eventLayout
.fieldChildTid());
115 String name
= EventField
.getString(event
, eventLayout
.fieldChildComm());
116 long ts
= event
.getTimestamp().getValue();
118 HostThread childHt
= new HostThread(host
, childTid
);
120 LttngWorker childTask
= system
.findWorker(childHt
);
121 if (childTask
== null) {
122 childTask
= new LttngWorker(childHt
, name
, ts
);
123 system
.addWorker(childTask
);
126 childTask
.setStatus(ProcessStatus
.WAIT_FORK
);
129 private void handleSchedWakeup(ITmfEvent event
) {
130 String host
= event
.getTrace().getHostId();
131 Integer cpu
= NonNullUtils
.checkNotNull(TmfTraceUtils
.resolveIntEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
));
132 LttngEventLayout eventLayout
= getProvider().getEventLayout();
133 LttngSystemModel system
= getProvider().getSystem();
135 Integer tid
= EventField
.getInt(event
, eventLayout
.fieldTid());
136 HostThread targetHt
= new HostThread(host
, tid
);
138 LttngWorker target
= system
.findWorker(targetHt
);
139 LttngWorker current
= system
.getWorkerOnCpu(host
, cpu
);
140 if (target
== null) {
141 String name
= EventField
.getOrDefault(event
, eventLayout
.fieldComm(), NonNullUtils
.checkNotNull(Messages
.TraceEventHandlerSched_UnknownThreadName
));
142 target
= new LttngWorker(targetHt
, name
, event
.getTimestamp().getValue());
143 system
.addWorker(target
);
144 target
.setStatus(ProcessStatus
.WAIT_BLOCKED
);
147 ProcessStatus status
= target
.getStatus();
148 if ((current
!= null && target
.getHostThread().equals(current
.getHostThread())) ||
149 status
== ProcessStatus
.WAIT_CPU
) {
152 if (status
== ProcessStatus
.WAIT_BLOCKED
||
153 status
== ProcessStatus
.WAIT_FORK
||
154 status
== ProcessStatus
.UNKNOWN
) {
155 target
.setStatus(ProcessStatus
.WAIT_CPU
);
160 private void handleSchedProcessExit(ITmfEvent event
) {
161 String host
= event
.getTrace().getHostId();
162 LttngEventLayout eventLayout
= getProvider().getEventLayout();
163 LttngSystemModel system
= getProvider().getSystem();
165 Integer tid
= EventField
.getInt(event
, eventLayout
.fieldTid());
166 LttngWorker task
= system
.findWorker(new HostThread(host
, tid
));
170 task
.setStatus(ProcessStatus
.EXIT
);
173 private void handleSchedProcessExec(ITmfEvent event
) {
174 String host
= event
.getTrace().getHostId();
175 Integer cpu
= NonNullUtils
.checkNotNull(TmfTraceUtils
.resolveIntEventAspectOfClassForEvent(event
.getTrace(), TmfCpuAspect
.class, event
));
176 LttngEventLayout eventLayout
= getProvider().getEventLayout();
177 LttngSystemModel system
= getProvider().getSystem();
179 String filename
= EventField
.getString(event
, eventLayout
.fieldFilename());
180 LttngWorker task
= system
.getWorkerOnCpu(host
, cpu
);
184 task
.setName(filename
);