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