analysis: let the soft irq raised state appear in the Resources view
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.ui / src / org / eclipse / tracecompass / internal / analysis / os / linux / ui / views / resources / ResourcesPresentationProvider.java
CommitLineData
dedc7dec 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
dedc7dec
PT
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 * Patrick Tasse - Initial API and implementation
4999a196 11 * Geneviève Bastien - Move code to provide base classes for time graph view
dedc7dec
PT
12 *******************************************************************************/
13
eeff806b 14package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources;
dedc7dec
PT
15
16import java.util.LinkedHashMap;
17import java.util.List;
18import java.util.Map;
19
713a70ae 20import org.eclipse.swt.SWT;
5bf0ab10 21import org.eclipse.swt.graphics.Color;
713a70ae 22import org.eclipse.swt.graphics.GC;
dedc7dec 23import org.eclipse.swt.graphics.RGB;
713a70ae 24import org.eclipse.swt.graphics.Rectangle;
0f7a12d3
AM
25import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
26import org.eclipse.tracecompass.analysis.os.linux.core.kernel.StateValues;
e363eae1
AM
27import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
28import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
f69045e2 29import org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.Attributes;
e363eae1
AM
30import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
31import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
eeff806b 32import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.resources.ResourcesEntry.Type;
e894a508
AM
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.statesystem.core.statevalue.ITmfStateValue;
2bdf0193 40import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
acba092b 41import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
2bdf0193
AM
42import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
43import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
44import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
45import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
46import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
47import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
48import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITmfTimeGraphDrawingHelper;
49import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
50import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
51import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
dedc7dec
PT
52
53/**
54 * Presentation provider for the Resource view, based on the generic TMF
55 * presentation provider.
56 *
57 * @author Patrick Tasse
58 */
59public class ResourcesPresentationProvider extends TimeGraphPresentationProvider {
60
4999a196 61 private long fLastThreadId = -1;
5bf0ab10
MAL
62 private Color fColorWhite;
63 private Color fColorGray;
64 private Integer fAverageCharWidth;
713a70ae 65
dedc7dec 66 private enum State {
4999a196 67 IDLE (new RGB(200, 200, 200)),
1d46dc38
PT
68 USERMODE (new RGB( 0, 200, 0)),
69 SYSCALL (new RGB( 0, 0, 200)),
4999a196
GB
70 IRQ (new RGB(200, 0, 100)),
71 SOFT_IRQ (new RGB(200, 150, 100)),
72 IRQ_ACTIVE (new RGB(200, 0, 100)),
1d46dc38 73 SOFT_IRQ_RAISED (new RGB(200, 200, 0)),
4999a196 74 SOFT_IRQ_ACTIVE (new RGB(200, 150, 100));
dedc7dec
PT
75
76 public final RGB rgb;
77
4999a196 78 private State(RGB rgb) {
dedc7dec
PT
79 this.rgb = rgb;
80 }
81 }
82
713a70ae
PT
83 /**
84 * Default constructor
713a70ae 85 */
4999a196 86 public ResourcesPresentationProvider() {
713a70ae 87 super();
713a70ae
PT
88 }
89
4999a196
GB
90 private static State[] getStateValues() {
91 return State.values();
dedc7dec
PT
92 }
93
1d46dc38
PT
94 private static State getEventState(TimeEvent event) {
95 if (event.hasValue()) {
4999a196 96 ResourcesEntry entry = (ResourcesEntry) event.getEntry();
1d46dc38 97 int value = event.getValue();
4999a196
GB
98
99 if (entry.getType() == Type.CPU) {
100 if (value == StateValues.CPU_STATUS_IDLE) {
101 return State.IDLE;
102 } else if (value == StateValues.CPU_STATUS_RUN_USERMODE) {
103 return State.USERMODE;
104 } else if (value == StateValues.CPU_STATUS_RUN_SYSCALL) {
105 return State.SYSCALL;
106 } else if (value == StateValues.CPU_STATUS_IRQ) {
107 return State.IRQ;
108 } else if (value == StateValues.CPU_STATUS_SOFTIRQ) {
109 return State.SOFT_IRQ;
08aa7eb2
CB
110 } else if (value == StateValues.CPU_STATUS_SOFT_IRQ_RAISED) {
111 return State.SOFT_IRQ_RAISED;
4999a196 112 }
1d46dc38 113 } else if (entry.getType() == Type.IRQ) {
4999a196 114 return State.IRQ_ACTIVE;
1d46dc38 115 } else if (entry.getType() == Type.SOFT_IRQ) {
8140841e 116 if (value == StateValues.CPU_STATUS_SOFT_IRQ_RAISED) {
4999a196
GB
117 return State.SOFT_IRQ_RAISED;
118 }
119 return State.SOFT_IRQ_ACTIVE;
120 }
dedc7dec 121 }
4999a196 122 return null;
dedc7dec
PT
123 }
124
125 @Override
126 public int getStateTableIndex(ITimeEvent event) {
1d46dc38 127 State state = getEventState((TimeEvent) event);
4999a196
GB
128 if (state != null) {
129 return state.ordinal();
130 }
1d46dc38
PT
131 if (event instanceof NullTimeEvent) {
132 return INVISIBLE;
dedc7dec 133 }
af10fe06 134 return TRANSPARENT;
dedc7dec
PT
135 }
136
4999a196
GB
137 @Override
138 public StateItem[] getStateTable() {
139 State[] states = getStateValues();
140 StateItem[] stateTable = new StateItem[states.length];
141 for (int i = 0; i < stateTable.length; i++) {
142 State state = states[i];
143 stateTable[i] = new StateItem(state.rgb, state.toString());
144 }
145 return stateTable;
146 }
147
dedc7dec
PT
148 @Override
149 public String getEventName(ITimeEvent event) {
1d46dc38 150 State state = getEventState((TimeEvent) event);
4999a196
GB
151 if (state != null) {
152 return state.toString();
153 }
1d46dc38
PT
154 if (event instanceof NullTimeEvent) {
155 return null;
dedc7dec 156 }
af10fe06 157 return Messages.ResourcesView_multipleStates;
dedc7dec
PT
158 }
159
160 @Override
161 public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) {
162
e0838ca1 163 Map<String, String> retMap = new LinkedHashMap<>();
4999a196 164 if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
dedc7dec 165
4999a196
GB
166 TimeEvent tcEvent = (TimeEvent) event;
167 ResourcesEntry entry = (ResourcesEntry) event.getEntry();
dedc7dec 168
4999a196 169 if (tcEvent.hasValue()) {
6d16f5a9 170 ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
4bc53929
GB
171 if (ss == null) {
172 return retMap;
173 }
4999a196
GB
174 // Check for IRQ or Soft_IRQ type
175 if (entry.getType().equals(Type.IRQ) || entry.getType().equals(Type.SOFT_IRQ)) {
dedc7dec 176
4999a196
GB
177 // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
178 int cpu = tcEvent.getValue();
179 if (cpu >= 0) {
180 retMap.put(Messages.ResourcesView_attributeCpuName, String.valueOf(cpu));
181 }
dedc7dec 182 }
dedc7dec 183
4999a196
GB
184 // Check for type CPU
185 else if (entry.getType().equals(Type.CPU)) {
186 int status = tcEvent.getValue();
187
188 if (status == StateValues.CPU_STATUS_IRQ) {
189 // In IRQ state get the IRQ that caused the interruption
4999a196
GB
190 int cpu = entry.getId();
191
192 try {
193 List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
19ed6598 194 List<Integer> irqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.IRQS, "*"); //$NON-NLS-1$
4999a196
GB
195
196 for (int irqQuark : irqQuarks) {
631d47f1
LPD
197 ITmfStateInterval value = fullState.get(irqQuark);
198 if (!value.getStateValue().isNull()) {
199 String irq = ss.getAttributeName(irqQuark);
200 retMap.put(Messages.ResourcesView_attributeIrqName, irq);
4999a196 201 break;
dedc7dec 202 }
dedc7dec 203 }
631d47f1 204 } catch (TimeRangeException | StateValueTypeException e) {
4bc53929 205 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
206 } catch (StateSystemDisposedException e) {
207 /* Ignored */
dedc7dec 208 }
4999a196
GB
209 } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
210 // In SOFT_IRQ state get the SOFT_IRQ that caused the interruption
4999a196
GB
211 int cpu = entry.getId();
212
213 try {
214 List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
19ed6598 215 List<Integer> softIrqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
4999a196
GB
216
217 for (int softIrqQuark : softIrqQuarks) {
631d47f1
LPD
218 ITmfStateInterval value = fullState.get(softIrqQuark);
219 if (!value.getStateValue().isNull()) {
220 String softIrq = ss.getAttributeName(softIrqQuark);
221 retMap.put(Messages.ResourcesView_attributeSoftIrqName, softIrq);
4999a196 222 break;
dedc7dec 223 }
dedc7dec 224 }
631d47f1 225 } catch (TimeRangeException | StateValueTypeException e) {
4bc53929 226 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
227 } catch (StateSystemDisposedException e) {
228 /* Ignored */
dedc7dec 229 }
4999a196
GB
230 } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL) {
231 // In running state get the current tid
4999a196
GB
232
233 try {
234 retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
235 int cpuQuark = entry.getQuark();
4bc53929
GB
236 int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
237 ITmfStateInterval interval = ss.querySingleState(hoverTime, currentThreadQuark);
dedc7dec 238 if (!interval.getStateValue().isNull()) {
4999a196
GB
239 ITmfStateValue value = interval.getStateValue();
240 int currentThreadId = value.unboxInt();
241 retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
4bc53929
GB
242 int execNameQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
243 interval = ss.querySingleState(hoverTime, execNameQuark);
dedc7dec
PT
244 if (!interval.getStateValue().isNull()) {
245 value = interval.getStateValue();
4999a196
GB
246 retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
247 }
248 if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
fd7961ac
LPD
249 int syscallQuark = ss.optQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
250 if (syscallQuark == ITmfStateSystem.INVALID_ATTRIBUTE) {
251 return retMap;
252 }
4bc53929 253 interval = ss.querySingleState(hoverTime, syscallQuark);
4999a196
GB
254 if (!interval.getStateValue().isNull()) {
255 value = interval.getStateValue();
256 retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
257 }
dedc7dec
PT
258 }
259 }
4bc53929
GB
260 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
261 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
262 } catch (StateSystemDisposedException e) {
263 /* Ignored */
dedc7dec 264 }
dedc7dec 265 }
96345c5a 266 }
dedc7dec
PT
267 }
268 }
269
270 return retMap;
271 }
272
713a70ae
PT
273 @Override
274 public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
5bf0ab10
MAL
275 if (fColorGray == null) {
276 fColorGray = gc.getDevice().getSystemColor(SWT.COLOR_GRAY);
277 }
278 if (fColorWhite == null) {
279 fColorWhite = gc.getDevice().getSystemColor(SWT.COLOR_WHITE);
280 }
281 if (fAverageCharWidth == null) {
282 fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth();
283 }
284
4999a196 285 ITmfTimeGraphDrawingHelper drawingHelper = getDrawingHelper();
5bf0ab10 286 if (bounds.width <= fAverageCharWidth) {
713a70ae
PT
287 return;
288 }
4999a196
GB
289
290 if (!(event instanceof TimeEvent)) {
713a70ae
PT
291 return;
292 }
4999a196
GB
293 TimeEvent tcEvent = (TimeEvent) event;
294 if (!tcEvent.hasValue()) {
713a70ae
PT
295 return;
296 }
4999a196
GB
297
298 ResourcesEntry entry = (ResourcesEntry) event.getEntry();
299 if (!entry.getType().equals(Type.CPU)) {
300 return;
301 }
302
303 int status = tcEvent.getValue();
713a70ae
PT
304 if (status != StateValues.CPU_STATUS_RUN_USERMODE && status != StateValues.CPU_STATUS_RUN_SYSCALL) {
305 return;
306 }
4999a196 307
6d16f5a9 308 ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
4bc53929
GB
309 if (ss == null) {
310 return;
311 }
713a70ae 312 long time = event.getTime();
a3fbd3f4
PT
313 try {
314 while (time < event.getTime() + event.getDuration()) {
713a70ae
PT
315 int cpuQuark = entry.getQuark();
316 int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
317 ITmfStateInterval tidInterval = ss.querySingleState(time, currentThreadQuark);
1b26cb91
PT
318 long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
319 int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
320 if (x >= bounds.x + bounds.width) {
321 break;
322 }
713a70ae
PT
323 if (!tidInterval.getStateValue().isNull()) {
324 ITmfStateValue value = tidInterval.getStateValue();
325 int currentThreadId = value.unboxInt();
1b26cb91
PT
326 long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
327 int xForEndTime = drawingHelper.getXForTime(endTime);
328 if (xForEndTime > bounds.x) {
329 int width = Math.min(xForEndTime, bounds.x + bounds.width) - x - 1;
330 if (width > 0) {
331 String attribute = null;
332 int beginIndex = 0;
333 if (status == StateValues.CPU_STATUS_RUN_USERMODE && currentThreadId != fLastThreadId) {
334 attribute = Attributes.EXEC_NAME;
335 } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
336 attribute = Attributes.SYSTEM_CALL;
acba092b
AM
337 /*
338 * Remove the "sys_" or "syscall_entry_" or similar from what we
339 * draw in the rectangle. This depends on the trace's event layout.
340 */
341 ITmfTrace trace = entry.getTrace();
e363eae1
AM
342 if (trace instanceof IKernelTrace) {
343 IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout();
acba092b
AM
344 beginIndex = layout.eventSyscallEntryPrefix().length();
345 }
1b26cb91
PT
346 }
347 if (attribute != null) {
fd7961ac
LPD
348 int quark = ss.optQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), attribute);
349 if (quark == ITmfStateSystem.INVALID_ATTRIBUTE) {
350 return;
351 }
1b26cb91 352 ITmfStateInterval interval = ss.querySingleState(time, quark);
5bf0ab10
MAL
353 if (!interval.getStateValue().isNull()) {
354 value = interval.getStateValue();
355 gc.setForeground(fColorWhite);
3bd20aa6 356 int drawn = Utils.drawText(gc, value.unboxStr().substring(beginIndex), x + 1, bounds.y, width, bounds.height, true, true);
38f7712b 357 if (drawn > 0 && status == StateValues.CPU_STATUS_RUN_USERMODE) {
5bf0ab10
MAL
358 fLastThreadId = currentThreadId;
359 }
713a70ae
PT
360 }
361 }
1b26cb91
PT
362 if (xForEndTime < bounds.x + bounds.width) {
363 gc.setForeground(fColorGray);
364 gc.drawLine(xForEndTime, bounds.y + 1, xForEndTime, bounds.y + bounds.height - 2);
713a70ae
PT
365 }
366 }
367 }
368 }
1b26cb91
PT
369 // make sure next time is at least at the next pixel
370 time = Math.max(tidInterval.getEndTime() + 1, drawingHelper.getTimeAtX(x + 1));
713a70ae 371 }
4bc53929
GB
372 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
373 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
a3fbd3f4
PT
374 } catch (StateSystemDisposedException e) {
375 /* Ignored */
713a70ae
PT
376 }
377 }
378
379 @Override
380 public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) {
381 fLastThreadId = -1;
382 }
dedc7dec 383}
This page took 0.096361 seconds and 5 git commands to generate.