--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTrace.java Thu Feb 11 15:32:31 2010 +0200
@@ -0,0 +1,1118 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.address;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.Function;
+import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
+import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+import com.nokia.carbide.cpp.pi.util.BinaryColorPalette;
+import com.nokia.carbide.cpp.pi.util.FunctionColorPalette;
+import com.nokia.carbide.cpp.pi.util.ThreadColorPalette;
+
+
+public class GppTrace extends GenericSampledTraceWithFunctions
+{
+ private static final long serialVersionUID = -658505849351283165L;
+
+ // sample times start at a set interval, monotonically increase by that interval, and end at a
+ // time equal to (number of elements - 1) times the interval
+ private boolean complete;
+
+ private transient GppSample[] sortedSamples = null;
+
+ // unchanging set of objects in the trace, ordered by total load
+ private transient Vector<ProfiledGeneric> sortedProfiledThreads;
+ private transient Vector<ProfiledGeneric> sortedProfiledBinaries;
+ private transient Vector<ProfiledGeneric> sortedProfiledFunctions;
+
+ // unchanging set of objects in the trace, sorted by index
+ private transient Vector<ProfiledGeneric> profiledThreads;
+ private transient Vector<ProfiledGeneric> profiledBinaries;
+ private transient Vector<ProfiledGeneric> profiledFunctions;
+
+ // selection time based objects in the trace
+ private transient int startSampleIndex; // first sample in the selection
+ private transient int endSampleIndex; // last sample in the selection
+
+ // sample counts for the currently selected area of the graph
+ private transient int[] threadSamples;
+ private transient int[] binarySamples;
+ private transient int[] functionSamples;
+
+ private transient GppTraceGraph[] graphs;
+
+ // tie palette to a trace instead of graph since trace is the data it represents
+ private transient ThreadColorPalette threadColorPalette = null;
+ private transient BinaryColorPalette binaryColorPalette = null;
+ private transient FunctionColorPalette functionColorPalette = null;
+
+ //protected int uid;
+
+ public GppTrace()
+ {
+ }
+
+ // for fast access, created a sorted array of samples
+ // this will remove duplicate times, find if times are missing, and
+ // find if times are increasing
+ public void sortGppSamples()
+ {
+ // check if already sorted
+ if (this.sortedSamples != null)
+ return;
+
+ int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+
+ complete = this.samples.size()*samplingInterval == this.getLastSampleNumber();
+
+ this.sortedSamples = new GppSample[this.samples.size()];
+
+ // fill the sorted array, assuming each sample time matches its (index+1)*samplingInterval
+ boolean sorted = true;
+ int arrayIndex = 0;
+ long lastTime = -1;
+
+ for (int i = 0, sampleTime = 0; i < this.samples.size(); i++) {
+ Object o = this.samples.get(i);
+ if (o instanceof GppSample) {
+ GppSample sample = (GppSample)o;
+
+ // don't copy duplicates
+ if (sample.sampleSynchTime == lastTime)
+ continue;
+
+ this.sortedSamples[arrayIndex++] = sample;
+ sampleTime += samplingInterval;
+
+ // make sure times are in increasing order
+ if (sample.sampleSynchTime < lastTime)
+ sorted = false;
+
+ lastTime = sample.sampleSynchTime;
+
+ if (sample.sampleSynchTime != sampleTime) {
+ this.complete = false;
+
+ // find the time it does match, in case one is missing
+ while (sample.sampleSynchTime > sampleTime)
+ sampleTime += samplingInterval;
+ }
+ } else {
+ // error case
+ this.sortedSamples = new GppSample[1];
+ this.sortedSamples[0].sampleSynchTime = -1;
+ this.complete = false;
+ return;
+ }
+ }
+
+ // if any duplicates, create a shorter array
+ if (arrayIndex != this.samples.size()) {
+ GppSample[] sampleObjects1 = new GppSample[this.samples.size()];
+ for (int i = 0; i < this.sortedSamples.length; i++)
+ sampleObjects1[i] = this.sortedSamples[i];
+ this.sortedSamples = sampleObjects1;
+ }
+
+ if (!sorted) {
+ // now we have to actually sort
+ Arrays.sort(this.sortedSamples, new Comparator<Object>() {
+
+ public int compare(Object arg0, Object arg1)
+ {
+ return (int) (((GppSample)arg0).sampleSynchTime - ((GppSample)arg1).sampleSynchTime);
+ }
+ });
+
+ // get rid of any duplicates and check for completeness
+ for (int i = 0, sampleTime = 0, length = this.sortedSamples.length; i < length; i++) {
+ GppSample sample = this.sortedSamples[i];
+
+ // don't copy duplicates
+ if (sample.sampleSynchTime == lastTime) {
+ for (int j = i; j < length - 1; j++) {
+ this.sortedSamples[j] = this.sortedSamples[j + 1];
+ }
+ length--;
+ this.complete = false;
+ continue;
+ }
+
+ sampleTime += samplingInterval;
+
+ if (sample.sampleSynchTime != sampleTime) {
+ this.complete = false;
+
+ // find the time it does match, in case one is missing
+ while (sample.sampleSynchTime > sampleTime)
+ sampleTime += samplingInterval;
+ }
+ }
+ }
+ }
+
+ public boolean isGppSampleComplete()
+ {
+ return this.complete;
+ }
+
+ public GppSample[] getSortedGppSamples()
+ {
+ return this.sortedSamples;
+ }
+
+ public GppSample getGppSample(int number)
+ {
+ return (GppSample)this.samples.elementAt(number);
+ }
+
+ public GenericTraceGraph getTraceGraph(int graphIndex, int uid)
+ {
+ return getGppGraph(graphIndex,uid);
+ }
+
+ public GppTraceGraph getGppGraph(int graphIndex, int uid)
+ {
+ if (graphs == null) {
+ graphs = new GppTraceGraph[3];
+ }
+
+ // note that graphIndex needs not match the index sent to GppTraceGraph
+ if ( (graphIndex == PIPageEditor.THREADS_PAGE)
+ || (graphIndex == PIPageEditor.BINARIES_PAGE)
+ || (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
+ if (graphs[graphIndex] == null)
+ graphs[graphIndex] = new GppTraceGraph(graphIndex, this, uid);
+ return graphs[graphIndex];
+ }
+
+ return null;
+ }
+
+ public GenericTraceGraph getTraceGraph(int graphIndex)
+ {
+ int uid = NpiInstanceRepository.getInstance().activeUid();
+ return getTraceGraph(graphIndex, uid);
+ }
+
+ public void refineTrace(FunctionResolver resolver)
+ {
+ super.refineTrace(resolver);
+ }
+
+ public int getSortedThreadsCount()
+ {
+ return this.sortedProfiledThreads.size();
+ }
+
+ public Enumeration<ProfiledGeneric> getSortedThreadsElements()
+ {
+ return this.sortedProfiledThreads.elements();
+ }
+
+ public Vector<ProfiledGeneric> getSortedThreads()
+ {
+ if (this.sortedProfiledThreads == null)
+ this.sortedProfiledThreads = new Vector<ProfiledGeneric>();
+ return this.sortedProfiledThreads;
+ }
+
+ public Vector<ProfiledGeneric> getIndexedThreads()
+ {
+ if (this.profiledThreads == null)
+ this.profiledThreads = new Vector<ProfiledGeneric>();
+ return this.profiledThreads;
+ }
+
+ public int getSortedBinariesCount()
+ {
+ return this.sortedProfiledBinaries.size();
+ }
+
+ public Enumeration<ProfiledGeneric> getSortedBinariesElements()
+ {
+ return this.sortedProfiledBinaries.elements();
+ }
+
+ public Vector<ProfiledGeneric> getSortedBinaries()
+ {
+ if (this.sortedProfiledBinaries == null)
+ this.sortedProfiledBinaries = new Vector<ProfiledGeneric>();
+ return this.sortedProfiledBinaries;
+ }
+
+ public Vector<ProfiledGeneric> getIndexedBinaries()
+ {
+ if (this.profiledBinaries == null)
+ this.profiledBinaries = new Vector<ProfiledGeneric>();
+ return this.profiledBinaries;
+ }
+
+ public int getSortedFunctionsCount()
+ {
+ return this.sortedProfiledFunctions.size();
+ }
+
+ public Enumeration<ProfiledGeneric> getSortedFunctionsElements()
+ {
+ return this.sortedProfiledFunctions.elements();
+ }
+
+ public Vector<ProfiledGeneric> getSortedFunctions()
+ {
+ if (this.sortedProfiledFunctions == null)
+ this.sortedProfiledFunctions = new Vector<ProfiledGeneric>();
+ return this.sortedProfiledFunctions;
+ }
+
+ public Vector<ProfiledGeneric> getIndexedFunctions()
+ {
+ if (this.profiledFunctions == null)
+ this.profiledFunctions = new Vector<ProfiledGeneric>();
+ return this.profiledFunctions;
+ }
+
+ /*
+ * Determine the threads, binaries, and functions associated with a time period
+ * from the start time up to and including the end time. If the times are equal,
+ * do not include any samples.
+ */
+ public void setSelectedArea() {
+ // create empty arrays to hold sample counts
+ this.threadSamples = new int[this.profiledThreads.size()];
+ this.binarySamples = new int[this.profiledBinaries.size()];
+ this.functionSamples = new int[this.profiledFunctions.size()];
+
+ double doubleStartTime = PIPageEditor.currentPageEditor().getStartTime();
+ double doubleEndTime = PIPageEditor.currentPageEditor().getEndTime();
+
+ int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$
+
+ GppSample[] sortedGppSamples = this.getSortedGppSamples();
+
+ // get the sample start time in integer multiples of milliseconds
+ startSampleIndex = ((int) ((doubleStartTime + 0.0005f)* 1000.0f))/samplingInterval;
+ if (startSampleIndex*samplingInterval < this.getFirstSampleNumber()) {
+ startSampleIndex = 0;
+ } else if (startSampleIndex > sortedGppSamples.length) {
+ startSampleIndex = sortedGppSamples.length - 1;
+ }
+
+ // get the sample end time in integer multiples of milliseconds
+ // NOTE: endSampleIndex is one past the last allowed index, so that when no time
+ // is selected startSampleIndex will equal end sample index
+ endSampleIndex = ((int) ((doubleEndTime + 0.0005f) * 1000.0f))/samplingInterval;
+ if (endSampleIndex*samplingInterval < this.getFirstSampleNumber()) {
+ endSampleIndex = 0;
+ } else if (endSampleIndex > sortedGppSamples.length) {
+ endSampleIndex = sortedGppSamples.length - 1;
+ }
+
+ if (this.isGppSampleComplete()) {
+ // find the sample counts in each category
+ // just use the start and end times as indices
+ for (int i = startSampleIndex; i < endSampleIndex; i++) {
+ threadSamples[sortedGppSamples[i].threadIndex]++;
+ binarySamples[sortedGppSamples[i].binaryIndex]++;
+ functionSamples[sortedGppSamples[i].functionIndex]++;
+ }
+ } else {
+ // use a binary search to find the first sample
+ int startIndex = 0;
+ GppSample sample = null;
+ int lowerBound = 0;
+ int upperBound = sortedGppSamples.length;
+ while (lowerBound <= upperBound) {
+ startIndex = (lowerBound + upperBound)/2;
+ sample = sortedGppSamples[startIndex];
+ if (startSampleIndex*samplingInterval == sample.sampleSynchTime) {
+ break;
+ } else if (sample.sampleSynchTime > startSampleIndex*samplingInterval)
+ upperBound = startIndex - 1;
+ else
+ lowerBound = startIndex + 1;
+ }
+
+ // if there is no match, it's okay if the sample's time is larger than the
+ // startTime, but not if the startTime is less
+ if (sample.sampleSynchTime < startSampleIndex*samplingInterval)
+ startIndex++;
+ endSampleIndex = startIndex;
+
+ // find the sample counts in each category
+ // use comparisons to find the end sample
+ if (startIndex < this.samples.size()) {
+ while (sample.sampleSynchTime < endSampleIndex*samplingInterval) {
+ threadSamples[sample.threadIndex]++;
+ binarySamples[sample.binaryIndex]++;
+ functionSamples[sample.functionIndex]++;
+
+ endSampleIndex++;
+ if (endSampleIndex == sortedGppSamples.length)
+ break;
+
+ sample = sortedGppSamples[endSampleIndex];
+ }
+
+ if ( (endSampleIndex == this.samples.size())
+ || (sample.sampleSynchTime > endSampleIndex*samplingInterval))
+ endSampleIndex--;
+ }
+ endSampleIndex++;
+ }
+
+ // set the sample counts and loads for all the trace-related graphs
+ // set the % load strings only for a tab's base table
+ // To optimise this, we could just set the main sample count and load per graph (e.g., thread stuff for page 0)
+ // To ptimise this, we could check drawMode and ignore sample counts when tables don't show them
+ // requires sample counts, a
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ // NOTE: For slightly better performance, might have other functions rely on this one zeroing out sample counts
+ for (int i = 0; i < this.profiledThreads.size(); i++) {
+ ProfiledGeneric pThread = this.profiledThreads.elementAt(i);
+ pThread.setSampleCount(PIPageEditor.THREADS_PAGE, this.threadSamples[i]);
+ pThread.setLoadAndString(PIPageEditor.THREADS_PAGE, (float)(this.threadSamples[i] * percentPerSample));
+ }
+
+ for (int i = 0; i < this.profiledBinaries.size(); i++) {
+ ProfiledGeneric pBinary = this.profiledBinaries.elementAt(i);
+ pBinary.setSampleCount(PIPageEditor.BINARIES_PAGE, this.binarySamples[i]);
+ pBinary.setLoadAndString(PIPageEditor.BINARIES_PAGE, (float)(this.binarySamples[i] * percentPerSample));
+ }
+
+ for (int i = 0; i < this.profiledFunctions.size(); i++) {
+ ProfiledGeneric pFunction = this.profiledFunctions.elementAt(i);
+ pFunction.setSampleCount(PIPageEditor.FUNCTIONS_PAGE, this.functionSamples[i]);
+ pFunction.setLoadAndString(PIPageEditor.FUNCTIONS_PAGE, (float)(this.functionSamples[i] * percentPerSample));
+ }
+ }
+
+ /*
+ * Based on a graph's set of enabled threads, produce a set of binaries, and
+ * disable all other binaries for that graph
+ */
+ public Vector<ProfiledGeneric> setThreadBinary(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphBinaries = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
+
+ // disable all binaries for the given graph
+ for (int i = 0; i < this.profiledBinaries.size(); i++) {
+ ProfiledGeneric pBinary = this.profiledBinaries.elementAt(i);
+ pBinary.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find binaries below the threshold
+ boolean lowBinary;
+ ProfiledThreshold thresholdBinary = this.graphs[graphIndex].getThresholdBinary();
+ thresholdBinary.init(graphIndex);
+
+ // for each binary in the selected sample range, if its thread is enabled, add the binary
+ int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledThread pThread = (ProfiledThread)
+ this.profiledThreads.elementAt(sample.threadIndex);
+
+ if (pThread.isEnabled(graphIndex)) {
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+ String binaryName = pBinary.getNameString();
+
+ lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
+
+ if (!foundBinaries.containsKey(binaryName)) {
+ pBinary.setEnabled(graphIndex, true);
+ foundBinaries.put(binaryName, binaryName);
+ if (lowBinary) {
+ thresholdBinary.addItem(graphIndex, pBinary, 1);
+ } else {
+ pBinary.setSampleCount(graphIndex, 1);
+ graphBinaries.add(pBinary);
+ }
+ } else {
+ if (lowBinary)
+ thresholdBinary.incSampleCount(graphIndex);
+ else
+ pBinary.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphBinaries.size(); i++) {
+ ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
+ pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphBinaries;
+ }
+
+ /*
+ * Based on a graph's set of enabled threads and binaries, produce a set of functions, and
+ * disable all other functions for that graph
+ */
+ public Vector<ProfiledGeneric> setThreadBinaryFunction(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphFunctions = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
+
+ // disable all functions for the given graph
+ for (int i = 0; i < this.profiledFunctions.size(); i++) {
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(i);
+ pFunction.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find functions below the threshold
+ boolean lowFunction;
+ ProfiledThreshold thresholdFunction = this.graphs[graphIndex].getThresholdFunction();
+ thresholdFunction.init(graphIndex);
+
+ // for each function in the selected sample range, if its thread and binary are enabled,
+ // add the function
+ int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+
+ if (pThread.isEnabled(graphIndex) && pBinary.isEnabled(graphIndex)) {
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+ String functionName = pFunction.getNameString();
+
+ lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
+
+ if (!foundFunctions.containsKey(functionName)) {
+ pFunction.setEnabled(graphIndex, true);
+ foundFunctions.put(functionName, functionName);
+ if (lowFunction) {
+ thresholdFunction.addItem(graphIndex, pFunction, 1);
+ } else {
+ pFunction.setSampleCount(graphIndex, 1);
+ graphFunctions.add(pFunction);
+ }
+ } else {
+ if (lowFunction)
+ thresholdFunction.incSampleCount(graphIndex);
+ else
+ pFunction.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphFunctions.size(); i++) {
+ ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
+ pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex)* percentPerSample));
+ }
+
+ return graphFunctions;
+ }
+
+ public Vector<ProfiledGeneric> setBinaryThreadFunction(int graphIndex)
+ {
+ return setThreadBinaryFunction(graphIndex);
+ }
+
+ /*
+ * Based on a graph's set of enabled threads, produce a set of functions, and
+ * disable all other functions for that graph
+ */
+ public Vector<ProfiledGeneric> setThreadFunction(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphFunctions = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
+
+ // disable all functions for the given graph
+ for (int i = 0; i < this.profiledFunctions.size(); i++) {
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(i);
+ pFunction.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find functions below the threshold
+ boolean lowFunction;
+ ProfiledThreshold thresholdFunction = this.graphs[graphIndex].getThresholdFunction();
+ thresholdFunction.init(graphIndex);
+
+ // for each function in the selected sample range, if its thread is enabled, add the function
+ int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+
+ if (pThread.isEnabled(graphIndex)) {
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+ String functionName = pFunction.getNameString();
+
+ lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
+
+ if (!foundFunctions.containsKey(functionName)) {
+ pFunction.setEnabled(graphIndex, true);
+ foundFunctions.put(functionName, functionName);
+ if (lowFunction) {
+ thresholdFunction.addItem(graphIndex, pFunction, 1);
+ } else {
+ pFunction.setSampleCount(graphIndex, 1);
+ graphFunctions.add(pFunction);
+ }
+ } else {
+ if (lowFunction)
+ thresholdFunction.incSampleCount(graphIndex);
+ else
+ pFunction.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphFunctions.size(); i++) {
+ ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
+ pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphFunctions;
+ }
+
+ /*
+ * Based on a graph's set of enabled threads and functions, produce a set of binaries, and
+ * disable all other binaries for that graph
+ */
+ public Vector<ProfiledGeneric> setThreadFunctionBinary(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphBinaries = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
+
+ // disable all binaries for the given graph
+ for (int i = 0; i < this.profiledBinaries.size(); i++) {
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(i);
+ pBinary.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find binaries below the threshold
+ boolean lowBinary;
+ ProfiledThreshold thresholdBinary = this.graphs[graphIndex].getThresholdBinary();
+ thresholdBinary.init(graphIndex);
+
+ // for each binary in the selected sample range, if its thread and function are enabled,
+ // add the binary
+ int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+
+ if (pThread.isEnabled(graphIndex) && pFunction.isEnabled(graphIndex)) {
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+ String binaryName = pBinary.getNameString();
+
+ lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
+
+ if (!foundBinaries.containsKey(binaryName)) {
+ pBinary.setEnabled(graphIndex, true);
+ foundBinaries.put(binaryName, binaryName);
+ if (lowBinary) {
+ thresholdBinary.addItem(graphIndex, pBinary, 1);
+ } else {
+ pBinary.setSampleCount(graphIndex, 1);
+ graphBinaries.add(pBinary);
+ }
+ } else {
+ if (lowBinary)
+ thresholdBinary.incSampleCount(graphIndex);
+ else
+ pBinary.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphBinaries.size(); i++) {
+ ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
+ pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphBinaries;
+ }
+
+ public Vector<ProfiledGeneric> setFunctionThreadBinary(int graphIndex)
+ {
+ return setThreadFunctionBinary(graphIndex);
+ }
+
+ /*
+ * Based on a graph's set of enabled binaries, produce a set of threads, and
+ * disable all other threads for that graph
+ */
+ public Vector<ProfiledGeneric> setBinaryThread(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphThreads = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundThreads = new Hashtable<String,String>();
+
+ // disable all threads for the given graph
+ for (int i = 0; i < this.profiledThreads.size(); i++) {
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(i);
+ pThread.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find threads below the threshold
+ boolean lowThread;
+ ProfiledThreshold thresholdThread = this.graphs[graphIndex].getThresholdThread();
+ thresholdThread.init(graphIndex);
+
+ // for each thread in the selected sample range, if its binary is enabled, add the thread
+ int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+
+ if (pBinary.isEnabled(graphIndex)) {
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+ String threadName = pThread.getNameString();
+
+ lowThread = pThread.getTotalSampleCount() < threadThreshold;
+
+ if (!foundThreads.containsKey(threadName)) {
+ pThread.setEnabled(graphIndex, true);
+ foundThreads.put(threadName, threadName);
+ if (lowThread) {
+ thresholdThread.addItem(graphIndex, pThread, 1);
+ } else {
+ pThread.setSampleCount(graphIndex, 1);
+ graphThreads.add(pThread);
+ }
+ } else {
+ if (lowThread)
+ thresholdThread.incSampleCount(graphIndex);
+ else
+ pThread.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphThreads.size(); i++) {
+ ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
+ pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphThreads;
+ }
+
+ /*
+ * Based on a graph's set of enabled functions, produce a set of threads, and
+ * disable all other threads for that graph
+ */
+ public Vector<ProfiledGeneric> setFunctionThread(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphThreads = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundThreads = new Hashtable<String,String>();
+
+ // disable all threads for the given graph
+ for (int i = 0; i < this.profiledThreads.size(); i++) {
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(i);
+ pThread.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find threads below the threshold
+ boolean lowThread;
+ ProfiledThreshold thresholdThread = this.graphs[graphIndex].getThresholdThread();
+ thresholdThread.init(graphIndex);
+
+ // for each thread in the selected sample range, if its function is enabled, add the thread
+ int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+
+ if (pFunction.isEnabled(graphIndex)) {
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+ String threadName = pThread.getNameString();
+
+ lowThread = pThread.getTotalSampleCount() < threadThreshold;
+
+ if (!foundThreads.containsKey(threadName)) {
+ pThread.setEnabled(graphIndex, true);
+ foundThreads.put(threadName, threadName);
+ if (lowThread) {
+ thresholdThread.addItem(graphIndex, pThread, 1);
+ } else {
+ pThread.setSampleCount(graphIndex, 1);
+ graphThreads.add(pThread);
+ }
+ } else {
+ if (lowThread)
+ thresholdThread.incSampleCount(graphIndex);
+ else
+ pThread.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphThreads.size(); i++) {
+ ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
+ pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphThreads;
+ }
+
+ /*
+ * Based on a graph's set of enabled binaries and functions, produce a set of threads, and
+ * disable all other threads for that graph
+ */
+ public Vector<ProfiledGeneric> setBinaryFunctionThread(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphThreads = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundThreads = new Hashtable<String,String>();
+
+ // disable all threads for the given graph
+ for (int i = 0; i < this.profiledThreads.size(); i++) {
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(i);
+ pThread.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find threads below the threshold
+ boolean lowThread;
+ ProfiledThreshold thresholdThread = this.graphs[graphIndex].getThresholdThread();
+ thresholdThread.init(graphIndex);
+
+ // for each thread in the selected sample range, if its binary and function are enabled,
+ // add the thread
+ int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+
+ if (pBinary.isEnabled(graphIndex)
+ && (pFunction.isEnabled(graphIndex))) {
+ ProfiledThread pThread = (ProfiledThread) this.profiledThreads.elementAt(sample.threadIndex);
+ String threadName = pThread.getNameString();
+
+ lowThread = pThread.getTotalSampleCount() < threadThreshold;
+
+ if (!foundThreads.containsKey(threadName)) {
+ pThread.setEnabled(graphIndex, true);
+ foundThreads.put(threadName, threadName);
+ if (lowThread) {
+ thresholdThread.addItem(graphIndex, pThread, 1);
+ } else {
+ pThread.setSampleCount(graphIndex, 1);
+ graphThreads.add(pThread);
+ }
+ } else {
+ if (lowThread)
+ thresholdThread.incSampleCount(graphIndex);
+ else
+ pThread.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphThreads.size(); i++) {
+ ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
+ pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphThreads;
+ }
+
+ public Vector<ProfiledGeneric> setFunctionBinaryThread(int graphIndex)
+ {
+ return setBinaryFunctionThread(graphIndex);
+ }
+
+ /*
+ * Based on a graph's set of enabled functions, produce a set of binaries, and
+ * disable all other binaries for that graph
+ */
+ public Vector<ProfiledGeneric> setFunctionBinary(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphBinaries = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
+
+ // disable all binaries for the given graph
+ for (int i = 0; i < this.profiledBinaries.size(); i++) {
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(i);
+ pBinary.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find binaries below the threshold
+ boolean lowBinary;
+ ProfiledThreshold thresholdBinary = this.graphs[graphIndex].getThresholdBinary();
+ thresholdBinary.init(graphIndex);
+
+ // for each binary in the selected sample range, if its function is enabled, add the binary
+ int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+
+ if (pFunction.isEnabled(graphIndex)) {
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+ String binaryName = pBinary.getNameString();
+
+ lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
+
+ if (!foundBinaries.containsKey(binaryName)) {
+ pBinary.setEnabled(graphIndex, true);
+ foundBinaries.put(binaryName, binaryName);
+ if (lowBinary) {
+ thresholdBinary.addItem(graphIndex, pBinary, 1);
+ } else {
+ pBinary.setSampleCount(graphIndex, 1);
+ graphBinaries.add(pBinary);
+ }
+ } else {
+ if (lowBinary)
+ thresholdBinary.incSampleCount(graphIndex);
+ else
+ pBinary.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphBinaries.size(); i++) {
+ ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
+ pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphBinaries;
+ }
+
+ /*
+ * Based on a graph's set of enabled binaries, produce a set of functions, and
+ * disable all other functions for that graph
+ */
+ public Vector<ProfiledGeneric> setBinaryFunction(int graphIndex)
+ {
+ Vector<ProfiledGeneric> graphFunctions = new Vector<ProfiledGeneric>();
+ Hashtable<String,String> foundFunctions = new Hashtable<String,String>();
+
+ // disable all functions for the given graph
+ for (int i = 0; i < this.profiledFunctions.size(); i++) {
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(i);
+ pFunction.setEnabled(graphIndex, false);
+ }
+
+ // set up in case we find functions below the threshold
+ boolean lowFunction;
+ ProfiledThreshold thresholdFunction = this.graphs[graphIndex].getThresholdFunction();
+ thresholdFunction.init(graphIndex);
+
+ // for each function in the selected sample range, if its binary is enabled, add the function
+ int functionThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
+ for (int i = this.startSampleIndex; i < this.endSampleIndex; i++) {
+ GppSample sample = this.sortedSamples[i];
+ ProfiledBinary pBinary = (ProfiledBinary) this.profiledBinaries.elementAt(sample.binaryIndex);
+
+ if (pBinary.isEnabled(graphIndex)) {
+ ProfiledFunction pFunction = (ProfiledFunction) this.profiledFunctions.elementAt(sample.functionIndex);
+ String functionName = pFunction.getNameString();
+
+ lowFunction = pFunction.getTotalSampleCount() < functionThreshold;
+
+ if (!foundFunctions.containsKey(functionName)) {
+ pFunction.setEnabled(graphIndex, true);
+ foundFunctions.put(functionName, functionName);
+ if (lowFunction) {
+ thresholdFunction.addItem(graphIndex, pFunction, 1);
+ } else {
+ pFunction.setSampleCount(graphIndex, 1);
+ graphFunctions.add(pFunction);
+ }
+ } else {
+ if (lowFunction)
+ thresholdFunction.incSampleCount(graphIndex);
+ else
+ pFunction.incSampleCount(graphIndex);
+ }
+ }
+ }
+
+ // since we are not converting float % load to string % load inside the table viewers, do it here
+ double percentPerSample;
+ if (startSampleIndex == endSampleIndex)
+ percentPerSample = 0.0;
+ else
+ percentPerSample = 100.0 / ((double)(this.endSampleIndex - this.startSampleIndex));
+
+ for (int i = 0; i < graphFunctions.size(); i++) {
+ ProfiledFunction pFunction = (ProfiledFunction) graphFunctions.elementAt(i);
+ pFunction.setLoadAndString(graphIndex, (float)(pFunction.getSampleCount(graphIndex) * percentPerSample));
+ }
+
+ return graphFunctions;
+ }
+
+ public int getStartSampleIndex()
+ {
+ return this.startSampleIndex;
+ }
+
+ public int getEndSampleIndex()
+ {
+ return this.endSampleIndex;
+ }
+
+ public int[] getThreadSampleCounts()
+ {
+ return this.threadSamples;
+ }
+
+ public int[] getBinarySampleCounts()
+ {
+ return this.binarySamples;
+ }
+
+ public int[] getFunctionSampleCounts()
+ {
+ return this.functionSamples;
+ }
+
+ public void setThreadSampleCounts(int[] sampleCounts)
+ {
+ this.threadSamples = sampleCounts;
+ }
+
+ public void setBinarySampleCounts(int[] sampleCounts)
+ {
+ this.binarySamples = sampleCounts;
+ }
+
+ public void setFunctionSampleCounts(int[] sampleCounts)
+ {
+ this.functionSamples = sampleCounts;
+ }
+
+ public void setThreadColorPalette(ThreadColorPalette tableColorPalette) {
+ this.threadColorPalette = tableColorPalette;
+ }
+
+ public ThreadColorPalette getThreadColorPalette() {
+ if (this.threadColorPalette == null) {
+ this.threadColorPalette = new ThreadColorPalette();
+ }
+ return this.threadColorPalette;
+ }
+
+ public void setBinaryColorPalette(BinaryColorPalette tableColorPalette) {
+ this.binaryColorPalette = tableColorPalette;
+ }
+
+ public BinaryColorPalette getBinaryColorPalette() {
+ if (this.binaryColorPalette == null) {
+ this.binaryColorPalette = new BinaryColorPalette();
+ }
+ return this.binaryColorPalette;
+ }
+
+ public void setFunctionColorPalette(FunctionColorPalette tableColorPalette) {
+ this.functionColorPalette = tableColorPalette;
+ }
+
+ public FunctionColorPalette getFunctionColorPalette() {
+ if (this.functionColorPalette == null) {
+ this.functionColorPalette = new FunctionColorPalette();
+ }
+ return this.functionColorPalette;
+ }
+
+ @Override
+ public void finalizeTrace() {
+ samples.trimToSize();
+ for (int i = 0; i < samples.size(); i++) {
+ GppSample sample = (GppSample) samples.get(i);
+
+ if (sample.currentFunctionItt == null && sample.currentFunctionSym == null) {
+ sample.currentFunctionItt = new Function(Messages.getString("GppTrace.functionNotFound1") + Long.toHexString(sample.programCounter) + Messages.getString("GppTrace.functionNotFound2"), //$NON-NLS-1$ //$NON-NLS-2$
+ new Long(sample.programCounter),
+ Messages.getString("GppTrace.binaryNotFound1") + Long.toHexString(sample.programCounter) + Messages.getString("GppTrace.binarynotFound2")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+}