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