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