releng: Update staging target to Oxygen
[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;
110 }
1d46dc38 111 } else if (entry.getType() == Type.IRQ) {
4999a196 112 return State.IRQ_ACTIVE;
1d46dc38 113 } else if (entry.getType() == Type.SOFT_IRQ) {
8140841e 114 if (value == StateValues.CPU_STATUS_SOFT_IRQ_RAISED) {
4999a196
GB
115 return State.SOFT_IRQ_RAISED;
116 }
117 return State.SOFT_IRQ_ACTIVE;
118 }
dedc7dec 119 }
4999a196 120 return null;
dedc7dec
PT
121 }
122
123 @Override
124 public int getStateTableIndex(ITimeEvent event) {
1d46dc38 125 State state = getEventState((TimeEvent) event);
4999a196
GB
126 if (state != null) {
127 return state.ordinal();
128 }
1d46dc38
PT
129 if (event instanceof NullTimeEvent) {
130 return INVISIBLE;
dedc7dec 131 }
af10fe06 132 return TRANSPARENT;
dedc7dec
PT
133 }
134
4999a196
GB
135 @Override
136 public StateItem[] getStateTable() {
137 State[] states = getStateValues();
138 StateItem[] stateTable = new StateItem[states.length];
139 for (int i = 0; i < stateTable.length; i++) {
140 State state = states[i];
141 stateTable[i] = new StateItem(state.rgb, state.toString());
142 }
143 return stateTable;
144 }
145
dedc7dec
PT
146 @Override
147 public String getEventName(ITimeEvent event) {
1d46dc38 148 State state = getEventState((TimeEvent) event);
4999a196
GB
149 if (state != null) {
150 return state.toString();
151 }
1d46dc38
PT
152 if (event instanceof NullTimeEvent) {
153 return null;
dedc7dec 154 }
af10fe06 155 return Messages.ResourcesView_multipleStates;
dedc7dec
PT
156 }
157
158 @Override
159 public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event, long hoverTime) {
160
e0838ca1 161 Map<String, String> retMap = new LinkedHashMap<>();
4999a196 162 if (event instanceof TimeEvent && ((TimeEvent) event).hasValue()) {
dedc7dec 163
4999a196
GB
164 TimeEvent tcEvent = (TimeEvent) event;
165 ResourcesEntry entry = (ResourcesEntry) event.getEntry();
dedc7dec 166
4999a196 167 if (tcEvent.hasValue()) {
6d16f5a9 168 ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
4bc53929
GB
169 if (ss == null) {
170 return retMap;
171 }
4999a196
GB
172 // Check for IRQ or Soft_IRQ type
173 if (entry.getType().equals(Type.IRQ) || entry.getType().equals(Type.SOFT_IRQ)) {
dedc7dec 174
4999a196
GB
175 // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
176 int cpu = tcEvent.getValue();
177 if (cpu >= 0) {
178 retMap.put(Messages.ResourcesView_attributeCpuName, String.valueOf(cpu));
179 }
dedc7dec 180 }
dedc7dec 181
4999a196
GB
182 // Check for type CPU
183 else if (entry.getType().equals(Type.CPU)) {
184 int status = tcEvent.getValue();
185
186 if (status == StateValues.CPU_STATUS_IRQ) {
187 // In IRQ state get the IRQ that caused the interruption
4999a196
GB
188 int cpu = entry.getId();
189
190 try {
191 List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
19ed6598 192 List<Integer> irqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.IRQS, "*"); //$NON-NLS-1$
4999a196
GB
193
194 for (int irqQuark : irqQuarks) {
631d47f1
LPD
195 ITmfStateInterval value = fullState.get(irqQuark);
196 if (!value.getStateValue().isNull()) {
197 String irq = ss.getAttributeName(irqQuark);
198 retMap.put(Messages.ResourcesView_attributeIrqName, irq);
4999a196 199 break;
dedc7dec 200 }
dedc7dec 201 }
631d47f1 202 } catch (TimeRangeException | StateValueTypeException e) {
4bc53929 203 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
204 } catch (StateSystemDisposedException e) {
205 /* Ignored */
dedc7dec 206 }
4999a196
GB
207 } else if (status == StateValues.CPU_STATUS_SOFTIRQ) {
208 // In SOFT_IRQ state get the SOFT_IRQ that caused the interruption
4999a196
GB
209 int cpu = entry.getId();
210
211 try {
212 List<ITmfStateInterval> fullState = ss.queryFullState(event.getTime());
19ed6598 213 List<Integer> softIrqQuarks = ss.getQuarks(Attributes.CPUS, Integer.toString(cpu), Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
4999a196
GB
214
215 for (int softIrqQuark : softIrqQuarks) {
631d47f1
LPD
216 ITmfStateInterval value = fullState.get(softIrqQuark);
217 if (!value.getStateValue().isNull()) {
218 String softIrq = ss.getAttributeName(softIrqQuark);
219 retMap.put(Messages.ResourcesView_attributeSoftIrqName, softIrq);
4999a196 220 break;
dedc7dec 221 }
dedc7dec 222 }
631d47f1 223 } catch (TimeRangeException | StateValueTypeException e) {
4bc53929 224 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
225 } catch (StateSystemDisposedException e) {
226 /* Ignored */
dedc7dec 227 }
4999a196
GB
228 } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL) {
229 // In running state get the current tid
4999a196
GB
230
231 try {
232 retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
233 int cpuQuark = entry.getQuark();
4bc53929
GB
234 int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
235 ITmfStateInterval interval = ss.querySingleState(hoverTime, currentThreadQuark);
dedc7dec 236 if (!interval.getStateValue().isNull()) {
4999a196
GB
237 ITmfStateValue value = interval.getStateValue();
238 int currentThreadId = value.unboxInt();
239 retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
4bc53929
GB
240 int execNameQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
241 interval = ss.querySingleState(hoverTime, execNameQuark);
dedc7dec
PT
242 if (!interval.getStateValue().isNull()) {
243 value = interval.getStateValue();
4999a196
GB
244 retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
245 }
246 if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
4bc53929
GB
247 int syscallQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
248 interval = ss.querySingleState(hoverTime, syscallQuark);
4999a196
GB
249 if (!interval.getStateValue().isNull()) {
250 value = interval.getStateValue();
251 retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
252 }
dedc7dec
PT
253 }
254 }
4bc53929
GB
255 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
256 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
257 } catch (StateSystemDisposedException e) {
258 /* Ignored */
dedc7dec 259 }
dedc7dec 260 }
96345c5a 261 }
dedc7dec
PT
262 }
263 }
264
265 return retMap;
266 }
267
713a70ae
PT
268 @Override
269 public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
5bf0ab10
MAL
270 if (fColorGray == null) {
271 fColorGray = gc.getDevice().getSystemColor(SWT.COLOR_GRAY);
272 }
273 if (fColorWhite == null) {
274 fColorWhite = gc.getDevice().getSystemColor(SWT.COLOR_WHITE);
275 }
276 if (fAverageCharWidth == null) {
277 fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth();
278 }
279
4999a196 280 ITmfTimeGraphDrawingHelper drawingHelper = getDrawingHelper();
5bf0ab10 281 if (bounds.width <= fAverageCharWidth) {
713a70ae
PT
282 return;
283 }
4999a196
GB
284
285 if (!(event instanceof TimeEvent)) {
713a70ae
PT
286 return;
287 }
4999a196
GB
288 TimeEvent tcEvent = (TimeEvent) event;
289 if (!tcEvent.hasValue()) {
713a70ae
PT
290 return;
291 }
4999a196
GB
292
293 ResourcesEntry entry = (ResourcesEntry) event.getEntry();
294 if (!entry.getType().equals(Type.CPU)) {
295 return;
296 }
297
298 int status = tcEvent.getValue();
713a70ae
PT
299 if (status != StateValues.CPU_STATUS_RUN_USERMODE && status != StateValues.CPU_STATUS_RUN_SYSCALL) {
300 return;
301 }
4999a196 302
6d16f5a9 303 ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
4bc53929
GB
304 if (ss == null) {
305 return;
306 }
713a70ae 307 long time = event.getTime();
a3fbd3f4
PT
308 try {
309 while (time < event.getTime() + event.getDuration()) {
713a70ae
PT
310 int cpuQuark = entry.getQuark();
311 int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
312 ITmfStateInterval tidInterval = ss.querySingleState(time, currentThreadQuark);
1b26cb91
PT
313 long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
314 int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
315 if (x >= bounds.x + bounds.width) {
316 break;
317 }
713a70ae
PT
318 if (!tidInterval.getStateValue().isNull()) {
319 ITmfStateValue value = tidInterval.getStateValue();
320 int currentThreadId = value.unboxInt();
1b26cb91
PT
321 long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
322 int xForEndTime = drawingHelper.getXForTime(endTime);
323 if (xForEndTime > bounds.x) {
324 int width = Math.min(xForEndTime, bounds.x + bounds.width) - x - 1;
325 if (width > 0) {
326 String attribute = null;
327 int beginIndex = 0;
328 if (status == StateValues.CPU_STATUS_RUN_USERMODE && currentThreadId != fLastThreadId) {
329 attribute = Attributes.EXEC_NAME;
330 } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
331 attribute = Attributes.SYSTEM_CALL;
acba092b
AM
332 /*
333 * Remove the "sys_" or "syscall_entry_" or similar from what we
334 * draw in the rectangle. This depends on the trace's event layout.
335 */
336 ITmfTrace trace = entry.getTrace();
e363eae1
AM
337 if (trace instanceof IKernelTrace) {
338 IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout();
acba092b
AM
339 beginIndex = layout.eventSyscallEntryPrefix().length();
340 }
1b26cb91
PT
341 }
342 if (attribute != null) {
343 int quark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), attribute);
344 ITmfStateInterval interval = ss.querySingleState(time, quark);
5bf0ab10
MAL
345 if (!interval.getStateValue().isNull()) {
346 value = interval.getStateValue();
347 gc.setForeground(fColorWhite);
3bd20aa6 348 int drawn = Utils.drawText(gc, value.unboxStr().substring(beginIndex), x + 1, bounds.y, width, bounds.height, true, true);
38f7712b 349 if (drawn > 0 && status == StateValues.CPU_STATUS_RUN_USERMODE) {
5bf0ab10
MAL
350 fLastThreadId = currentThreadId;
351 }
713a70ae
PT
352 }
353 }
1b26cb91
PT
354 if (xForEndTime < bounds.x + bounds.width) {
355 gc.setForeground(fColorGray);
356 gc.drawLine(xForEndTime, bounds.y + 1, xForEndTime, bounds.y + bounds.height - 2);
713a70ae
PT
357 }
358 }
359 }
360 }
1b26cb91
PT
361 // make sure next time is at least at the next pixel
362 time = Math.max(tidInterval.getEndTime() + 1, drawingHelper.getTimeAtX(x + 1));
713a70ae 363 }
4bc53929
GB
364 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
365 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
a3fbd3f4
PT
366 } catch (StateSystemDisposedException e) {
367 /* Ignored */
713a70ae
PT
368 }
369 }
370
371 @Override
372 public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) {
373 fLastThreadId = -1;
374 }
dedc7dec 375}
This page took 0.098229 seconds and 5 git commands to generate.