Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: fcb2c06ed0fde3aaa34169dfd324e14f1fe3a3c4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**********************************************************************
 * Copyright (c) 2014 Ericsson, École Polytechnique de Montréal
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Bernd Hufmann - Initial API and implementation
 *   Geneviève Bastien - Create and use base class for XY plots
 **********************************************************************/

package org.eclipse.linuxtools.internal.lttng2.ust.ui.views.memusage;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.linuxtools.internal.lttng2.ust.core.memoryusage.UstMemoryStrings;
import org.eclipse.linuxtools.internal.tmf.core.Activator;
import org.eclipse.linuxtools.lttng2.ust.core.analysis.memory.UstMemoryAnalysisModule;
import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException;
import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule;
import org.eclipse.linuxtools.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer;
import org.eclipse.swt.widgets.Composite;

/**
 * Memory usage view
 *
 * @author Matthew Khouzam
 */
@SuppressWarnings("restriction")
public class MemoryUsageViewer extends TmfCommonXLineChartViewer {

    private TmfStateSystemAnalysisModule fModule = null;

    private final Map<Integer, double[]> fYValues = new HashMap<>();
    private final Map<Integer, Integer> fMemoryQuarks = new HashMap<>();
    private final Map<Integer, String> fSeriesName = new HashMap<>();

    private static final int BYTES_TO_KB = 1024;

    // Timeout between updates in the updateData thread
    private static final long BUILD_UPDATE_TIMEOUT = 500;

    /**
     * Constructor
     *
     * @param parent
     *            parent view
     */
    public MemoryUsageViewer(Composite parent) {
        super(parent, Messages.MemoryUsageViewer_Title, Messages.MemoryUsageViewer_XAxis, Messages.MemoryUsageViewer_YAxis);
    }

    @Override
    protected void initializeDataSource() {
        if (getTrace() != null) {
            fModule = getTrace().getAnalysisModuleOfClass(TmfStateSystemAnalysisModule.class, UstMemoryAnalysisModule.ID);
            if (fModule == null) {
                return;
            }
            fModule.schedule();
        }
    }

    @Override
    protected void updateData(long start, long end, int nb, IProgressMonitor monitor) {
        try {
            if (getTrace() == null || fModule == null) {
                return;
            }
            fModule.waitForInitialization();
            ITmfStateSystem ss = fModule.getStateSystem();
            /* Don't wait for the module completion, when it's ready, we'll know */
            if (ss == null) {
                return;
            }

            double[] xvalues = getXAxis(start, end, nb);
            setXAxis(xvalues);

            boolean complete = false;
            long currentEnd = start;

            while (!complete && currentEnd < end) {
                if (monitor.isCanceled()) {
                    return;
                }
                complete = ss.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
                currentEnd = ss.getCurrentEndTime();
                List<Integer> tidQuarks = ss.getSubAttributes(-1, false);
                long traceStart = getStartTime();
                long traceEnd = getEndTime();
                long offset = this.getTimeOffset();

                /* Initialize quarks and series names */
                for (int quark : tidQuarks) {
                    fYValues.put(quark, new double[xvalues.length]);
                    fMemoryQuarks.put(quark, ss.getQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_MEMORY_ATTRIBUTE));
                    int procNameQuark = ss.getQuarkRelative(quark, UstMemoryStrings.UST_MEMORY_PROCNAME_ATTRIBUTE);
                    try {
                        ITmfStateValue procnameValue = ss.querySingleState(start, procNameQuark).getStateValue();
                        String procname = new String();
                        if (!procnameValue.isNull()) {
                            procname = procnameValue.unboxStr();
                        }
                        fSeriesName.put(quark, new String(procname + ' ' + '(' + ss.getAttributeName(quark) + ')').trim());
                    } catch (TimeRangeException e) {
                        fSeriesName.put(quark, '(' + ss.getAttributeName(quark) + ')');
                    }
                }

                /*
                 * TODO: It should only show active threads in the time range. If a
                 * tid does not have any memory value (only 1 interval in the time
                 * range with value null or 0), then its series should not be
                 * displayed.
                 */
                double yvalue = 0.0;
                for (int i = 0; i < xvalues.length; i++) {
                    if (monitor.isCanceled()) {
                        return;
                    }
                    double x = xvalues[i];
                    long time = (long) x + offset;
                    // make sure that time is in the trace range after double to
                    // long conversion
                    time = time < traceStart ? traceStart : time;
                    time = time > traceEnd ? traceEnd : time;

                    for (int quark : tidQuarks) {
                        try {
                            yvalue = ss.querySingleState(time, fMemoryQuarks.get(quark)).getStateValue().unboxLong() / BYTES_TO_KB;
                            fYValues.get(quark)[i] = yvalue;
                        } catch (TimeRangeException e) {
                            fYValues.get(quark)[i] = 0;
                        }
                    }
                }
                for (int quark : tidQuarks) {
                    setSeries(fSeriesName.get(quark), fYValues.get(quark));
                }
                updateDisplay();
            }
        } catch (AttributeNotFoundException | StateValueTypeException | StateSystemDisposedException e) {
            Activator.logError("Error updating the data of the Memory usage view", e); //$NON-NLS-1$
        }
    }

}

Back to the top