tmf: Add unit tests for PeriodicMarkerEventSource
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.kernel.core / src / org / eclipse / tracecompass / internal / lttng2 / kernel / core / analysis / vm / module / VirtualMachineCpuAnalysis.java
CommitLineData
4a74f111 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2014, 2015 École Polytechnique de Montréal
4a74f111
MG
3 *
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 *
9 * Contributors:
10 * Mohamad Gebai - Initial API and implementation
11 * Geneviève Bastien - Initial API and implementation
12 *******************************************************************************/
13
14package org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.vm.module;
15
1d83ed07
AM
16import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
4a74f111
MG
18import java.util.Comparator;
19import java.util.HashSet;
20import java.util.Set;
21
22import org.eclipse.core.runtime.IProgressMonitor;
23import org.eclipse.jdt.annotation.NonNull;
6d16f5a9 24import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysisModule;
e363eae1 25import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelThreadInformationProvider;
4a74f111
MG
26import org.eclipse.tracecompass.common.core.NonNullUtils;
27import org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.vm.VcpuStateValues;
28import org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.vm.VmAttributes;
4a74f111
MG
29import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
30import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
31import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
32import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
33import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
34import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
35import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
36import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
37import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
38import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
39import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
40import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
41import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
42import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
43import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
44import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperimentUtils;
45
46import com.google.common.collect.ImmutableSet;
47import com.google.common.collect.Multimap;
48import com.google.common.collect.TreeMultimap;
49
50/**
51 * Module for the virtual machine CPU analysis. It tracks the status of the
52 * virtual CPUs for each guest of the experiment.
53 *
54 * @author Mohamad Gebai
55 * @author Geneviève Bastien
56 */
57public class VirtualMachineCpuAnalysis extends TmfStateSystemAnalysisModule {
58
b1a7aebb
MG
59 /** The ID of this analysis module */
60 public static final String ID = "org.eclipse.tracecompass.lttng2.analysis.vm.core.VirtualMachineAnalysisModule"; //$NON-NLS-1$
61
4a74f111 62 // TODO: Update with event layout when requirements are back */
df2597e0 63 static final Set<String> REQUIRED_EVENTS = NonNullUtils.checkNotNull(ImmutableSet.of(
4a74f111
MG
64 // LttngStrings.SCHED_SWITCH
65 ));
66
67 /* State value for a preempted virtual CPU */
68 private static final ITmfStateValue VCPU_PREEMPT_VALUE = TmfStateValue.newValueInt(VcpuStateValues.VCPU_PREEMPT);
69
70 /**
71 * Constructor
72 */
73 public VirtualMachineCpuAnalysis() {
74 super();
75 }
76
77 @Override
78 protected ITmfStateProvider createStateProvider() {
79 ITmfTrace trace = getTrace();
80 if (!(trace instanceof TmfExperiment)) {
81 throw new IllegalStateException();
82 }
83 return new VirtualMachineStateProvider((TmfExperiment) trace);
84 }
85
86 @Override
87 protected @NonNull StateSystemBackendType getBackendType() {
88 return StateSystemBackendType.FULL;
89 }
90
91 @Override
92 public String getHelpText() {
93 return Messages.getMessage(Messages.VirtualMachineCPUAnalysis_Help);
94 }
95
96 @Override
97 protected Iterable<IAnalysisModule> getDependentAnalyses() {
98 Set<IAnalysisModule> modules = new HashSet<>();
99 /* Depends on the LTTng Kernel analysis modules */
100 for (ITmfTrace trace : TmfTraceManager.getTraceSet(getTrace())) {
1d83ed07 101 trace = checkNotNull(trace);
6d16f5a9 102 for (KernelAnalysisModule module : TmfTraceUtils.getAnalysisModulesOfClass(trace, KernelAnalysisModule.class)) {
4a74f111
MG
103 modules.add(module);
104 }
105 }
106 return modules;
107 }
108
109 private static Multimap<Integer, ITmfStateInterval> createThreadMultimap() {
110
111 /*
112 * Create the multimap for threads with the appropriate comparator
113 * objects for keys and values
114 */
722d5c71
AM
115 final Multimap<Integer, ITmfStateInterval> map = TreeMultimap.create(
116 /* Key comparator. Keys do not have to be sorted, just use natural sorting*/
117 Comparator.naturalOrder(),
118
119 /* Value comparator */
120 (arg0, arg1) -> {
121 if (arg1.getStateValue() == VCPU_PREEMPT_VALUE && arg0.getStateValue() != VCPU_PREEMPT_VALUE) {
4a74f111 122 /*
722d5c71
AM
123 * For VCPU_PREEMPT state values, the state has to be
124 * after any other state that it overlaps, because those
125 * intervals usually decorate the other intervals.
4a74f111 126 */
722d5c71 127 if (((Long) arg0.getEndTime()).compareTo(arg1.getStartTime()) < 0) {
4a74f111
MG
128 return -1;
129 }
722d5c71 130 return ((Long) arg0.getStartTime()).compareTo(arg1.getEndTime());
4a74f111 131 }
722d5c71
AM
132 /* Otherwise, we use ordering by start time */
133 return (((Long) arg0.getStartTime()).compareTo(arg1.getStartTime()));
134 });
4a74f111
MG
135 return map;
136 }
137
138 /**
139 * Get the status intervals for the threads from a virtual machine. Those
140 * intervals are correlated with the data from the virtual CPU's preemption
141 * status.
142 *
143 * This method uses the Linux Kernel Analysis data for the thread's status
144 * intervals.
145 *
146 * @param vmQuark
147 * The quark of the virtual machine
148 * @param start
149 * The start time of the period to get the intervals from
150 * @param end
151 * The end time of the period to get the intervals from
152 * @param resolution
153 * The resolution
154 * @param monitor
155 * A progress monitor for this task
156 * @return A map of status intervals for the machine's threads, including
157 * preempted intervals. Intervals from the thread status and the CPU
158 * preemption status overlap and are ordered such that CPU
159 * preemption intervals are after any interval they overlap with
160 */
161 public Multimap<Integer, ITmfStateInterval> getUpdatedThreadIntervals(int vmQuark, long start, long end, long resolution, IProgressMonitor monitor) {
162
163 final Multimap<Integer, ITmfStateInterval> map = createThreadMultimap();
164
165 ITmfStateSystem ss = getStateSystem();
166 if (ss == null) {
167 return map;
168 }
169 ITmfTrace trace = getTrace();
170 if (!(trace instanceof TmfExperiment)) {
171 return map;
172 }
173
174 String vmHostId = NonNullUtils.checkNotNull(ss.getAttributeName(vmQuark));
6d16f5a9 175 KernelAnalysisModule kernelModule = TmfExperimentUtils.getAnalysisModuleOfClassForHost((TmfExperiment) trace, vmHostId, KernelAnalysisModule.class);
4a74f111
MG
176 if (kernelModule == null) {
177 return map;
178 }
179
180 /*
181 * Initialize the map with the original status intervals from the kernel
182 * module
183 */
e363eae1 184 for (Integer tid : KernelThreadInformationProvider.getThreadIds(kernelModule)) {
e363eae1 185 map.putAll(tid, KernelThreadInformationProvider.getStatusIntervalsForThread(kernelModule, tid, start, end, resolution, monitor));
4a74f111
MG
186 if (monitor.isCanceled()) {
187 return map;
188 }
189 }
190
191 try {
192 /* Correlate thread information with virtual CPU information */
193 for (Integer vcpuQuark : ss.getSubAttributes(vmQuark, false)) {
194 Long virtualCPU = Long.parseLong(ss.getAttributeName(vcpuQuark));
195 Integer statusQuark = ss.getQuarkRelative(vcpuQuark, VmAttributes.STATUS);
196
197 for (ITmfStateInterval cpuInterval : StateSystemUtils.queryHistoryRange(ss, statusQuark, start, end - 1, resolution, monitor)) {
198 ITmfStateValue stateValue = cpuInterval.getStateValue();
199 switch (stateValue.getType()) {
200 case INTEGER:
201 int value = stateValue.unboxInt();
202 /*
203 * If the current CPU is either preempted or in
204 * hypervisor mode, add preempted intervals to running
205 * processes
206 */
207 if ((value & (VcpuStateValues.VCPU_PREEMPT | VcpuStateValues.VCPU_VMM)) == 0) {
208 break;
209 }
e363eae1 210 Integer threadOnCpu = KernelThreadInformationProvider.getThreadOnCpu(kernelModule, virtualCPU, cpuInterval.getStartTime());
4a74f111
MG
211 if (threadOnCpu != null) {
212 map.put(threadOnCpu, new TmfStateInterval(cpuInterval.getStartTime(), cpuInterval.getEndTime(), threadOnCpu, VCPU_PREEMPT_VALUE));
213 }
214 break;
215 case DOUBLE:
216 case LONG:
217 case NULL:
218 case STRING:
219 default:
220 break;
221 }
222
223 }
224 }
225 } catch (AttributeNotFoundException | StateSystemDisposedException e) {
226 }
227 return NonNullUtils.checkNotNull(map);
228 }
229
230}
This page took 0.053691 seconds and 5 git commands to generate.