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
.statesystem
.TmfStateSystemAnalysisModule
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
27 import org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.xycharts
.linecharts
.TmfCommonXLineChartViewer
;
28 import org
.swtchart
.Chart
;
33 * @author Samuel Gagnon
34 * @author Wassim Nasrallah
36 public class KernelMemoryUsageViewer
extends TmfCommonXLineChartViewer
{
38 private static final String NOT_SELECTED
= "-1"; //$NON-NLS-1$
40 private TmfStateSystemAnalysisModule fModule
= null;
41 private String fSelectedThread
= NOT_SELECTED
;
49 public KernelMemoryUsageViewer(Composite parent
) {
50 super(parent
, Messages
.MemoryUsageViewer_title
, Messages
.MemoryUsageViewer_xAxis
, Messages
.MemoryUsageViewer_yAxis
);
51 Chart chart
= getSwtChart();
52 chart
.getAxisSet().getYAxis(0).getTick().setFormat(DataSizeWithUnitFormat
.getInstance());
53 chart
.getLegend().setPosition(SWT
.BOTTOM
);
57 protected void initializeDataSource() {
58 ITmfTrace trace
= getTrace();
60 fModule
= TmfTraceUtils
.getAnalysisModuleOfClass(trace
, TmfStateSystemAnalysisModule
.class, KernelMemoryAnalysisModule
.ID
);
61 if (fModule
== null) {
69 protected void updateData(long start
, long end
, int nb
, IProgressMonitor monitor
) {
70 TmfStateSystemAnalysisModule module
= fModule
;
71 if (getTrace() == null || module
== null) {
75 if (!module
.waitForInitialization()) {
79 ITmfStateSystem ss
= module
.getStateSystem();
81 throw new IllegalStateException();
84 double[] xvalues
= getXAxis(start
, end
, nb
);
85 if (xvalues
.length
== 0) {
92 * For a given time range, we plot two lines representing the memory
93 * allocation. The first line represent the total memory allocation
94 * of every process. The second line represent the memory allocation
95 * of the selected thread.
97 double[] totalKernelMemoryValues
= new double[xvalues
.length
];
98 double[] selectedThreadValues
= new double[xvalues
.length
];
99 for (int i
= 0; i
< xvalues
.length
; i
++) {
100 if (monitor
.isCanceled()) {
104 double x
= xvalues
[i
];
105 long t
= (long) x
+ getTimeOffset();
107 List
<ITmfStateInterval
> kernelState
= ss
.queryFullState(t
);
109 /* The subattributes of the root are the different threads */
110 List
<Integer
> threadQuarkList
= ss
.getSubAttributes(-1, false);
111 /* We add the value of each thread to the total quantity */
112 for (Integer threadQuark
: threadQuarkList
) {
113 ITmfStateInterval threadMemoryInterval
= kernelState
.get(threadQuark
);
114 long value
= threadMemoryInterval
.getStateValue().unboxLong();
115 totalKernelMemoryValues
[i
] += value
;
117 String tid
= ss
.getAttributeName(threadQuark
);
118 if (tid
.equals(fSelectedThread
)) {
119 selectedThreadValues
[i
] = value
;
125 * For each thread, we look for its lowest value since the beginning
126 * of the trace. This way, we can avoid negative values in the plot.
128 double totalKernelMemoryValuesShift
= 0;
129 double selectThreadValuesShift
= 0;
132 * The lowest value we are searching is at the end of the current
135 List
<ITmfStateInterval
> kernelState
= ss
.queryFullState(end
);
136 List
<Integer
> threadQuarkList
= ss
.getSubAttributes(-1, false);
137 /* We add the lowest value of each thread */
138 for (Integer threadQuark
: threadQuarkList
) {
139 int lowestMemoryQuark
= ss
.getQuarkRelative(threadQuark
, KernelMemoryAnalysisModule
.THREAD_LOWEST_MEMORY_VALUE
);
140 ITmfStateInterval lowestMemoryInterval
= kernelState
.get(lowestMemoryQuark
);
141 long lowestMemoryValue
= lowestMemoryInterval
.getStateValue().unboxLong();
142 // We want to add up a positive quantity.
143 totalKernelMemoryValuesShift
-= lowestMemoryValue
;
145 String tid
= ss
.getAttributeName(threadQuark
);
146 if (tid
.equals(fSelectedThread
)) {
147 // We want to add up a positive quantity.
148 selectThreadValuesShift
= -lowestMemoryValue
;
153 * We shift the two displayed lines up.
155 for (int i
= 0; i
< xvalues
.length
; i
++) {
156 totalKernelMemoryValues
[i
] += totalKernelMemoryValuesShift
;
157 selectedThreadValues
[i
] += selectThreadValuesShift
;
159 setSeries(Messages
.MemoryUsageViewer_Total
, totalKernelMemoryValues
);
160 if (fSelectedThread
!= NOT_SELECTED
) {
161 setSeries(fSelectedThread
, selectedThreadValues
);
165 } catch (TimeRangeException
| StateSystemDisposedException
| AttributeNotFoundException e
) {
166 Activator
.getDefault().logError(e
.getMessage(), e
);
171 * Set the selected thread ID, which will be graphed in this viewer
174 * The selected thread ID
176 public void setSelectedThread(String tid
) {
178 deleteSeries(fSelectedThread
);
179 fSelectedThread
= tid
;