1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
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 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.lttng2
.kernel
.ui
.views
.resources
;
15 import java
.util
.LinkedHashMap
;
16 import java
.util
.List
;
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
;
45 * Presentation provider for the Resource view, based on the generic TMF
46 * presentation provider.
48 * @author Patrick Tasse
50 public class ResourcesPresentationProvider
extends TimeGraphPresentationProvider
{
52 private final TimeGraphViewer fTimeGraphViewer
;
53 private long fLastThreadId
= -1; // used to draw the process name label only once per thread id
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)),
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 * @param timeGraphViewer the time graph viewer
78 public ResourcesPresentationProvider(TimeGraphViewer timeGraphViewer
) {
80 this.fTimeGraphViewer
= timeGraphViewer
;
84 public String
getStateTypeName() {
85 return Messages
.ResourcesView_stateTypeName
;
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());
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();
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();
122 return State
.SOFT_IRQ_ACTIVE
.ordinal();
127 return State
.UNKNOWN
.ordinal();
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();
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();
154 return State
.SOFT_IRQ_ACTIVE
.toString();
159 return State
.UNKNOWN
.toString();
163 public Map
<String
, String
> getEventHoverToolTipInfo(ITimeEvent event
, long hoverTime
) {
165 Map
<String
, String
> retMap
= new LinkedHashMap
<String
, String
>();
166 if (event
instanceof ResourcesEvent
) {
168 ResourcesEvent resourcesEvent
= (ResourcesEvent
) event
;
170 // Check for IRQ or Soft_IRQ type
171 if (resourcesEvent
.getType().equals(Type
.IRQ
) || resourcesEvent
.getType().equals(Type
.SOFT_IRQ
)) {
173 // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
174 int cpu
= resourcesEvent
.getValue();
176 retMap
.put(Messages
.ResourcesView_attributeCpuName
, String
.valueOf(cpu
));
180 // Check for type CPU
181 if (resourcesEvent
.getType().equals(Type
.CPU
)) {
182 int status
= resourcesEvent
.getValue();
184 if (status
== StateValues
.CPU_STATUS_IRQ
) {
185 // In IRQ state get the IRQ that caused the interruption
186 ResourcesEntry entry
= (ResourcesEntry
) event
.getEntry();
187 ITmfStateSystem ss
= entry
.getTrace().getStateSystem(CtfKernelTrace
.STATE_ID
);
188 int cpu
= entry
.getId();
191 List
<ITmfStateInterval
> fullState
= ss
.queryFullState(event
.getTime());
192 List
<Integer
> irqQuarks
= ss
.getQuarks(Attributes
.RESOURCES
, Attributes
.IRQS
, "*"); //$NON-NLS-1$
194 for (int irqQuark
: irqQuarks
) {
195 if (fullState
.get(irqQuark
).getStateValue().unboxInt() == cpu
) {
196 ITmfStateInterval value
= ss
.querySingleState(event
.getTime(), irqQuark
);
197 if (!value
.getStateValue().isNull()) {
198 int irq
= Integer
.parseInt(ss
.getAttributeName(irqQuark
));
199 retMap
.put(Messages
.ResourcesView_attributeIrqName
, String
.valueOf(irq
));
204 } catch (AttributeNotFoundException e
) {
206 } catch (TimeRangeException e
) {
208 } catch (StateValueTypeException e
) {
210 } catch (StateSystemDisposedException e
) {
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();
216 ITmfStateSystem ss
= entry
.getTrace().getStateSystem(CtfKernelTrace
.STATE_ID
);
217 int cpu
= entry
.getId();
220 List
<ITmfStateInterval
> fullState
= ss
.queryFullState(event
.getTime());
221 List
<Integer
> softIrqQuarks
= ss
.getQuarks(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
, "*"); //$NON-NLS-1$
223 for (int softIrqQuark
: softIrqQuarks
) {
224 if (fullState
.get(softIrqQuark
).getStateValue().unboxInt() == cpu
) {
225 ITmfStateInterval value
= ss
.querySingleState(event
.getTime(), softIrqQuark
);
226 if (!value
.getStateValue().isNull()) {
227 int softIrq
= Integer
.parseInt(ss
.getAttributeName(softIrqQuark
));
228 retMap
.put(Messages
.ResourcesView_attributeSoftIrqName
, String
.valueOf(softIrq
));
233 } catch (AttributeNotFoundException e
) {
235 } catch (TimeRangeException e
) {
237 } catch (StateValueTypeException e
) {
239 } catch (StateSystemDisposedException e
) {
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();
245 ITmfStateSystem ssq
= entry
.getTrace().getStateSystem(CtfKernelTrace
.STATE_ID
);
248 retMap
.put(Messages
.ResourcesView_attributeHoverTime
, Utils
.formatTime(hoverTime
, TimeFormat
.CALENDAR
, Resolution
.NANOSEC
));
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());
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());
271 } catch (AttributeNotFoundException e
) {
273 } catch (TimeRangeException e
) {
275 } catch (StateValueTypeException e
) {
277 } catch (StateSystemDisposedException e
) {
288 public void postDrawEvent(ITimeEvent event
, Rectangle bounds
, GC gc
) {
289 if (bounds
.width
<= gc
.getFontMetrics().getAverageCharWidth()) {
292 if (!(event
instanceof ResourcesEvent
)) {
295 ResourcesEvent resourcesEvent
= (ResourcesEvent
) event
;
296 if (!resourcesEvent
.getType().equals(Type
.CPU
)) {
299 int status
= resourcesEvent
.getValue();
300 if (status
!= StateValues
.CPU_STATUS_RUN_USERMODE
&& status
!= StateValues
.CPU_STATUS_RUN_SYSCALL
) {
303 ResourcesEntry entry
= (ResourcesEntry
) event
.getEntry();
304 ITmfStateSystem ss
= entry
.getTrace().getStateSystem(CtfKernelTrace
.STATE_ID
);
305 long time
= event
.getTime();
307 while (time
< event
.getTime() + event
.getDuration()) {
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);
327 fLastThreadId
= currentThreadId
;
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);
347 time
= tidInterval
.getEndTime() + 1;
348 if (time
< event
.getTime() + event
.getDuration()) {
349 int x
= fTimeGraphViewer
.getXForTime(time
);
351 gc
.setForeground(gc
.getDevice().getSystemColor(SWT
.COLOR_GRAY
));
352 gc
.drawLine(x
, bounds
.y
+ 1, x
, bounds
.y
+ bounds
.height
- 2);
356 } catch (AttributeNotFoundException e
) {
358 } catch (TimeRangeException e
) {
360 } catch (StateValueTypeException e
) {
362 } catch (StateSystemDisposedException e
) {
368 public void postDrawEntry(ITimeGraphEntry entry
, Rectangle bounds
, GC gc
) {