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
);
57 chart
.getLegend().setVisible(false);
61 protected void initializeDataSource() {
62 ITmfTrace trace
= getTrace();
64 fModule
= TmfTraceUtils
.getAnalysisModuleOfClass(trace
, TmfStateSystemAnalysisModule
.class, KernelMemoryAnalysisModule
.ID
);
65 if (fModule
== null) {
73 protected void updateData(long start
, long end
, int nb
, IProgressMonitor monitor
) {
74 TmfStateSystemAnalysisModule module
= fModule
;
75 if (getTrace() == null || module
== null) {
79 if (!module
.waitForInitialization()) {
83 ITmfStateSystem ss
= module
.getStateSystem();
85 throw new IllegalStateException("No state system for the module " + module
.toString()); //$NON-NLS-1$
88 double[] xvalues
= getXAxis(start
, end
, nb
);
89 if (xvalues
.length
== 0) {
92 long clampedEnd
= Math
.min(end
, ss
.getCurrentEndTime());
93 if (clampedEnd
< ss
.getStartTime()) {
100 * For a given time range, we plot two lines representing the memory
101 * allocation. The first line represent the total memory allocation
102 * of every process. The second line represent the memory allocation
103 * of the selected thread.
105 double[] totalKernelMemoryValues
= new double[xvalues
.length
];
106 double[] selectedThreadValues
= new double[xvalues
.length
];
107 for (int i
= 0; i
< xvalues
.length
; i
++) {
108 if (monitor
.isCanceled()) {
112 double x
= xvalues
[i
];
113 long t
= (long) x
+ getTimeOffset();
114 if( ss
.getCurrentEndTime() < t
|| ss
.getStartTime() > t
) {
115 selectedThreadValues
[i
] = 0;
118 List
<ITmfStateInterval
> kernelState
= ss
.queryFullState(t
);
120 /* The subattributes of the root are the different threads */
121 List
<Integer
> threadQuarkList
= ss
.getSubAttributes(-1, false);
122 /* We add the value of each thread to the total quantity */
123 for (Integer threadQuark
: threadQuarkList
) {
124 ITmfStateInterval threadMemoryInterval
= kernelState
.get(threadQuark
);
125 long value
= threadMemoryInterval
.getStateValue().unboxLong();
126 totalKernelMemoryValues
[i
] += value
;
128 String tid
= ss
.getAttributeName(threadQuark
);
129 if (tid
.equals(fSelectedThread
)) {
130 selectedThreadValues
[i
] = value
;
136 * For each thread, we look for its lowest value since the beginning
137 * of the trace. This way, we can avoid negative values in the plot.
139 double totalKernelMemoryValuesShift
= 0;
140 double selectThreadValuesShift
= 0;
143 * The lowest value we are searching is at the end of the current
146 List
<ITmfStateInterval
> kernelState
= ss
.queryFullState(clampedEnd
);
147 List
<Integer
> threadQuarkList
= ss
.getSubAttributes(-1, false);
148 /* We add the lowest value of each thread */
149 for (Integer threadQuark
: threadQuarkList
) {
150 int lowestMemoryQuark
= ss
.getQuarkRelative(threadQuark
, KernelMemoryAnalysisModule
.THREAD_LOWEST_MEMORY_VALUE
);
151 ITmfStateInterval lowestMemoryInterval
= kernelState
.get(lowestMemoryQuark
);
152 long lowestMemoryValue
= lowestMemoryInterval
.getStateValue().unboxLong();
153 // We want to add up a positive quantity.
154 totalKernelMemoryValuesShift
-= lowestMemoryValue
;
156 String tid
= ss
.getAttributeName(threadQuark
);
157 if (tid
.equals(fSelectedThread
)) {
158 // We want to add up a positive quantity.
159 selectThreadValuesShift
= -lowestMemoryValue
;
164 * We shift the two displayed lines up.
166 for (int i
= 0; i
< xvalues
.length
; i
++) {
167 totalKernelMemoryValues
[i
] += totalKernelMemoryValuesShift
;
168 selectedThreadValues
[i
] += selectThreadValuesShift
;
170 setSeries(Messages
.MemoryUsageViewer_Total
, totalKernelMemoryValues
);
171 if (fSelectedThread
!= NOT_SELECTED
) {
172 setSeries(fSelectedThread
, selectedThreadValues
);
176 } catch (TimeRangeException
| StateSystemDisposedException
| AttributeNotFoundException e
) {
177 Activator
.getDefault().logError(e
.getMessage(), e
);
182 * Set the selected thread ID, which will be graphed in this viewer
185 * The selected thread ID
187 public void setSelectedThread(String tid
) {
189 deleteSeries(fSelectedThread
);
190 fSelectedThread
= tid
;
196 public void traceSelected(TmfTraceSelectedSignal signal
) {
197 setSelectedThread(NOT_SELECTED
);
198 super.traceSelected(signal
);
203 public void traceOpened(TmfTraceOpenedSignal signal
) {
204 setSelectedThread(NOT_SELECTED
);
205 super.traceOpened(signal
);