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