1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Ericsson, École Polytechnique de Montréal
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
10 * Patrick Tasse - Initial API and implementation
11 * Geneviève Bastien - Move code to provide base classes for time graph view
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.ui
.views
.resources
;
16 import java
.util
.LinkedHashMap
;
17 import java
.util
.List
;
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
;
47 * Presentation provider for the Resource view, based on the generic TMF
48 * presentation provider.
50 * @author Patrick Tasse
52 public class ResourcesPresentationProvider
extends TimeGraphPresentationProvider
{
54 private long fLastThreadId
= -1;
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));
68 private State(RGB rgb
) {
76 public ResourcesPresentationProvider() {
80 private static State
[] getStateValues() {
81 return State
.values();
84 private static State
getEventState(ITimeEvent event
) {
85 if (event
instanceof TimeEvent
&& ((TimeEvent
) event
).hasValue()) {
86 TimeEvent tcEvent
= (TimeEvent
) event
;
88 ResourcesEntry entry
= (ResourcesEntry
) event
.getEntry();
89 int value
= tcEvent
.getValue();
91 if (entry
.getType() == Type
.CPU
) {
92 if (value
== StateValues
.CPU_STATUS_IDLE
) {
94 } else if (value
== StateValues
.CPU_STATUS_RUN_USERMODE
) {
95 return State
.USERMODE
;
96 } else if (value
== StateValues
.CPU_STATUS_RUN_SYSCALL
) {
98 } else if (value
== StateValues
.CPU_STATUS_IRQ
) {
100 } else if (value
== StateValues
.CPU_STATUS_SOFTIRQ
) {
101 return State
.SOFT_IRQ
;
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
;
109 return State
.SOFT_IRQ_ACTIVE
;
116 public int getStateTableIndex(ITimeEvent event
) {
117 State state
= getEventState(event
);
119 return state
.ordinal();
121 if (event
instanceof TimeEvent
) {
122 TimeEvent tcEvent
= (TimeEvent
) event
;
123 if (tcEvent
.hasValue()) {
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());
142 public String
getEventName(ITimeEvent event
) {
143 State state
= getEventState(event
);
145 return state
.toString();
147 if (event
instanceof TimeEvent
) {
148 TimeEvent tcEvent
= (TimeEvent
) event
;
149 if (tcEvent
.hasValue()) {
153 return Messages
.ResourcesView_multipleStates
;
157 public Map
<String
, String
> getEventHoverToolTipInfo(ITimeEvent event
, long hoverTime
) {
159 Map
<String
, String
> retMap
= new LinkedHashMap
<String
, String
>();
160 if (event
instanceof TimeEvent
&& ((TimeEvent
) event
).hasValue()) {
162 TimeEvent tcEvent
= (TimeEvent
) event
;
163 ResourcesEntry entry
= (ResourcesEntry
) event
.getEntry();
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
)) {
169 // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
170 int cpu
= tcEvent
.getValue();
172 retMap
.put(Messages
.ResourcesView_attributeCpuName
, String
.valueOf(cpu
));
176 // Check for type CPU
177 else if (entry
.getType().equals(Type
.CPU
)) {
178 int status
= tcEvent
.getValue();
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();
186 List
<ITmfStateInterval
> fullState
= ss
.queryFullState(event
.getTime());
187 List
<Integer
> irqQuarks
= ss
.getQuarks(Attributes
.RESOURCES
, Attributes
.IRQS
, "*"); //$NON-NLS-1$
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
));
199 } catch (AttributeNotFoundException e
) {
201 } catch (TimeRangeException e
) {
203 } catch (StateValueTypeException e
) {
205 } catch (StateSystemDisposedException e
) {
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();
214 List
<ITmfStateInterval
> fullState
= ss
.queryFullState(event
.getTime());
215 List
<Integer
> softIrqQuarks
= ss
.getQuarks(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
, "*"); //$NON-NLS-1$
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
));
227 } catch (AttributeNotFoundException e
) {
229 } catch (TimeRangeException e
) {
231 } catch (StateValueTypeException e
) {
233 } catch (StateSystemDisposedException e
) {
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
);
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());
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());
264 } catch (AttributeNotFoundException e
) {
266 } catch (TimeRangeException e
) {
268 } catch (StateValueTypeException e
) {
270 } catch (StateSystemDisposedException e
) {
282 public void postDrawEvent(ITimeEvent event
, Rectangle bounds
, GC gc
) {
283 ITmfTimeGraphDrawingHelper drawingHelper
= getDrawingHelper();
284 if (bounds
.width
<= gc
.getFontMetrics().getAverageCharWidth()) {
288 if (!(event
instanceof TimeEvent
)) {
291 TimeEvent tcEvent
= (TimeEvent
) event
;
292 if (!tcEvent
.hasValue()) {
296 ResourcesEntry entry
= (ResourcesEntry
) event
.getEntry();
297 if (!entry
.getType().equals(Type
.CPU
)) {
301 int status
= tcEvent
.getValue();
302 if (status
!= StateValues
.CPU_STATUS_RUN_USERMODE
&& status
!= StateValues
.CPU_STATUS_RUN_SYSCALL
) {
306 ITmfStateSystem ss
= entry
.getTrace().getStateSystems().get(LttngKernelTrace
.STATE_ID
);
307 long time
= event
.getTime();
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);
329 fLastThreadId
= currentThreadId
;
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);
349 time
= tidInterval
.getEndTime() + 1;
350 if (time
< event
.getTime() + event
.getDuration()) {
351 int x
= drawingHelper
.getXForTime(time
);
353 gc
.setForeground(gc
.getDevice().getSystemColor(SWT
.COLOR_GRAY
));
354 gc
.drawLine(x
, bounds
.y
+ 1, x
, bounds
.y
+ bounds
.height
- 2);
358 } catch (AttributeNotFoundException e
) {
360 } catch (TimeRangeException e
) {
362 } catch (StateValueTypeException e
) {
364 } catch (StateSystemDisposedException e
) {
370 public void postDrawEntry(ITimeGraphEntry entry
, Rectangle bounds
, GC gc
) {