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