Replace usage of ViewerSorter with ViewerComparator
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.ui / src / org / eclipse / tracecompass / 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
e363eae1 14package org.eclipse.tracecompass.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;
e363eae1 25import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes;
6d16f5a9 26import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysisModule;
e363eae1
AM
27import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.StateValues;
28import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
29import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
30import org.eclipse.tracecompass.analysis.os.linux.ui.views.resources.ResourcesEntry.Type;
31import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
32import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
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) {
4999a196
GB
114 if (value == StateValues.SOFT_IRQ_RAISED) {
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());
192 List<Integer> irqQuarks = ss.getQuarks(Attributes.RESOURCES, Attributes.IRQS, "*"); //$NON-NLS-1$
193
194 for (int irqQuark : irqQuarks) {
195 if (fullState.get(irqQuark).getStateValue().unboxInt() == cpu) {
196 ITmfStateInterval value = ss.querySingleState(event.getTime(), irqQuark);
197 if (!value.getStateValue().isNull()) {
198 int irq = Integer.parseInt(ss.getAttributeName(irqQuark));
199 retMap.put(Messages.ResourcesView_attributeIrqName, String.valueOf(irq));
200 }
201 break;
dedc7dec 202 }
dedc7dec 203 }
4bc53929
GB
204 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
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());
215 List<Integer> softIrqQuarks = ss.getQuarks(Attributes.RESOURCES, Attributes.SOFT_IRQS, "*"); //$NON-NLS-1$
216
217 for (int softIrqQuark : softIrqQuarks) {
218 if (fullState.get(softIrqQuark).getStateValue().unboxInt() == cpu) {
219 ITmfStateInterval value = ss.querySingleState(event.getTime(), softIrqQuark);
220 if (!value.getStateValue().isNull()) {
221 int softIrq = Integer.parseInt(ss.getAttributeName(softIrqQuark));
222 retMap.put(Messages.ResourcesView_attributeSoftIrqName, String.valueOf(softIrq));
223 }
224 break;
dedc7dec 225 }
dedc7dec 226 }
4bc53929
GB
227 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
228 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
229 } catch (StateSystemDisposedException e) {
230 /* Ignored */
dedc7dec 231 }
4999a196
GB
232 } else if (status == StateValues.CPU_STATUS_RUN_USERMODE || status == StateValues.CPU_STATUS_RUN_SYSCALL) {
233 // In running state get the current tid
4999a196
GB
234
235 try {
236 retMap.put(Messages.ResourcesView_attributeHoverTime, Utils.formatTime(hoverTime, TimeFormat.CALENDAR, Resolution.NANOSEC));
237 int cpuQuark = entry.getQuark();
4bc53929
GB
238 int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
239 ITmfStateInterval interval = ss.querySingleState(hoverTime, currentThreadQuark);
dedc7dec 240 if (!interval.getStateValue().isNull()) {
4999a196
GB
241 ITmfStateValue value = interval.getStateValue();
242 int currentThreadId = value.unboxInt();
243 retMap.put(Messages.ResourcesView_attributeTidName, Integer.toString(currentThreadId));
4bc53929
GB
244 int execNameQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.EXEC_NAME);
245 interval = ss.querySingleState(hoverTime, execNameQuark);
dedc7dec
PT
246 if (!interval.getStateValue().isNull()) {
247 value = interval.getStateValue();
4999a196
GB
248 retMap.put(Messages.ResourcesView_attributeProcessName, value.unboxStr());
249 }
250 if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
4bc53929
GB
251 int syscallQuark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), Attributes.SYSTEM_CALL);
252 interval = ss.querySingleState(hoverTime, syscallQuark);
4999a196
GB
253 if (!interval.getStateValue().isNull()) {
254 value = interval.getStateValue();
255 retMap.put(Messages.ResourcesView_attributeSyscallName, value.unboxStr());
256 }
dedc7dec
PT
257 }
258 }
4bc53929
GB
259 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
260 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
4999a196
GB
261 } catch (StateSystemDisposedException e) {
262 /* Ignored */
dedc7dec 263 }
dedc7dec 264 }
96345c5a 265 }
dedc7dec
PT
266 }
267 }
268
269 return retMap;
270 }
271
713a70ae
PT
272 @Override
273 public void postDrawEvent(ITimeEvent event, Rectangle bounds, GC gc) {
5bf0ab10
MAL
274 if (fColorGray == null) {
275 fColorGray = gc.getDevice().getSystemColor(SWT.COLOR_GRAY);
276 }
277 if (fColorWhite == null) {
278 fColorWhite = gc.getDevice().getSystemColor(SWT.COLOR_WHITE);
279 }
280 if (fAverageCharWidth == null) {
281 fAverageCharWidth = gc.getFontMetrics().getAverageCharWidth();
282 }
283
4999a196 284 ITmfTimeGraphDrawingHelper drawingHelper = getDrawingHelper();
5bf0ab10 285 if (bounds.width <= fAverageCharWidth) {
713a70ae
PT
286 return;
287 }
4999a196
GB
288
289 if (!(event instanceof TimeEvent)) {
713a70ae
PT
290 return;
291 }
4999a196
GB
292 TimeEvent tcEvent = (TimeEvent) event;
293 if (!tcEvent.hasValue()) {
713a70ae
PT
294 return;
295 }
4999a196
GB
296
297 ResourcesEntry entry = (ResourcesEntry) event.getEntry();
298 if (!entry.getType().equals(Type.CPU)) {
299 return;
300 }
301
302 int status = tcEvent.getValue();
713a70ae
PT
303 if (status != StateValues.CPU_STATUS_RUN_USERMODE && status != StateValues.CPU_STATUS_RUN_SYSCALL) {
304 return;
305 }
4999a196 306
6d16f5a9 307 ITmfStateSystem ss = TmfStateSystemAnalysisModule.getStateSystem(entry.getTrace(), KernelAnalysisModule.ID);
4bc53929
GB
308 if (ss == null) {
309 return;
310 }
713a70ae 311 long time = event.getTime();
a3fbd3f4
PT
312 try {
313 while (time < event.getTime() + event.getDuration()) {
713a70ae
PT
314 int cpuQuark = entry.getQuark();
315 int currentThreadQuark = ss.getQuarkRelative(cpuQuark, Attributes.CURRENT_THREAD);
316 ITmfStateInterval tidInterval = ss.querySingleState(time, currentThreadQuark);
1b26cb91
PT
317 long startTime = Math.max(tidInterval.getStartTime(), event.getTime());
318 int x = Math.max(drawingHelper.getXForTime(startTime), bounds.x);
319 if (x >= bounds.x + bounds.width) {
320 break;
321 }
713a70ae
PT
322 if (!tidInterval.getStateValue().isNull()) {
323 ITmfStateValue value = tidInterval.getStateValue();
324 int currentThreadId = value.unboxInt();
1b26cb91
PT
325 long endTime = Math.min(tidInterval.getEndTime() + 1, event.getTime() + event.getDuration());
326 int xForEndTime = drawingHelper.getXForTime(endTime);
327 if (xForEndTime > bounds.x) {
328 int width = Math.min(xForEndTime, bounds.x + bounds.width) - x - 1;
329 if (width > 0) {
330 String attribute = null;
331 int beginIndex = 0;
332 if (status == StateValues.CPU_STATUS_RUN_USERMODE && currentThreadId != fLastThreadId) {
333 attribute = Attributes.EXEC_NAME;
334 } else if (status == StateValues.CPU_STATUS_RUN_SYSCALL) {
335 attribute = Attributes.SYSTEM_CALL;
acba092b
AM
336 /*
337 * Remove the "sys_" or "syscall_entry_" or similar from what we
338 * draw in the rectangle. This depends on the trace's event layout.
339 */
340 ITmfTrace trace = entry.getTrace();
e363eae1
AM
341 if (trace instanceof IKernelTrace) {
342 IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout();
acba092b
AM
343 beginIndex = layout.eventSyscallEntryPrefix().length();
344 }
1b26cb91
PT
345 }
346 if (attribute != null) {
347 int quark = ss.getQuarkAbsolute(Attributes.THREADS, Integer.toString(currentThreadId), attribute);
348 ITmfStateInterval interval = ss.querySingleState(time, quark);
5bf0ab10
MAL
349 if (!interval.getStateValue().isNull()) {
350 value = interval.getStateValue();
351 gc.setForeground(fColorWhite);
1b26cb91 352 int drawn = Utils.drawText(gc, value.unboxStr().substring(beginIndex), x + 1, bounds.y - 2, width, true, true);
5bf0ab10
MAL
353 if (drawn > 0) {
354 fLastThreadId = currentThreadId;
355 }
713a70ae
PT
356 }
357 }
1b26cb91
PT
358 if (xForEndTime < bounds.x + bounds.width) {
359 gc.setForeground(fColorGray);
360 gc.drawLine(xForEndTime, bounds.y + 1, xForEndTime, bounds.y + bounds.height - 2);
713a70ae
PT
361 }
362 }
363 }
364 }
1b26cb91
PT
365 // make sure next time is at least at the next pixel
366 time = Math.max(tidInterval.getEndTime() + 1, drawingHelper.getTimeAtX(x + 1));
713a70ae 367 }
4bc53929
GB
368 } catch (AttributeNotFoundException | TimeRangeException | StateValueTypeException e) {
369 Activator.getDefault().logError("Error in ResourcesPresentationProvider", e); //$NON-NLS-1$
a3fbd3f4
PT
370 } catch (StateSystemDisposedException e) {
371 /* Ignored */
713a70ae
PT
372 }
373 }
374
375 @Override
376 public void postDrawEntry(ITimeGraphEntry entry, Rectangle bounds, GC gc) {
377 fLastThreadId = -1;
378 }
dedc7dec 379}
This page took 0.081771 seconds and 5 git commands to generate.