linux.core: Add messages to IllegalStateExceptions
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.core / src / org / eclipse / tracecompass / analysis / os / linux / core / contextswitch / KernelContextSwitchAnalysis.java
CommitLineData
0c85f6f2
ACL
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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 * Alexis Cabana-Loriaux - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.analysis.os.linux.core.contextswitch;
14
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
17import java.util.Collections;
18import java.util.HashMap;
19import java.util.HashSet;
20import java.util.List;
21import java.util.Map;
22import java.util.Set;
23
24import org.eclipse.jdt.annotation.NonNull;
25import org.eclipse.jdt.annotation.NonNullByDefault;
26import org.eclipse.jdt.annotation.Nullable;
0f7a12d3 27import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
aa38ac17 28import org.eclipse.tracecompass.analysis.os.linux.core.trace.DefaultEventLayout;
0c85f6f2
ACL
29import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
30import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
31import org.eclipse.tracecompass.internal.analysis.os.linux.core.Activator;
f69045e2 32import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
0c85f6f2
ACL
33import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
34import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
35import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
36import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
37import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
38import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
39import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
40import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
41import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
42import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
43import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
44
45/**
46 * This analysis module computes the number of context switches of a system from
47 * a kernel trace.
48 *
49 * @author Alexis Cabana-Loriaux
50 * @since 2.0
51 */
52@NonNullByDefault
53public class KernelContextSwitchAnalysis extends TmfStateSystemAnalysisModule {
54
55 /** The ID of this analysis */
56 public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.contextswitch"; //$NON-NLS-1$
57
58 /** Integer used to identify 'total' entries in the returned maps */
59 public static final Integer TOTAL = -1;
60
61 @Override
62 protected ITmfStateProvider createStateProvider() {
63 ITmfTrace trace = checkNotNull(getTrace());
64 IKernelAnalysisEventLayout layout;
65
66 if (trace instanceof IKernelTrace) {
67 layout = ((IKernelTrace) trace).getKernelEventLayout();
68 } else {
69 /* Fall-back to the base LttngEventLayout */
aa38ac17 70 layout = DefaultEventLayout.getInstance();
0c85f6f2
ACL
71 }
72
73 return new KernelContextSwitchStateProvider(trace, layout);
74 }
75
76 @Override
77 protected StateSystemBackendType getBackendType() {
78 return StateSystemBackendType.FULL;
79 }
80
81 @Override
82 protected Iterable<IAnalysisModule> getDependentAnalyses() {
83 Set<IAnalysisModule> modules = new HashSet<>();
84
85 ITmfTrace trace = getTrace();
86 if (trace == null) {
878d6a0e 87 throw new IllegalStateException("Analysis requires a trace"); //$NON-NLS-1$
0c85f6f2
ACL
88 }
89 /*
90 * This analysis depends on the LTTng kernel analysis, so it's added to
91 * dependent modules.
92 */
93 Iterable<KernelAnalysisModule> kernelModules = TmfTraceUtils.getAnalysisModulesOfClass(trace, KernelAnalysisModule.class);
94 for (KernelAnalysisModule kernelModule : kernelModules) {
95 /* Only add the first one we find, if there is one */
96 modules.add(kernelModule);
97 break;
98 }
99 return modules;
100 }
101
102 /**
103 * Get a map of the number of context switch per CPU during a time range.
104 *
105 * @param startParam
106 * Start time of requested range
107 * @param endParam
108 * End time of requested range
109 * @return A map of CPU# -> nb of context switch in the [start, end]
110 * interval. CPU# == -1 represents the total number of context
111 * switch
112 * @throws TimeRangeException
113 * if one or more of the parameters is outside the range the
114 * state history
115 */
116 public @NonNullByDefault({}) @NonNull Map<Integer, Long> getContextSwitchesRange(final long startParam, final long endParam) {
117 final @Nullable ITmfStateSystem stateSystem = getStateSystem();
118 ITmfTrace trace = getTrace();
119 if (trace == null || stateSystem == null) {
120 return Collections.<Integer, Long> emptyMap();
121 }
122 long start = Math.max(startParam, stateSystem.getStartTime());
123 long end = Math.min(endParam, stateSystem.getCurrentEndTime());
124 ITmfStateSystem contextSwitchStateSystem = TmfStateSystemAnalysisModule.getStateSystem(trace, KernelContextSwitchAnalysis.ID);
125 if (contextSwitchStateSystem == null) {
126 return Collections.<Integer, Long> emptyMap();
127 }
128
129 /*
130 * Make sure the start/end times are within the state history, so we
131 * don't get TimeRange exceptions.
132 */
133 long startTime = contextSwitchStateSystem.getStartTime();
134 long endTime = contextSwitchStateSystem.getCurrentEndTime();
135 if (endTime < startTime) {
136 return Collections.<Integer, Long> emptyMap();
137 }
138
139 Map<Integer, Long> map = new HashMap<>();
140 try {
141 /* Get the list of quarks for each CPU */
142 int cpusNode = contextSwitchStateSystem.getQuarkAbsolute(Attributes.CPUS);
143 List<Integer> cpuQuarks = contextSwitchStateSystem.getSubAttributes(cpusNode, false);
144 /* Query full states at start and end times */
145 List<ITmfStateInterval> kernelEndState = contextSwitchStateSystem.queryFullState(end);
146 List<ITmfStateInterval> kernelStartState = contextSwitchStateSystem.queryFullState(start);
147 Long totalNbCxtSwt = 0l;
148 for (Integer cpuQuark : cpuQuarks) {
149 int cpuNb = Integer.parseInt(contextSwitchStateSystem.getAttributeName(cpuQuark.intValue()));
150 Long nbCxtSwtForCore = kernelEndState.get(cpuQuark).getStateValue().unboxLong() - kernelStartState.get(cpuQuark).getStateValue().unboxLong();
151 map.put(cpuNb, nbCxtSwtForCore);
152 totalNbCxtSwt += nbCxtSwtForCore;
153 }
154
155 /* Put the total number of context switches in the interval */
156 map.put(TOTAL, totalNbCxtSwt);
157 } catch (TimeRangeException | AttributeNotFoundException e) {
158 /*
159 * Assume there is no events or the attribute does not exist yet,
160 * nothing will be put in the map.
161 */
162 } catch (StateValueTypeException | StateSystemDisposedException e) {
163 /*
164 * These other exception types would show a logic problem, so they
165 * should not happen.
166 */
167 Activator.getDefault().logError("Error getting CPU context switches in a time range", e); //$NON-NLS-1$
168 }
169
170 return map;
171 }
172
173}
This page took 0.035669 seconds and 5 git commands to generate.