Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeneviève Bastien2018-02-12 10:58:29 -0500
committerGenevieve Bastien2018-05-04 15:15:52 -0400
commitf8db6e55d77472c2da4733aa489867cffb3bb260 (patch)
tree276d9e984b698399812b6a32a94cfd4201a5e13f
parente4f7c5119aee80e3db30443114e48f078299bb85 (diff)
downloadorg.eclipse.tracecompass.incubator-f8db6e55d77472c2da4733aa489867cffb3bb260.tar.gz
org.eclipse.tracecompass.incubator-f8db6e55d77472c2da4733aa489867cffb3bb260.tar.xz
org.eclipse.tracecompass.incubator-f8db6e55d77472c2da4733aa489867cffb3bb260.zip
vm: Update the overhead analysis to the new model
Change-Id: If8faf152d3dc11c2a9874c2af6ad4b8f1dd368c4 Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net> Reviewed-on: https://git.eclipse.org/r/117202 Tested-by: CI Bot Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/OneQemuKvmTestCase.java12
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/package-info.java2
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/testfiles/vm/OneQemuKvm/host.xml10
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/META-INF/MANIFEST.MF1
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/IVirtualEnvironmentModel.java4
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/analysis/VirtualEnvironment.java9
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadAnalysis.java11
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadStateProvider.java358
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/QemuKvmEventHandler.java120
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/SchedSwitchEventHandler.java224
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/package-info.java11
-rw-r--r--vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/virtual/resources/VirtualResourcesStateProvider.java1
12 files changed, 485 insertions, 278 deletions
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/OneQemuKvmTestCase.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/OneQemuKvmTestCase.java
index 4aa468e2..87164655 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/OneQemuKvmTestCase.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/OneQemuKvmTestCase.java
@@ -42,7 +42,9 @@ public class OneQemuKvmTestCase extends VmTestCase {
Set<IntervalInfo> info = new HashSet<>();
/* Verify the first level of overhead attribute */
- ImmutableList<ITmfStateInterval> intervals = ImmutableList.of(new StateIntervalStub(1, 174, TmfStateValue.nullValue()),
+ ImmutableList<ITmfStateInterval> intervals = ImmutableList.of(new StateIntervalStub(1, 34, TmfStateValue.nullValue()),
+ new StateIntervalStub(35, 74, TmfStateValue.newValueString("RUN")),
+ new StateIntervalStub(75, 174, TmfStateValue.nullValue()),
new StateIntervalStub(175, 224, TmfStateValue.newValueString("RUN")),
new StateIntervalStub(225, 274, TmfStateValue.nullValue()),
new StateIntervalStub(275, 374, TmfStateValue.newValueString("RUN")),
@@ -50,7 +52,9 @@ public class OneQemuKvmTestCase extends VmTestCase {
info.add(new IntervalInfo(intervals, VmOverheadStateProvider.TRACES, VmTraces.GUEST_ONE_QEMUKVM.getHostId(), VmOverheadStateProvider.THREADS, "130", "CallStack", "1"));
/* Verify the second level of overhead */
- intervals = ImmutableList.of(new StateIntervalStub(1, 194, TmfStateValue.nullValue()),
+ intervals = ImmutableList.of(new StateIntervalStub(1, 44, TmfStateValue.nullValue()),
+ new StateIntervalStub(45, 59, TmfStateValue.newValueString("VMM")),
+ new StateIntervalStub(60, 194, TmfStateValue.nullValue()),
new StateIntervalStub(195, 209, TmfStateValue.newValueString("VMM")),
new StateIntervalStub(210, 294, TmfStateValue.nullValue()),
new StateIntervalStub(295, 299, TmfStateValue.newValueString("VMM")),
@@ -60,7 +64,9 @@ public class OneQemuKvmTestCase extends VmTestCase {
info.add(new IntervalInfo(intervals, VmOverheadStateProvider.TRACES, VmTraces.GUEST_ONE_QEMUKVM.getHostId(), VmOverheadStateProvider.THREADS, "130", "CallStack", "2"));
/* Verify the third level of overhead */
- intervals = ImmutableList.of(new StateIntervalStub(1, 194, TmfStateValue.nullValue()),
+ intervals = ImmutableList.of(new StateIntervalStub(1, 44, TmfStateValue.nullValue()),
+ new StateIntervalStub(45, 59, TmfStateValue.newValueString("32")),
+ new StateIntervalStub(60, 194, TmfStateValue.nullValue()),
new StateIntervalStub(195, 209, TmfStateValue.newValueString("32")),
new StateIntervalStub(210, 294, TmfStateValue.nullValue()),
new StateIntervalStub(295, 299, TmfStateValue.newValueString("32")),
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/package-info.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/package-info.java
index 2936ed1d..1cdf40ec 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/package-info.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/src/org/eclipse/tracecompass/incubator/virtual/machine/analysis/core/tests/overhead/package-info.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017 École Polytechnique de Montréal
+ * Copyright (c) 2018 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/testfiles/vm/OneQemuKvm/host.xml b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/testfiles/vm/OneQemuKvm/host.xml
index dc0e1fa9..6a36cc92 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/testfiles/vm/OneQemuKvm/host.xml
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests/testfiles/vm/OneQemuKvm/host.xml
@@ -18,7 +18,7 @@
</event>
<event timestamp="45" name="kvm_exit">
<field name="cpu" value="0" type="int" />
-<field name="exit_reason" value="32" type="int" />
+<field name="exit_reason" value="32" type="long" />
<field name="guest_rip" value="123456" type="long" />
<field name="isa" value="1" type="int" />
<field name="info1" value="654654" type="long" />
@@ -40,7 +40,7 @@
</event>
<event timestamp="95" name="kvm_exit">
<field name="cpu" value="0" type="int" />
-<field name="exit_reason" value="32" type="int" />
+<field name="exit_reason" value="32" type="long" />
<field name="guest_rip" value="123456" type="long" />
<field name="isa" value="1" type="int" />
<field name="info1" value="654654" type="long" />
@@ -72,7 +72,7 @@
</event>
<event timestamp="195" name="kvm_exit">
<field name="cpu" value="0" type="int" />
-<field name="exit_reason" value="32" type="int" />
+<field name="exit_reason" value="32" type="long" />
<field name="guest_rip" value="123456" type="long" />
<field name="isa" value="1" type="int" />
<field name="info1" value="654654" type="long" />
@@ -94,7 +94,7 @@
</event>
<event timestamp="245" name="kvm_exit">
<field name="cpu" value="0" type="int" />
-<field name="exit_reason" value="32" type="int" />
+<field name="exit_reason" value="32" type="long" />
<field name="guest_rip" value="123456" type="long" />
<field name="isa" value="1" type="int" />
<field name="info1" value="654654" type="long" />
@@ -116,7 +116,7 @@
</event>
<event timestamp="295" name="kvm_exit">
<field name="cpu" value="0" type="int" />
-<field name="exit_reason" value="32" type="int" />
+<field name="exit_reason" value="32" type="long" />
<field name="guest_rip" value="123456" type="long" />
<field name="isa" value="1" type="int" />
<field name="info1" value="654654" type="long" />
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/META-INF/MANIFEST.MF b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/META-INF/MANIFEST.MF
index 05e34cb3..d5d15be0 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/META-INF/MANIFEST.MF
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/META-INF/MANIFEST.MF
@@ -29,6 +29,7 @@ Export-Package: org.eclipse.tracecompass.incubator.internal.virtual.machine.anal
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.lxc;x-internal:=true,
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.qemukvm;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests,org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui",
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests",
+ org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.handlers;x-internal:=true,
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.trace;x-internal:=true,
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.virtual.resources;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests,org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui",
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.virtual.resources.handlers;x-internal:=true
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/IVirtualEnvironmentModel.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/IVirtualEnvironmentModel.java
index ce4d6d49..7e35ffdb 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/IVirtualEnvironmentModel.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/IVirtualEnvironmentModel.java
@@ -94,7 +94,7 @@ public interface IVirtualEnvironmentModel {
* @return The HostThread corresponding to this CPU, or <code>null</code> if no
* such thread is found
*/
- // @Nullable
- // HostThread getVirtualCpuTid(VirtualCPU vcpu);
+ @Nullable
+ HostThread getVirtualCpuTid(VirtualCPU vcpu);
}
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/analysis/VirtualEnvironment.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/analysis/VirtualEnvironment.java
index 45bb8b8e..13d3257e 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/analysis/VirtualEnvironment.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/model/analysis/VirtualEnvironment.java
@@ -24,6 +24,8 @@ import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedE
import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
import com.google.common.primitives.Longs;
/**
@@ -36,7 +38,7 @@ import com.google.common.primitives.Longs;
public class VirtualEnvironment implements IVirtualEnvironmentModel {
/** Associate a host's thread to a virtual CPU */
- protected final Map<HostThread, VirtualCPU> fTidToVcpu = new HashMap<>();
+ protected final BiMap<HostThread, VirtualCPU> fTidToVcpu = HashBiMap.create();
/** Associate a host's thread to a virtual machine */
protected final Map<HostThread, VirtualMachine> fTidToVm = new HashMap<>();
/** Maps a virtual machine name to a virtual machine */
@@ -153,4 +155,9 @@ public class VirtualEnvironment implements IVirtualEnvironmentModel {
return fKnownMachines.values();
}
+ @Override
+ public @Nullable HostThread getVirtualCpuTid(VirtualCPU vcpu) {
+ return fTidToVcpu.inverse().get(vcpu);
+ }
+
}
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadAnalysis.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadAnalysis.java
index 15f5c59a..c498ed0a 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadAnalysis.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadAnalysis.java
@@ -26,6 +26,7 @@ import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesyste
import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.InstrumentedCallStackElement;
import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.fused.FusedVMInformationProvider;
import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.fused.FusedVirtualMachineAnalysis;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.analysis.VirtualMachineModelAnalysis;
import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.virtual.resources.VirtualResourcesAnalysis;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
@@ -89,7 +90,15 @@ public class VmOverheadAnalysis extends InstrumentedCallStackAnalysis {
if (!(trace instanceof TmfExperiment)) {
throw new IllegalStateException();
}
- return new VmOverheadStateProvider((TmfExperiment) trace);
+ VirtualMachineModelAnalysis model = TmfTraceUtils.getAnalysisModuleOfClass(trace, VirtualMachineModelAnalysis.class, VirtualMachineModelAnalysis.ID);
+ if (model == null) {
+ throw new IllegalStateException("There should be a model analysis for this class"); //$NON-NLS-1$
+ }
+ model.schedule();
+ if (!model.waitForInitialization()) {
+ throw new IllegalStateException("Problem initializing the model analysis"); //$NON-NLS-1$
+ }
+ return new VmOverheadStateProvider((TmfExperiment) trace, model.getVirtualEnvironmentModel());
}
/**
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadStateProvider.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadStateProvider.java
index b7de76da..d0d062f5 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadStateProvider.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/VmOverheadStateProvider.java
@@ -11,6 +11,7 @@ package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.cor
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -18,7 +19,6 @@ import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.LinuxTidAspect;
import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.DefaultEventLayout;
import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
@@ -26,23 +26,20 @@ import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
import org.eclipse.tracecompass.incubator.analysis.core.concepts.ProcessStatusInterval;
import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel;
import org.eclipse.tracecompass.incubator.analysis.core.model.ModelManager;
-import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis;
-import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.IVirtualMachineModel;
-import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.VirtualCPU;
-import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.VirtualMachine;
-import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.qemukvm.QemuKvmVmModel;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.IVirtualMachineEventHandler;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.IVirtualEnvironmentModel;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.handlers.QemuKvmEventHandler;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.handlers.SchedSwitchEventHandler;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
-import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
-import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.Table;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
/**
* State provider for VM overhead analysis. At the first level is the status of
@@ -58,38 +55,53 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
* The threads attribute in the state system
*/
public static final String TRACES = "Traces"; //$NON-NLS-1$
-
/**
* The threads attribute in the state system
*/
public static final String THREADS = "Threads"; //$NON-NLS-1$
+ /**
+ * First level of overhead
+ */
+ public static final String LEVEL_1 = "1"; //$NON-NLS-1$
+ /**
+ * Second level of overhead
+ */
+ public static final String LEVEL_2 = "2"; //$NON-NLS-1$
+ /**
+ * Third level of overhead
+ */
+ public static final String LEVEL_3 = "3"; //$NON-NLS-1$
+ /**
+ * The status string for a preempted VCPU
+ */
+ public static final String STATUS_VCPU_PREEMPTED = "VCPU Preempted"; //$NON-NLS-1$
+ /**
+ * The status string of a VMM mode
+ */
+ public static final String STATUS_VMM_MODE = "VMM"; //$NON-NLS-1$
+ /**
+ * The status string for running
+ */
+ public static final String STATUS_RUNNING = "Running"; //$NON-NLS-1$
/**
* Version number of this state provider. Please bump this if you modify the
* contents of the generated state history in some way.
*/
- private static final int VERSION = 3;
-
- private static final int SCHED_SWITCH_INDEX = 0;
- private static final int KVM_ENTRY_INDEX = 1;
- private static final int KVM_EXIT_INDEX = 2;
-
- private static final String LEVEL_1 = "1"; //$NON-NLS-1$
- private static final String LEVEL_2 = "2"; //$NON-NLS-1$
- private static final String LEVEL_3 = "3"; //$NON-NLS-1$
- private static final String STATUS_VCPU_PREEMPTED = "VCPU Preempted"; //$NON-NLS-1$
- private static final String STATUS_VMM_MODE = "VMM"; //$NON-NLS-1$
- private static final String STATUS_RUNNING = "Running"; //$NON-NLS-1$
- private static final String FIELD_EXIT_REASON = "exit_reason"; //$NON-NLS-1$
-
- /* TODO: An analysis should support many hypervisor models */
- private IVirtualMachineModel fModel;
- private final Table<ITmfTrace, String, @Nullable Integer> fEventNames;
+ private static final int VERSION = 4;
+
+ private final Multimap<String, IVirtualMachineEventHandler> fEventNames = HashMultimap.create();
+ private final Collection<IVirtualMachineEventHandler> fHandlers;
private final Map<ITmfTrace, IKernelAnalysisEventLayout> fLayouts;
+ private final IVirtualEnvironmentModel fModel;
+
+ // A map of currently running thread and their kernel statuses
private final Map<HostThread, GuestKernelThreadStatuses> fGuestThreads = new HashMap<>();
- private final Map<HostThread, OverheadStatus> fPrevStatus = new HashMap<>();
+ // This class will update the guest kernel statuses for the running threads, so
+ // that the line corresponding to the guest thread contains the real thread
+ // statuses
private class GuestKernelThreadStatuses {
private final ITmfStateSystemBuilder fSs;
@@ -120,16 +132,6 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
}
- private class OverheadStatus {
- private final @Nullable Object fLevel2;
- private final @Nullable Object fLevel3;
-
- public OverheadStatus(@Nullable Object level2, @Nullable Object level3) {
- fLevel2 = level2;
- fLevel3 = level3;
- }
- }
-
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
@@ -139,13 +141,14 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
*
* @param experiment
* The virtual machine experiment
+ * @param model
+ * The virtual environment model
*/
- public VmOverheadStateProvider(TmfExperiment experiment) {
+ public VmOverheadStateProvider(TmfExperiment experiment, IVirtualEnvironmentModel model) {
super(experiment, "Vm Overhead State Provider"); //$NON-NLS-1$
- fModel = QemuKvmVmModel.get(experiment);
- Table<ITmfTrace, String, @Nullable Integer> table = HashBasedTable.create();
- fEventNames = table;
+ fModel = model;
+ fHandlers = ImmutableSet.of(new SchedSwitchEventHandler(this), new QemuKvmEventHandler(this));
fLayouts = new HashMap<>();
}
@@ -162,13 +165,11 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
layout = DefaultEventLayout.getInstance();
}
fLayouts.put(trace, layout);
- fEventNames.put(trace, layout.eventSchedSwitch(), SCHED_SWITCH_INDEX);
- for (String kvmEntry : layout.eventsKVMEntry()) {
- fEventNames.put(trace, kvmEntry, KVM_ENTRY_INDEX);
- }
- for (String kvmExit : layout.eventsKVMExit()) {
- fEventNames.put(trace, kvmExit, KVM_EXIT_INDEX);
- }
+ fHandlers.forEach(handler -> {
+ handler.getRequiredEvents(layout).forEach(event -> {
+ fEventNames.put(event, handler);
+ });
+ });
}
@Override
@@ -188,12 +189,11 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
@Override
public ITmfStateProvider getNewInstance() {
TmfExperiment trace = getTrace();
- return new VmOverheadStateProvider(trace);
+ return new VmOverheadStateProvider(trace, fModel);
}
@Override
protected void eventHandle(ITmfEvent event) {
-
Set<HostThread> toRemove = new HashSet<>();
fGuestThreads.entrySet().forEach(t -> {
if (!t.getValue().update(event.getTimestamp().toNanos())) {
@@ -204,7 +204,7 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
/* Is the event managed by this analysis */
final String eventName = event.getName();
- IKernelAnalysisEventLayout eventLayout = fLayouts.get(event.getTrace());
+ @Nullable IKernelAnalysisEventLayout eventLayout = fLayouts.get(event.getTrace());
if (eventLayout == null) {
buildEventNames(event.getTrace());
eventLayout = fLayouts.get(event.getTrace());
@@ -213,115 +213,32 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
}
}
- if (!eventName.equals(eventLayout.eventSchedSwitch()) &&
- !fModel.getRequiredEvents(eventLayout).contains(eventName)) {
- return;
- }
-
ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
-
- /* Have the hypervisor models handle the event first */
- fModel.handleEvent(event, eventLayout);
- // The model should have been populated by the dependent analysis, we can just use it
- VirtualMachine host = fModel.getCurrentMachine(event);
- if (host == null) {
- return;
- }
- Integer idx = fEventNames.get(event.getTrace(), eventName);
- int intval = (idx == null ? -1 : idx.intValue());
- switch (intval) {
- case SCHED_SWITCH_INDEX: // "sched_switch":
- if (host.isHost()) {
- handleHostSchedSwitch(ss, event, eventLayout);
- }
- if (host.isGuest()) {
- handleGuestSchedSwitch(ss, event, eventLayout, host);
- }
- break;
- case KVM_ENTRY_INDEX:
- handleKvmEntry(ss, event);
- break;
- case KVM_EXIT_INDEX:
- handleKvmExit(ss, event);
- break;
- default:
- // Nothing to do
- }
-
- }
-
- private void handleKvmEntry(ITmfStateSystemBuilder ss, ITmfEvent event) {
- Integer currentTid = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), LinuxTidAspect.class, event);
- if (currentTid == null || currentTid <= 0) {
+ Collection<IVirtualMachineEventHandler> handlers = fEventNames.get(eventName);
+ if (handlers.isEmpty()) {
return;
}
- HostThread ht = new HostThread(event.getTrace().getHostId(), currentTid);
- VirtualCPU vcpu = fModel.getVirtualCpu(ht);
-
- if (vcpu != null) {
- final long ts = event.getTimestamp().getValue();
- VirtualMachine vm = vcpu.getVm();
- IHostModel model = ModelManager.getModelFor(vm.getHostId());
- int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts, true);
- if (guestTid != IHostModel.UNKNOWN_TID) {
- int quark = ss.getQuarkAbsoluteAndAdd(TRACES, vm.getTraceName(), THREADS, buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()), InstrumentedCallStackAnalysis.CALL_STACK);
- // Just make sure this attribute exists, at the beginning of trace or if lost
- // events, it may not
- int tidQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_1);
- if (ss.queryOngoing(tidQuark) == null) {
- HostThread hostThread = new HostThread(event.getTrace().getHostId(), guestTid);
- createGuestThreadStatus(ss, hostThread, ts, tidQuark);
- }
- int preemptQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_2);
- ss.removeAttribute(ts, preemptQuark);
- int statusQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_3);
- ss.removeAttribute(ts, statusQuark);
- }
+ IVirtualEnvironmentModel virtEnv = fModel;
+ for (IVirtualMachineEventHandler handler : handlers) {
+ handler.handleEvent(ss, event, virtEnv, eventLayout);
}
- }
-
- private void handleKvmExit(ITmfStateSystemBuilder ss, ITmfEvent event) {
- Integer currentTid = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), LinuxTidAspect.class, event);
- if (currentTid == null || currentTid <= 0) {
- return;
- }
- HostThread ht = new HostThread(event.getTrace().getHostId(), currentTid);
- VirtualCPU vcpu = fModel.getVirtualCpu(ht);
- if (vcpu != null) {
- final long ts = event.getTimestamp().getValue();
- Long exitReason = event.getContent().getFieldValue(Long.class, FIELD_EXIT_REASON);
- VirtualMachine vm = vcpu.getVm();
- IHostModel model = ModelManager.getModelFor(vm.getHostId());
- int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts, true);
- if (guestTid != IHostModel.UNKNOWN_TID) {
- int quark = ss.getQuarkAbsoluteAndAdd(TRACES, vm.getTraceName(), THREADS, buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()), InstrumentedCallStackAnalysis.CALL_STACK);
- // Just make sure this attribute exists, at the beginning of trace or if lost
- // events, it may not
- int tidQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_1);
- if (ss.queryOngoing(tidQuark) == null) {
- HostThread hostThread = new HostThread(event.getTrace().getHostId(), guestTid);
- createGuestThreadStatus(ss, hostThread, ts, tidQuark);
- }
- int preemptQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_2);
- ss.modifyAttribute(ts, STATUS_VMM_MODE, preemptQuark);
- int statusQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_3);
- ss.modifyAttribute(ts, String.valueOf(exitReason), statusQuark);
- }
- }
- }
- private static String buildThreadAttributeName(int threadId, int cpuId) {
- if (threadId == 0) {
- if (cpuId < 0) {
- return String.valueOf(threadId);
- }
- return String.valueOf(threadId) + '_' + String.valueOf(cpuId);
- }
-
- return String.valueOf(threadId);
}
- private void createGuestThreadStatus(ITmfStateSystemBuilder ss, HostThread ht, long start, int tidQuark) {
+ /**
+ * Create a class that will provider the guest thread status values
+ *
+ * @param ss
+ * The overhead analysis state system
+ * @param ht
+ * The host thread for which to get the statuses
+ * @param start
+ * The timestamp where to start getting the statuses
+ * @param tidQuark
+ * The quark of the guest thread for which to update the status, in
+ * the overhead state system
+ */
+ public void createGuestThreadStatus(ITmfStateSystemBuilder ss, HostThread ht, long start, int tidQuark) {
IHostModel model = ModelManager.getModelFor(ht.getHost());
Iterable<ProcessStatusInterval> statuses = model.getThreadStatusIntervals(ht.getTid(), start, Long.MAX_VALUE, 1);
Iterator<ProcessStatusInterval> iterator = statuses.iterator();
@@ -332,121 +249,34 @@ public class VmOverheadStateProvider extends AbstractTmfStateProvider {
}
/**
- * For guest sched_switch, update the status of the previous and next TIDs
- * @param host
+ * Stop tracking the thread status for a process, usually when the thread is
+ * scheduled out
+ *
+ * @param ht
+ * The host thread for which to stop tracking status
*/
- private void handleGuestSchedSwitch(ITmfStateSystemBuilder ss, ITmfEvent event, IKernelAnalysisEventLayout eventLayout, VirtualMachine host) {
- final ITmfEventField content = event.getContent();
- final long ts = event.getTimestamp().getValue();
- int prevTid = ((Long) content.getField(eventLayout.fieldPrevTid()).getValue()).intValue();
- int nextTid = ((Long) content.getField(eventLayout.fieldNextTid()).getValue()).intValue();
- Object cpuObj = TmfTraceUtils.resolveEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
- int cpu = (cpuObj == null ? -1 : (Integer) cpuObj);
-
- int baseQuark = ss.getQuarkAbsoluteAndAdd(TRACES, event.getTrace().getName(), THREADS, buildThreadAttributeName(prevTid, cpu));
- // Remove host tid
- int quark = ss.getQuarkRelativeAndAdd(baseQuark, VmOverheadAnalysis.HOST_CPU_TID);
- ss.removeAttribute(ts, quark);
-
- quark = ss.getQuarkRelativeAndAdd(baseQuark, InstrumentedCallStackAnalysis.CALL_STACK);
- int tidQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_1);
- ss.removeAttribute(ts, tidQuark);
- int preemptQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_2);
- ss.removeAttribute(ts, preemptQuark);
- int statusQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_3);
- ss.removeAttribute(ts, statusQuark);
-
- fGuestThreads.remove(new HostThread(event.getTrace().getHostId(), prevTid));
-
- baseQuark = ss.getQuarkAbsoluteAndAdd(TRACES, event.getTrace().getName(), THREADS, buildThreadAttributeName(nextTid, cpu));
- if (cpuObj instanceof Integer) {
- // Find the host thread of the current cpu
- VirtualCPU virtualCPU = VirtualCPU.getVirtualCPU(host, ((Integer) cpuObj).longValue());
- HostThread vcpuTid = fModel.getVirtualCpuTid(virtualCPU);
- if (vcpuTid != null) {
- quark = ss.getQuarkRelativeAndAdd(baseQuark, VmOverheadAnalysis.HOST_CPU_TID);
- ss.modifyAttribute(ts, vcpuTid.getTid(), quark);
- }
- }
-
- quark = ss.getQuarkRelativeAndAdd(baseQuark, InstrumentedCallStackAnalysis.CALL_STACK);
- tidQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_1);
- if (ss.queryOngoing(tidQuark) == null) {
- ss.modifyAttribute(ts, STATUS_RUNNING, tidQuark);
- }
- preemptQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_2);
- ss.removeAttribute(ts, preemptQuark);
- statusQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_3);
- ss.removeAttribute(ts, statusQuark);
-
- HostThread hostThread = new HostThread(event.getTrace().getHostId(), nextTid);
- createGuestThreadStatus(ss, hostThread, ts, tidQuark);
+ public void removeGuestThreadStatus(HostThread ht) {
+ fGuestThreads.remove(ht);
}
/**
- * If the previous or next TID is one of a vcpu, update the preemption status of
- * the thread running on that CPU in the guest
+ * Method to build the thread attribute name. If the thread is 0, it will add an
+ * underscore with the CPU id after
+ *
+ * @param threadId
+ * The thread ID
+ * @param cpuId
+ * The CPU number
+ * @return The string corresponding to the thread attribute
*/
- private void handleHostSchedSwitch(ITmfStateSystemBuilder ss, ITmfEvent event, IKernelAnalysisEventLayout eventLayout) {
-
- final ITmfEventField content = event.getContent();
- final String hostId = event.getTrace().getHostId();
- final long ts = event.getTimestamp().getValue();
- int prevTid = ((Long) content.getField(eventLayout.fieldPrevTid()).getValue()).intValue();
- int nextTid = ((Long) content.getField(eventLayout.fieldNextTid()).getValue()).intValue();
- Long prevState = content.getFieldValue(Long.class, eventLayout.fieldPrevState());
-
- /* Verify if the previous thread corresponds to a virtual CPU */
- /*
- * If previous thread is virtual CPU, update status of the
- * virtual CPU to preempted
- */
- VirtualCPU vcpu = prevTid == 0 ? null : fModel.getVirtualCpu(new HostThread(hostId, prevTid));
- if (vcpu != null) {
- VirtualMachine vm = vcpu.getVm();
- IHostModel model = ModelManager.getModelFor(vm.getHostId());
- int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts, true);
- if (guestTid != IHostModel.UNKNOWN_TID) {
-
- int quark = ss.getQuarkAbsoluteAndAdd(TRACES, vm.getTraceName(), THREADS, buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()), InstrumentedCallStackAnalysis.CALL_STACK);
- // Just make sure this attribute exists, at the beginning of trace or if lost events, it may not
- ss.getQuarkRelativeAndAdd(quark, LEVEL_1);
- int preemptQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_2);
- int statusQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_3);
- // Save the previous statuses for this thread
- fPrevStatus.put(new HostThread(vm.getHostId(), guestTid), new OverheadStatus(ss.queryOngoing(preemptQuark), ss.queryOngoing(statusQuark)));
-
- // Set the overhead as vcpu preempted
- ss.modifyAttribute(ts, STATUS_VCPU_PREEMPTED, preemptQuark);
- if (prevState != null) {
- ss.modifyAttribute(ts, String.valueOf(prevState), statusQuark);
- }
+ public static String buildThreadAttributeName(int threadId, int cpuId) {
+ if (threadId == 0) {
+ if (cpuId < 0) {
+ return String.valueOf(threadId);
}
+ return String.valueOf(threadId) + '_' + String.valueOf(cpuId);
}
- vcpu = nextTid == 0 ? null : fModel.getVirtualCpu(new HostThread(hostId, nextTid));
- if (vcpu != null) {
- VirtualMachine vm = vcpu.getVm();
- IHostModel model = ModelManager.getModelFor(vm.getHostId());
- int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts);
- if (guestTid != IHostModel.UNKNOWN_TID) {
- int quark = ss.getQuarkAbsoluteAndAdd(TRACES, vm.getTraceName(), THREADS, buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()), InstrumentedCallStackAnalysis.CALL_STACK);
- int tidQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_1);
- if (ss.queryOngoing(tidQuark) == null) {
- ss.modifyAttribute(ts, STATUS_RUNNING, tidQuark);
- }
- // Reset to the previous overhead status
- int preemptQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_2);
- int statusQuark = ss.getQuarkRelativeAndAdd(quark, LEVEL_3);
- OverheadStatus overheadStatus = fPrevStatus.remove(new HostThread(vm.getHostId(), guestTid));
- if (overheadStatus == null) {
- ss.removeAttribute(ts, preemptQuark);
- ss.removeAttribute(ts, statusQuark);
- } else {
- ss.modifyAttribute(ts, overheadStatus.fLevel2, preemptQuark);
- ss.modifyAttribute(ts, overheadStatus.fLevel3, statusQuark);
- }
- }
- }
+ return String.valueOf(threadId);
}
}
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/QemuKvmEventHandler.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/QemuKvmEventHandler.java
new file mode 100644
index 00000000..5c48ce3e
--- /dev/null
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/QemuKvmEventHandler.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2018 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.handlers;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel;
+import org.eclipse.tracecompass.incubator.analysis.core.model.ModelManager;
+import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.IVirtualMachineEventHandler;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.IVirtualEnvironmentModel;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.VirtualCPU;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.VirtualMachine;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.VmOverheadStateProvider;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+
+/**
+ * Handle events coming from a qemu/kvm hypervisor
+ *
+ * @author Geneviève Bastien
+ */
+public class QemuKvmEventHandler implements IVirtualMachineEventHandler {
+
+ private static final String FIELD_EXIT_REASON = "exit_reason"; //$NON-NLS-1$
+
+ private final Map<IKernelAnalysisEventLayout, Set<String>> fRequiredEvents = new HashMap<>();
+
+ private final VmOverheadStateProvider fProvider;
+
+ /**
+ * Constructor
+ *
+ * @param provider
+ * The state provider
+ */
+ public QemuKvmEventHandler(VmOverheadStateProvider provider) {
+ fProvider = provider;
+ }
+
+ @Override
+ public Set<String> getRequiredEvents(IKernelAnalysisEventLayout layout) {
+ Set<String> events = fRequiredEvents.get(layout);
+ if (events == null) {
+ events = new HashSet<>();
+ events.addAll(layout.eventsKVMEntry());
+ events.addAll(layout.eventsKVMExit());
+ fRequiredEvents.put(layout, events);
+ }
+ return events;
+ }
+
+ /**
+ * Handle the event for a Qemu/kvm model
+ *
+ * @param ss
+ * The state system builder to fill
+ * @param event
+ * The event to handle
+ */
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event, IVirtualEnvironmentModel virtEnv, IKernelAnalysisEventLayout layout) {
+ String eventName = event.getName();
+ long ts = event.getTimestamp().toNanos();
+ if (layout.eventsKVMEntry().contains(eventName)) {
+ // The vcpu is exiting hypervisor mode
+ handleKvmEvent(ss, ts, event, virtEnv, null, null);
+ } else if (layout.eventsKVMExit().contains(eventName)) {
+ // The vcpu is entering hypervisor mode
+ Long exitReason = event.getContent().getFieldValue(Long.class, FIELD_EXIT_REASON);
+ handleKvmEvent(ss, ts, event, virtEnv, VmOverheadStateProvider.STATUS_VMM_MODE, String.valueOf(exitReason));
+ }
+ }
+
+ private void handleKvmEvent(ITmfStateSystemBuilder ss, long ts, ITmfEvent event, IVirtualEnvironmentModel virtEnv, @Nullable Object level2, @Nullable Object level3) {
+ HostThread ht = IVirtualMachineEventHandler.getCurrentHostThread(event, ts);
+ if (ht == null) {
+ return;
+ }
+ VirtualCPU vcpu = virtEnv.getVirtualCpu(event, ht);
+ if (vcpu == null) {
+ // The current thread has a vcpu configured, ignore
+ return;
+ }
+
+ VirtualMachine vm = vcpu.getVm();
+ IHostModel model = ModelManager.getModelFor(vm.getHostId());
+ int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts);
+ if (guestTid != IHostModel.UNKNOWN_TID) {
+ int quark = ss.getQuarkAbsoluteAndAdd(VmOverheadStateProvider.TRACES, vm.getTraceName(), VmOverheadStateProvider.THREADS, VmOverheadStateProvider.buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()), InstrumentedCallStackAnalysis.CALL_STACK);
+ // Just make sure this attribute exists, at the beginning of trace or if lost
+ // events, it may not
+ ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_1);
+ int tidQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_1);
+ if (ss.queryOngoing(tidQuark) == null) {
+ HostThread hostThread = new HostThread(event.getTrace().getHostId(), guestTid);
+ fProvider.createGuestThreadStatus(ss, hostThread, ts, tidQuark);
+ }
+ int preemptQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_2);
+ ss.modifyAttribute(ts, level2, preemptQuark);
+ int statusQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_3);
+ ss.modifyAttribute(ts, level3, statusQuark);
+ }
+
+ }
+
+}
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/SchedSwitchEventHandler.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/SchedSwitchEventHandler.java
new file mode 100644
index 00000000..65dac0f4
--- /dev/null
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/SchedSwitchEventHandler.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2018 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.handlers;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel;
+import org.eclipse.tracecompass.incubator.analysis.core.model.ModelManager;
+import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.IVirtualMachineEventHandler;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.IVirtualEnvironmentModel;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.VirtualCPU;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model.VirtualMachine;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.VmOverheadAnalysis;
+import org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.VmOverheadStateProvider;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
+
+/**
+ * Handle sched switches
+ *
+ * @author Geneviève Bastien
+ */
+public class SchedSwitchEventHandler implements IVirtualMachineEventHandler {
+
+ private Map<IKernelAnalysisEventLayout, Set<String>> fRequiredEvents = new HashMap<>();
+
+ private final Map<HostThread, OverheadStatus> fPrevStatus = new HashMap<>();
+
+ private final VmOverheadStateProvider fProvider;
+
+ private class OverheadStatus {
+ private final @Nullable Object fLevel2;
+ private final @Nullable Object fLevel3;
+
+ public OverheadStatus(@Nullable Object level2, @Nullable Object level3) {
+ fLevel2 = level2;
+ fLevel3 = level3;
+ }
+ }
+
+
+
+ /**
+ * Constructor
+ * @param provider The state provider running the analysis
+ */
+ public SchedSwitchEventHandler(VmOverheadStateProvider provider) {
+ fProvider = provider;
+ }
+
+ @Override
+ public Set<String> getRequiredEvents(IKernelAnalysisEventLayout layout) {
+ Set<String> events = fRequiredEvents.get(layout);
+ if (events == null) {
+ events = new HashSet<>();
+ events.add(layout.eventSchedSwitch());
+ fRequiredEvents.put(layout, events);
+ }
+ return events;
+ }
+
+ @Override
+ public void handleEvent(ITmfStateSystemBuilder ss, ITmfEvent event, IVirtualEnvironmentModel virtEnv, IKernelAnalysisEventLayout eventLayout) {
+
+ VirtualMachine currentMachine = virtEnv.getCurrentMachine(event);
+
+ /*
+ * If sched switch is from a guest, just update the status of the virtual CPU to
+ * either idle or running
+ */
+ if (currentMachine.isHost()) {
+ handleHostSchedSwitch(ss, event, virtEnv, eventLayout);
+ }
+ if (currentMachine.isGuest()) {
+ handleGuestSchedSwitch(ss, event, virtEnv, eventLayout, currentMachine);
+ }
+ }
+
+ /*
+ * If the previous or next TID is one of a vcpu, update the preemption status of
+ * the thread running on that CPU in the guest
+ */
+ private void handleHostSchedSwitch(ITmfStateSystemBuilder ss, ITmfEvent event, IVirtualEnvironmentModel virtEnv, IKernelAnalysisEventLayout eventLayout) {
+
+ final ITmfEventField content = event.getContent();
+ final String hostId = event.getTrace().getHostId();
+ final long ts = event.getTimestamp().getValue();
+ int prevTid = ((Long) content.getField(eventLayout.fieldPrevTid()).getValue()).intValue();
+ int nextTid = ((Long) content.getField(eventLayout.fieldNextTid()).getValue()).intValue();
+ Long prevState = content.getFieldValue(Long.class, eventLayout.fieldPrevState());
+
+ /* Verify if the previous thread corresponds to a virtual CPU */
+ /*
+ * If previous thread is virtual CPU, update status of the virtual CPU to
+ * preempted
+ */
+ VirtualCPU vcpu = prevTid == 0 ? null : virtEnv.getVirtualCpu(event, new HostThread(hostId, prevTid));
+ if (vcpu != null) {
+ VirtualMachine vm = vcpu.getVm();
+ IHostModel model = ModelManager.getModelFor(vm.getHostId());
+ int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts);
+ if (guestTid != IHostModel.UNKNOWN_TID) {
+
+ int quark = ss.getQuarkAbsoluteAndAdd(VmOverheadStateProvider.TRACES, vm.getTraceName(), VmOverheadStateProvider.THREADS, VmOverheadStateProvider.buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()),
+ InstrumentedCallStackAnalysis.CALL_STACK);
+ // Just make sure this attribute exists, at the beginning of trace or if lost
+ // events, it may not
+ int tidQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_1);
+ if (ss.queryOngoing(tidQuark) == null) {
+ HostThread hostThread = new HostThread(event.getTrace().getHostId(), guestTid);
+ fProvider.createGuestThreadStatus(ss, hostThread, ts, tidQuark);
+ }
+
+ int preemptQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_2);
+ int statusQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_3);
+ // Save the previous statuses for this thread
+ fPrevStatus.put(new HostThread(vm.getHostId(), guestTid), new OverheadStatus(ss.queryOngoing(preemptQuark), ss.queryOngoing(statusQuark)));
+
+ ss.modifyAttribute(ts, VmOverheadStateProvider.STATUS_VCPU_PREEMPTED, preemptQuark);
+ if (prevState != null) {
+ ss.modifyAttribute(ts, String.valueOf(prevState), statusQuark);
+ }
+
+ }
+ }
+
+ vcpu = nextTid == 0 ? null : virtEnv.getVirtualCpu(event, new HostThread(hostId, nextTid));
+ if (vcpu != null) {
+ VirtualMachine vm = vcpu.getVm();
+ IHostModel model = ModelManager.getModelFor(vm.getHostId());
+ int guestTid = model.getThreadOnCpu(vcpu.getCpuId().intValue(), ts);
+ if (guestTid != IHostModel.UNKNOWN_TID) {
+ int quark = ss.getQuarkAbsoluteAndAdd(VmOverheadStateProvider.TRACES, vm.getTraceName(), VmOverheadStateProvider.THREADS, VmOverheadStateProvider.buildThreadAttributeName(guestTid, vcpu.getCpuId().intValue()),
+ InstrumentedCallStackAnalysis.CALL_STACK);
+ int tidQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_1);
+ if (ss.queryOngoing(tidQuark) == null) {
+ ss.modifyAttribute(ts, VmOverheadStateProvider.STATUS_RUNNING, tidQuark);
+ }
+ int preemptQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_2);
+ int statusQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_3);
+ OverheadStatus overheadStatus = fPrevStatus.remove(new HostThread(vm.getHostId(), guestTid));
+ if (overheadStatus == null) {
+ ss.removeAttribute(ts, preemptQuark);
+ ss.removeAttribute(ts, statusQuark);
+ } else {
+ ss.modifyAttribute(ts, overheadStatus.fLevel2, preemptQuark);
+ ss.modifyAttribute(ts, overheadStatus.fLevel3, statusQuark);
+ }
+ }
+ }
+ }
+
+ private void handleGuestSchedSwitch(ITmfStateSystemBuilder ss, ITmfEvent event, IVirtualEnvironmentModel virtEnv, IKernelAnalysisEventLayout eventLayout, VirtualMachine host) {
+ final ITmfEventField content = event.getContent();
+ final long ts = event.getTimestamp().getValue();
+ int prevTid = ((Long) content.getField(eventLayout.fieldPrevTid()).getValue()).intValue();
+ int nextTid = ((Long) content.getField(eventLayout.fieldNextTid()).getValue()).intValue();
+ Object cpuObj = TmfTraceUtils.resolveEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
+ int cpu = (cpuObj == null ? -1 : (Integer) cpuObj);
+
+ // Handle the process being scheduled out
+ int baseQuark = ss.getQuarkAbsoluteAndAdd(VmOverheadStateProvider.TRACES, event.getTrace().getName(), VmOverheadStateProvider.THREADS, VmOverheadStateProvider.buildThreadAttributeName(prevTid, cpu));
+ // Remove host tid running the previous thread
+ int quark = ss.getQuarkRelativeAndAdd(baseQuark, VmOverheadAnalysis.HOST_CPU_TID);
+ ss.removeAttribute(ts, quark);
+
+ // The thread is not running anymore, remove all stack
+ quark = ss.getQuarkRelativeAndAdd(baseQuark, InstrumentedCallStackAnalysis.CALL_STACK);
+ int tidQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_1);
+ ss.removeAttribute(ts, tidQuark);
+ int preemptQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_2);
+ ss.removeAttribute(ts, preemptQuark);
+ int statusQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_3);
+ ss.removeAttribute(ts, statusQuark);
+
+ // Stop handling the guest thread status for previous thread
+ fProvider.removeGuestThreadStatus(new HostThread(event.getTrace().getHostId(), prevTid));
+
+ // Handle the next thread
+ baseQuark = ss.getQuarkAbsoluteAndAdd(VmOverheadStateProvider.TRACES, event.getTrace().getName(), VmOverheadStateProvider.THREADS, VmOverheadStateProvider.buildThreadAttributeName(nextTid, cpu));
+ if (cpu >= 0) {
+ // Find the host thread of the current cpu and set it as host thread
+ VirtualCPU virtualCPU = VirtualCPU.getVirtualCPU(host, Long.valueOf(cpu));
+ HostThread vcpuTid = virtEnv.getVirtualCpuTid(virtualCPU);
+ if (vcpuTid != null) {
+ quark = ss.getQuarkRelativeAndAdd(baseQuark, VmOverheadAnalysis.HOST_CPU_TID);
+ ss.modifyAttribute(ts, vcpuTid.getTid(), quark);
+ }
+ }
+
+ quark = ss.getQuarkRelativeAndAdd(baseQuark, InstrumentedCallStackAnalysis.CALL_STACK);
+ tidQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_1);
+ if (ss.queryOngoing(tidQuark) == null) {
+ ss.modifyAttribute(ts, VmOverheadStateProvider.STATUS_RUNNING, tidQuark);
+ }
+ preemptQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_2);
+ ss.removeAttribute(ts, preemptQuark);
+ statusQuark = ss.getQuarkRelativeAndAdd(quark, VmOverheadStateProvider.LEVEL_3);
+ ss.removeAttribute(ts, statusQuark);
+
+ // Create the iterator to update guest thread statuses
+ HostThread hostThread = new HostThread(event.getTrace().getHostId(), nextTid);
+ fProvider.createGuestThreadStatus(ss, hostThread, ts, tidQuark);
+
+ }
+
+}
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/package-info.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/package-info.java
new file mode 100644
index 00000000..10456a1f
--- /dev/null
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/overhead/handlers/package-info.java
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2018 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.overhead.handlers; \ No newline at end of file
diff --git a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/virtual/resources/VirtualResourcesStateProvider.java b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/virtual/resources/VirtualResourcesStateProvider.java
index 1780f464..ba08ea70 100644
--- a/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/virtual/resources/VirtualResourcesStateProvider.java
+++ b/vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/virtual/resources/VirtualResourcesStateProvider.java
@@ -154,7 +154,6 @@ public class VirtualResourcesStateProvider extends AbstractTmfStateProvider {
ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
-
Collection<IVirtualMachineEventHandler> handlers = fEventNames.get(eventName);
if (handlers.isEmpty()) {
return;

Back to the top