1 /**********************************************************************
2 * Copyright (c) 2016 É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
8 **********************************************************************/
9 package org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.ui
.views
.kernelmemoryusage
;
11 import java
.util
.List
;
13 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
14 import org
.eclipse
.swt
.SWT
;
15 import org
.eclipse
.swt
.widgets
.Composite
;
16 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelmemoryusage
.KernelMemoryAnalysisModule
;
17 import org
.eclipse
.tracecompass
.common
.core
.format
.DataSizeWithUnitFormat
;
18 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.ui
.Activator
;
19 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.interval
.ITmfStateInterval
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalHandler
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.TmfStateSystemAnalysisModule
;
28 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
29 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
30 import org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.xycharts
.linecharts
.TmfCommonXLineChartViewer
;
31 import org
.swtchart
.Chart
;
36 * @author Samuel Gagnon
37 * @author Wassim Nasrallah
39 public class KernelMemoryUsageViewer
extends TmfCommonXLineChartViewer
{
41 private static final String NOT_SELECTED
= "-1"; //$NON-NLS-1$
43 private TmfStateSystemAnalysisModule fModule
= null;
44 private String fSelectedThread
= NOT_SELECTED
;
52 public KernelMemoryUsageViewer(Composite parent
) {
53 super(parent
, Messages
.MemoryUsageViewer_title
, Messages
.MemoryUsageViewer_xAxis
, Messages
.MemoryUsageViewer_yAxis
);
54 Chart chart
= getSwtChart();
55 chart
.getAxisSet().getYAxis(0).getTick().setFormat(DataSizeWithUnitFormat
.getInstance());
56 chart
.getLegend().setPosition(SWT
.BOTTOM
);
60 protected void initializeDataSource() {
61 ITmfTrace trace
= getTrace();
63 fModule
= TmfTraceUtils
.getAnalysisModuleOfClass(trace
, TmfStateSystemAnalysisModule
.class, KernelMemoryAnalysisModule
.ID
);
64 if (fModule
== null) {
72 protected void updateData(long start
, long end
, int nb
, IProgressMonitor monitor
) {
73 TmfStateSystemAnalysisModule module
= fModule
;
74 if (getTrace() == null || module
== null) {
78 if (!module
.waitForInitialization()) {
82 ITmfStateSystem ss
= module
.getStateSystem();
84 throw new IllegalStateException("No state system for the module " + module
.toString()); //$NON-NLS-1$
87 double[] xvalues
= getXAxis(start
, end
, nb
);
88 if (xvalues
.length
== 0) {
91 long clampedEnd
= Math
.min(end
, ss
.getCurrentEndTime());
92 if (clampedEnd
< ss
.getStartTime()) {
99 * For a given time range, we plot two lines representing the memory
100 * allocation. The first line represent the total memory allocation
101 * of every process. The second line represent the memory allocation
102 * of the selected thread.
104 double[] totalKernelMemoryValues
= new double[xvalues
.length
];
105 double[] selectedThreadValues
= new double[xvalues
.length
];
106 for (int i
= 0; i
< xvalues
.length
; i
++) {
107 if (monitor
.isCanceled()) {
111 double x
= xvalues
[i
];
112 long t
= (long) x
+ getTimeOffset();
113 if( ss
.getCurrentEndTime() < t
|| ss
.getStartTime() > t
) {
114 selectedThreadValues
[i
] = 0;
117 List
<ITmfStateInterval
> kernelState
= ss
.queryFullState(t
);
119 /* The subattributes of the root are the different threads */
120 List
<Integer
> threadQuarkList
= ss
.getSubAttributes(-1, false);
121 /* We add the value of each thread to the total quantity */
122 for (Integer threadQuark
: threadQuarkList
) {
123 ITmfStateInterval threadMemoryInterval
= kernelState
.get(threadQuark
);
124 long value
= threadMemoryInterval
.getStateValue().unboxLong();
125 totalKernelMemoryValues
[i
] += value
;
127 String tid
= ss
.getAttributeName(threadQuark
);
128 if (tid
.equals(fSelectedThread
)) {
129 selectedThreadValues
[i
] = value
;
135 * For each thread, we look for its lowest value since the beginning
136 * of the trace. This way, we can avoid negative values in the plot.
138 double totalKernelMemoryValuesShift
= 0;
139 double selectThreadValuesShift
= 0;
142 * The lowest value we are searching is at the end of the current
145 List
<ITmfStateInterval
> kernelState
= ss
.queryFullState(clampedEnd
);
146 List
<Integer
> threadQuarkList
= ss
.getSubAttributes(-1, false);
147 /* We add the lowest value of each thread */
148 for (Integer threadQuark
: threadQuarkList
) {
149 int lowestMemoryQuark
= ss
.getQuarkRelative(threadQuark
, KernelMemoryAnalysisModule
.THREAD_LOWEST_MEMORY_VALUE
);
150 ITmfStateInterval lowestMemoryInterval
= kernelState
.get(lowestMemoryQuark
);
151 long lowestMemoryValue
= lowestMemoryInterval
.getStateValue().unboxLong();
152 // We want to add up a positive quantity.
153 totalKernelMemoryValuesShift
-= lowestMemoryValue
;
155 String tid
= ss
.getAttributeName(threadQuark
);
156 if (tid
.equals(fSelectedThread
)) {
157 // We want to add up a positive quantity.
158 selectThreadValuesShift
= -lowestMemoryValue
;
163 * We shift the two displayed lines up.
165 for (int i
= 0; i
< xvalues
.length
; i
++) {
166 totalKernelMemoryValues
[i
] += totalKernelMemoryValuesShift
;
167 selectedThreadValues
[i
] += selectThreadValuesShift
;
169 setSeries(Messages
.MemoryUsageViewer_Total
, totalKernelMemoryValues
);
170 if (fSelectedThread
!= NOT_SELECTED
) {
171 setSeries(fSelectedThread
, selectedThreadValues
);
175 } catch (TimeRangeException
| StateSystemDisposedException
| AttributeNotFoundException e
) {
176 Activator
.getDefault().logError(e
.getMessage(), e
);
181 * Set the selected thread ID, which will be graphed in this viewer
184 * The selected thread ID
186 public void setSelectedThread(String tid
) {
188 deleteSeries(fSelectedThread
);
189 fSelectedThread
= tid
;
195 public void traceSelected(TmfTraceSelectedSignal signal
) {
196 setSelectedThread(NOT_SELECTED
);
197 super.traceSelected(signal
);
202 public void traceOpened(TmfTraceOpenedSignal signal
) {
203 setSelectedThread(NOT_SELECTED
);
204 super.traceOpened(signal
);