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