1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 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 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));
67 private State (RGB rgb
) {
75 * @param timeGraphViewer the time graph viewer
77 public ResourcesPresentationProvider(TimeGraphViewer timeGraphViewer
) {
79 this.fTimeGraphViewer
= timeGraphViewer
;
83 public String
getStateTypeName() {
84 return Messages
.ResourcesView_stateTypeName
;
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());
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();
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();
121 return State
.SOFT_IRQ_ACTIVE
.ordinal();
123 return INVISIBLE
; // NULL
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();
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();
153 return State
.SOFT_IRQ_ACTIVE
.toString();
158 return Messages
.ResourcesView_multipleStates
;
162 public Map
<String
, String
> getEventHoverToolTipInfo(ITimeEvent event
, long hoverTime
) {
164 Map
<String
, String
> retMap
= new LinkedHashMap
<String
, String
>();
165 if (event
instanceof ResourcesEvent
) {
167 ResourcesEvent resourcesEvent
= (ResourcesEvent
) event
;
169 // Check for IRQ or Soft_IRQ type
170 if (resourcesEvent
.getType().equals(Type
.IRQ
) || resourcesEvent
.getType().equals(Type
.SOFT_IRQ
)) {
172 // Get CPU of IRQ or SoftIRQ and provide it for the tooltip display
173 int cpu
= resourcesEvent
.getValue();
175 retMap
.put(Messages
.ResourcesView_attributeCpuName
, String
.valueOf(cpu
));
179 // Check for type CPU
180 if (resourcesEvent
.getType().equals(Type
.CPU
)) {
181 int status
= resourcesEvent
.getValue();
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();
190 List
<ITmfStateInterval
> fullState
= ss
.queryFullState(event
.getTime());
191 List
<Integer
> irqQuarks
= ss
.getQuarks(Attributes
.RESOURCES
, Attributes
.IRQS
, "*"); //$NON-NLS-1$
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
));
203 } catch (AttributeNotFoundException e
) {
205 } catch (TimeRangeException e
) {
207 } catch (StateValueTypeException e
) {
209 } catch (StateSystemDisposedException e
) {
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();
219 List
<ITmfStateInterval
> fullState
= ss
.queryFullState(event
.getTime());
220 List
<Integer
> softIrqQuarks
= ss
.getQuarks(Attributes
.RESOURCES
, Attributes
.SOFT_IRQS
, "*"); //$NON-NLS-1$
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
));
232 } catch (AttributeNotFoundException e
) {
234 } catch (TimeRangeException e
) {
236 } catch (StateValueTypeException e
) {
238 } catch (StateSystemDisposedException e
) {
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
);
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());
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());
270 } catch (AttributeNotFoundException e
) {
272 } catch (TimeRangeException e
) {
274 } catch (StateValueTypeException e
) {
276 } catch (StateSystemDisposedException e
) {
287 public void postDrawEvent(ITimeEvent event
, Rectangle bounds
, GC gc
) {
288 if (bounds
.width
<= gc
.getFontMetrics().getAverageCharWidth()) {
291 if (!(event
instanceof ResourcesEvent
)) {
294 ResourcesEvent resourcesEvent
= (ResourcesEvent
) event
;
295 if (!resourcesEvent
.getType().equals(Type
.CPU
)) {
298 int status
= resourcesEvent
.getValue();
299 if (status
!= StateValues
.CPU_STATUS_RUN_USERMODE
&& status
!= StateValues
.CPU_STATUS_RUN_SYSCALL
) {
302 ResourcesEntry entry
= (ResourcesEntry
) event
.getEntry();
303 ITmfStateSystem ss
= entry
.getTrace().getStateSystem(CtfKernelTrace
.STATE_ID
);
304 long time
= event
.getTime();
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);
326 fLastThreadId
= currentThreadId
;
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);
346 time
= tidInterval
.getEndTime() + 1;
347 if (time
< event
.getTime() + event
.getDuration()) {
348 int x
= fTimeGraphViewer
.getXForTime(time
);
350 gc
.setForeground(gc
.getDevice().getSystemColor(SWT
.COLOR_GRAY
));
351 gc
.drawLine(x
, bounds
.y
+ 1, x
, bounds
.y
+ bounds
.height
- 2);
355 } catch (AttributeNotFoundException e
) {
357 } catch (TimeRangeException e
) {
359 } catch (StateValueTypeException e
) {
361 } catch (StateSystemDisposedException e
) {
367 public void postDrawEntry(ITimeGraphEntry entry
, Rectangle bounds
, GC gc
) {