sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTrace.java
changeset 5 844b047e260d
child 12 ae255c9aa552
equal deleted inserted replaced
4:615035072f7e 5:844b047e260d
       
     1 /*
       
     2  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description: 
       
    15  *
       
    16  */
       
    17 
       
    18 package com.nokia.carbide.cpp.pi.irq;
       
    19 
       
    20 import java.util.ArrayList;
       
    21 import java.util.Enumeration;
       
    22 import java.util.HashSet;
       
    23 import java.util.Hashtable;
       
    24 import java.util.Vector;
       
    25 
       
    26 import org.eclipse.swt.graphics.RGB;
       
    27 
       
    28 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
       
    29 import com.nokia.carbide.cpp.internal.pi.model.GenericSample;
       
    30 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTraceWithFunctions;
       
    31 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
       
    32 import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository;
       
    33 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
       
    34 import com.nokia.carbide.cpp.pi.address.GppTrace;
       
    35 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
       
    36 
       
    37 /**
       
    38  * Class containing all samples from one Irq trace
       
    39  */
       
    40 public class IrqTrace extends GenericSampledTraceWithFunctions {
       
    41 
       
    42 	private static final long serialVersionUID = 5128848053984932839L;
       
    43 
       
    44 	private transient IrqTraceGraph[] graphs;
       
    45 
       
    46 	/* Hashtable containing thread id's and swi offsets */
       
    47 	private Hashtable<Long, Integer> threadToOffset;
       
    48 
       
    49 	/* Hashtable containing thread id's and names */
       
    50 	private Hashtable<Long, String> threadToName;
       
    51 
       
    52 	/* Hashtable containing Irq lines and offsets */
       
    53 	private Hashtable<Long, Integer> irqToOffset;
       
    54 
       
    55 	/* Vector containing all thread wrappers */
       
    56 	private transient Vector<SwiThreadWrapper> allThreadWrappers;
       
    57 
       
    58 	/* Hashtable containing thread id's and all samples from that thread */
       
    59 	private transient Hashtable<Long, IrqSampleTypeWrapper> swiTable;
       
    60 
       
    61 	/* Hashtable containing irq line id's and all samples from that line */
       
    62 	private transient Hashtable<Long, IrqSampleTypeWrapper> irqTable;
       
    63 
       
    64 	/* Hashtable containing thread names functions */
       
    65 	private transient Hashtable<String, Hashtable<String, ArrayList<Long>>> threadsToFunctions;
       
    66 
       
    67 	/* All colors in use */
       
    68 	private transient HashSet<RGB> colorSet;
       
    69 	
       
    70 	/* Colors in functions and irq lines */
       
    71 	private Hashtable<String, RGB> colorsOfThreadsAndLines;
       
    72 
       
    73 	/* maximum amount of swi interrupts at one time frame */
       
    74 	private int maxAmountOfSWISamples;
       
    75 
       
    76 	/* maximum amount of irq interrupts at one time frame */
       
    77 	private int maxAmountOfIRQSamples;
       
    78 
       
    79 	/* Boolean value that is false if no function names is found from trace
       
    80 	 * (No Symbol files imported) 
       
    81 	 */
       
    82 	boolean functionNamesFound = false;
       
    83 	
       
    84 	/**
       
    85 	 * getter for trace graph
       
    86 	 * 
       
    87 	 * @param graphIndex
       
    88 	 *            index of the graph
       
    89 	 * @return graph
       
    90 	 */
       
    91 	public GenericTraceGraph getTraceGraph(int graphIndex) {
       
    92 		if (graphs == null) {
       
    93 			graphs = new IrqTraceGraph[3];
       
    94 		}
       
    95 		// note that graphIndex need not match the index sent to TraceGraph
       
    96 		if ((graphIndex == PIPageEditor.THREADS_PAGE)
       
    97 				|| (graphIndex == PIPageEditor.BINARIES_PAGE)
       
    98 				|| (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) {
       
    99 			int uid = NpiInstanceRepository.getInstance().activeUid();
       
   100 			
       
   101 			if(graphs[graphIndex] != null){
       
   102 				return graphs[graphIndex];
       
   103 			}
       
   104 			
       
   105 			// get first item that is null in graph array
       
   106 			int index = 0;
       
   107 			
       
   108 			while(index < graphs.length){
       
   109 				if( graphs[index] == null){
       
   110 					break;
       
   111 				}
       
   112 				index++;
       
   113 			}
       
   114 			if(index < graphs.length){
       
   115 				graphs[index] = new IrqTraceGraph(index, this, uid);
       
   116 				return graphs[index];
       
   117 			}
       
   118 			
       
   119 		}
       
   120 		return null;
       
   121 	}
       
   122 
       
   123 	/**
       
   124 	 * Fetches thread name for one sample from the address plug-in
       
   125 	 * 
       
   126 	 * @param sample
       
   127 	 *            sample
       
   128 	 * @return thread name
       
   129 	 */
       
   130 	@SuppressWarnings("unchecked")
       
   131 	private String getThreadName(IrqSample sample) {
       
   132 
       
   133 		if (sample.getType() == IrqSample.TYPE_SWI) {
       
   134 			// fetch trace information from address plug-in
       
   135 			ParsedTraceData ptd = TraceDataRepository.getInstance().getTrace(
       
   136 					NpiInstanceRepository.getInstance().activeUid(),
       
   137 					GppTrace.class);
       
   138 
       
   139 			// if trace data or static data cannot be found
       
   140 			if (ptd == null || ptd.staticData == null) {
       
   141 				return Messages.IrqTrace_0
       
   142 						+ Long.toHexString(sample.getThreadValue());
       
   143 			}
       
   144 
       
   145 			// Get that contains name for thread
       
   146 			ArrayList al = ptd.staticData.getColumnMatch(Messages.IrqTrace_1,
       
   147 					Messages.IrqTrace_2, new Long(sample.getThreadValue()));
       
   148 			if (al.size() > 0) {
       
   149 				return (String) al.get(0);
       
   150 			} else {
       
   151 				return Messages.IrqTrace_3
       
   152 						+ Long.toHexString(sample.getThreadValue());
       
   153 			}
       
   154 
       
   155 		}
       
   156 		return Messages.IrqTrace_4;
       
   157 	}
       
   158 
       
   159 	/**
       
   160 	 * Gathers data that is needed for drawing graph.
       
   161 	 */
       
   162 	public void gatherDrawData() {
       
   163 
       
   164 		boolean readThreadNamesFromTrace = false;
       
   165 
       
   166 		// if hash containing thread names is not found(meaning that dat file
       
   167 		// has just been imported) load thread names from trace.
       
   168 		if (threadToName == null) {
       
   169 			threadToName = new Hashtable<Long, String>();
       
   170 			readThreadNamesFromTrace = true;
       
   171 		}
       
   172 		
       
   173 		if(colorsOfThreadsAndLines == null){
       
   174 			colorsOfThreadsAndLines = new Hashtable<String, RGB>();
       
   175 		}
       
   176 
       
   177 		// reset all vectors and Hashtables that are just for optimizing drawing
       
   178 		allThreadWrappers = new Vector<SwiThreadWrapper>();
       
   179 		swiTable = new Hashtable<Long, IrqSampleTypeWrapper>();
       
   180 		irqTable = new Hashtable<Long, IrqSampleTypeWrapper>();
       
   181 		threadToOffset = new Hashtable<Long, Integer>();
       
   182 		this.irqToOffset = new Hashtable<Long, Integer>();
       
   183 		threadsToFunctions = new Hashtable<String, Hashtable<String, ArrayList<Long>>>();
       
   184 		colorSet = new HashSet<RGB>();
       
   185 		Hashtable<Long, Hashtable<Long, Integer>> irqLines = new Hashtable<Long, Hashtable<Long, Integer>>();
       
   186 
       
   187 		int swiOffset = 0;
       
   188 		int irqOffset = 0;
       
   189 
       
   190 		maxAmountOfSWISamples = 1;
       
   191 		maxAmountOfIRQSamples = 1;
       
   192 		int amountOfSamples = 0;
       
   193 		long previousTimeCode = 0;
       
   194 
       
   195 		// go thru all samples from trace
       
   196 		Enumeration<GenericSample> enumeration = this.getSamples();
       
   197 		while (enumeration.hasMoreElements()) {
       
   198 			IrqSample sample = (IrqSample) enumeration.nextElement();
       
   199 			long val = 0;
       
   200 			long valL = 0;
       
   201 			Hashtable<Long, IrqSampleTypeWrapper> table = new Hashtable<Long, IrqSampleTypeWrapper>();
       
   202 
       
   203 			// if this is software interrupt
       
   204 			if (sample.getType() == IrqSample.TYPE_SWI) {
       
   205 				val = sample.getLrValue();
       
   206 				table = swiTable;
       
   207 
       
   208 				String threadName = Messages.IrqTrace_5;
       
   209 				// Get thread name
       
   210 				if (readThreadNamesFromTrace) {
       
   211 					threadName = getThreadName(sample);
       
   212 				} else {
       
   213 					threadName = threadToName.get(sample.getThreadValue());
       
   214 				}
       
   215 
       
   216 				if(sample.getFunction()!= null){
       
   217 					
       
   218 					this.functionNamesFound = true;
       
   219 					
       
   220 					// Add thread into threadsToFunctions hash if needed
       
   221 					if (!threadsToFunctions.containsKey(threadName)) {
       
   222 						// Create new item into thread section
       
   223 						Hashtable<String, ArrayList<Long>> functionTable = new Hashtable<String, ArrayList<Long>>();
       
   224 						ArrayList<Long> list = new ArrayList<Long>();
       
   225 						list.add(sample.sampleSynchTime);
       
   226 						functionTable.put(sample.getFunction().getFunctionName(), list);
       
   227 						threadsToFunctions.put(threadName, functionTable);
       
   228 						previousTimeCode = sample.sampleSynchTime;
       
   229 						amountOfSamples = 1;
       
   230 	
       
   231 					} else {
       
   232 						// add sample to existing thread
       
   233 	
       
   234 						// check if previous sample from this thread was from same
       
   235 						// time frame and increase amountOfSamples if needed
       
   236 						if (sample.sampleSynchTime == previousTimeCode) {
       
   237 							amountOfSamples++;
       
   238 						} else {
       
   239 							// check is amount of samples from previous tim frame
       
   240 							// was greater than maximum amount of interrupts so far
       
   241 							if (amountOfSamples > maxAmountOfSWISamples) {
       
   242 								maxAmountOfSWISamples = amountOfSamples;
       
   243 							}
       
   244 							amountOfSamples = 0;
       
   245 							previousTimeCode = sample.sampleSynchTime;
       
   246 						}
       
   247 	
       
   248 						// get thread's hashtable containing all its functions
       
   249 						Hashtable<String, ArrayList<Long>> functionSet = threadsToFunctions
       
   250 								.get(threadName);
       
   251 	
       
   252 						String functionName = sample.getFunction().getFunctionName();
       
   253 	
       
   254 						if (!functionSet.containsKey(functionName)) {
       
   255 							// add new function into table
       
   256 							ArrayList<Long> list = new ArrayList<Long>();
       
   257 							list.add(sample.sampleSynchTime);
       
   258 							functionSet
       
   259 									.put(sample.getFunction().getFunctionName(), list);
       
   260 						} else {
       
   261 							functionSet.get(functionName).add(
       
   262 									sample.sampleSynchTime);
       
   263 						}
       
   264 					}
       
   265 				}				
       
   266 				// if thread is not yet found from threadToOffset
       
   267 				if (!this.threadToOffset.containsKey(new Long(sample
       
   268 						.getThreadValue()))) {
       
   269 					this.threadToOffset.put(new Long(sample.getThreadValue()),
       
   270 							Integer.valueOf(swiOffset++));
       
   271 
       
   272 					// read thread names from trace if needed
       
   273 					if (readThreadNamesFromTrace) {
       
   274 						try {
       
   275 							this.threadToName.put(new Long(sample
       
   276 									.getThreadValue()), this
       
   277 									.getThreadName(sample));
       
   278 						} catch (NullPointerException e1) {
       
   279 							this.threadToName
       
   280 									.put(new Long(sample.getThreadValue()),
       
   281 											Messages.IrqTrace_6
       
   282 													+ Long.toHexString(sample
       
   283 															.getThreadValue()));
       
   284 						}
       
   285 					}
       
   286 
       
   287 					// create thread wrapper for the thread and add it to allThreadWrappers
       
   288 					SwiThreadWrapper wrapper = new SwiThreadWrapper();
       
   289 					wrapper.threadAddress = new Long(sample.getThreadValue());
       
   290 					wrapper.threadName = threadToName.get(sample
       
   291 							.getThreadValue());
       
   292 					this.allThreadWrappers.add(wrapper);
       
   293 				}
       
   294 				
       
   295 			// if this is hardware interrupt
       
   296 			} else if (sample.getType() == IrqSample.TYPE_IRQ) {
       
   297 				val = sample.getIrqL1Value() + (sample.getIrqL2Value() << 8);
       
   298 				table = irqTable;
       
   299 
       
   300 				if (!this.irqToOffset.containsKey(new Long(val))) {
       
   301 					this.irqToOffset.put(new Long(val),
       
   302 							Integer.valueOf(irqOffset++));
       
   303 				}
       
   304 
       
   305 				// if line is already found from irq line hashtable
       
   306 				if (!irqLines.containsKey(val)) {
       
   307 					Hashtable<Long, Integer> hashTable = new Hashtable<Long, Integer>();
       
   308 					hashTable.put(val, 1);
       
   309 					irqLines.put(val, hashTable);
       
   310 				} else {
       
   311 					Hashtable<Long, Integer> interrupts = irqLines.get(val);
       
   312 					
       
   313 					// if event at this timeframe is not found yet
       
   314 					if (!interrupts.containsKey(sample.sampleSynchTime)) {
       
   315 						interrupts.put(sample.sampleSynchTime, 1);
       
   316 					} else {
       
   317 						int previousValue = interrupts
       
   318 								.get(sample.sampleSynchTime);
       
   319 						interrupts.put(sample.sampleSynchTime,
       
   320 								previousValue + 1);
       
   321 						
       
   322 						// check if value is greater than max amount of interrupts 
       
   323 						if (previousValue + 1 > maxAmountOfIRQSamples) {
       
   324 							maxAmountOfIRQSamples = previousValue + 1;
       
   325 						}
       
   326 					}
       
   327 				}
       
   328 			} else {
       
   329 				throw new ArrayIndexOutOfBoundsException();
       
   330 			}
       
   331 
       
   332 			// Add interrupts into its sampleTypeWrapper or create one if needed
       
   333 			valL = new Long(val);
       
   334 			if (!table.containsKey(valL)) {
       
   335 				IrqSampleTypeWrapper w = new IrqSampleTypeWrapper(sample,
       
   336 						colorSet, colorsOfThreadsAndLines);
       
   337 				table.put(valL, w);
       
   338 			} else {
       
   339 				IrqSampleTypeWrapper w = (IrqSampleTypeWrapper) table.get(valL);
       
   340 				w.addSample(sample);
       
   341 			}
       
   342 		}
       
   343 	}
       
   344 
       
   345 
       
   346 	/**
       
   347 	 * @return all thread wrappers vector
       
   348 	 */
       
   349 	public Vector<SwiThreadWrapper> getAllThreadWrappers() {
       
   350 		return allThreadWrappers;
       
   351 	}
       
   352 
       
   353 	/**
       
   354 	 * @return irq to offset hashtable
       
   355 	 */
       
   356 	public Hashtable<Long, Integer> getIrqToOffset() {
       
   357 		return irqToOffset;
       
   358 	}
       
   359 
       
   360 	/**
       
   361 	 * @return swi hashtable
       
   362 	 */
       
   363 	public Hashtable<Long, IrqSampleTypeWrapper> getSwiTable() {
       
   364 		return swiTable;
       
   365 	}
       
   366 
       
   367 	/**
       
   368 	 * @return irq hashtable
       
   369 	 */
       
   370 	public Hashtable<Long, IrqSampleTypeWrapper> getIrqTable() {
       
   371 		return irqTable;
       
   372 	}
       
   373 
       
   374 	/**
       
   375 	 * @return threadsToFunctions hashtable
       
   376 	 */
       
   377 	public Hashtable<String, Hashtable<String, ArrayList<Long>>> getThreadsToFunctions() {
       
   378 		return threadsToFunctions;
       
   379 	}
       
   380 
       
   381 	/**
       
   382 	 * @return max amount of swi interrupts per one timeframe
       
   383 	 */
       
   384 	public int getMaxAmountOfSWISamples() {
       
   385 		return maxAmountOfSWISamples;
       
   386 	}
       
   387 
       
   388 	/**
       
   389 	 * @return max amount of irq interrupts per one timeframe
       
   390 	 */
       
   391 	public int getMaxAmountOfIRQSamples() {
       
   392 		return maxAmountOfIRQSamples;
       
   393 	}
       
   394 
       
   395 	/**
       
   396 	 * @return thread and irq line colors
       
   397 	 */
       
   398 	public Hashtable<String, RGB> getColorsOfThreadsAndLines() {
       
   399 		return colorsOfThreadsAndLines;
       
   400 	}
       
   401 	
       
   402 	/**
       
   403 	 * @return set containing all colors of the trace
       
   404 	 */
       
   405 	public HashSet<RGB> getColorSet(){
       
   406 		return colorSet;
       
   407 	}
       
   408 	
       
   409 	/**
       
   410 	 * changes color of one thread or irq line
       
   411 	 * @param wrapper threadwrapper
       
   412 	 * @param newColor new color for item
       
   413 	 */
       
   414 	public void changeColorOfThreadOrIRQLine(IrqSampleTypeWrapper wrapper, RGB newColor){
       
   415 		
       
   416 		// save color into colorsets at trace information
       
   417 		colorSet.remove(wrapper.rgb);
       
   418 		colorSet.add(newColor);
       
   419 		if(wrapper.getPrototypeSample().getType() == IrqSample.TYPE_IRQ){
       
   420 			colorsOfThreadsAndLines.put(Long.toString(wrapper.getPrototypeSample().getIrqL1Value()), newColor);
       
   421 		}
       
   422 		else{
       
   423 			if(wrapper.getPrototypeSample().getFunction() != null){
       
   424 				colorsOfThreadsAndLines.put(wrapper.getPrototypeSample().getFunction().getFunctionName(), newColor);
       
   425 			}
       
   426 		}
       
   427 		wrapper.rgb = newColor;
       
   428 		
       
   429 		for(IrqTraceGraph item : graphs){
       
   430 			// refresh table and set editor window dirty so that it can be saved.
       
   431 			if(wrapper.getPrototypeSample().getType() == IrqSample.TYPE_IRQ){
       
   432 				item.irqLineUnchecked(wrapper);
       
   433 				item.irqLineChecked(wrapper);
       
   434 			}
       
   435 			else{
       
   436 				item.recalculateWholeGraph();
       
   437 			}
       
   438 		}
       
   439 		PIPageEditor.currentPageEditor().setDirty();
       
   440 	}
       
   441 	
       
   442 	/**
       
   443 	 * updates all table viewers
       
   444 	 */
       
   445 	public void updateAllTableViewers(){
       
   446 		for(IrqTraceGraph item : graphs){
       
   447 			item.updateTableViewers();
       
   448 		}
       
   449 	}
       
   450 	
       
   451 	/**
       
   452 	 * @return all graphs for this trace
       
   453 	 */
       
   454 	public IrqTraceGraph[] getGraphs() {
       
   455 		return graphs;
       
   456 	}
       
   457 
       
   458 	/**
       
   459 	 * @return true if function names are found from trace
       
   460 	 */
       
   461 	public boolean isFunctionNamesFound() {
       
   462 		return functionNamesFound;
       
   463 	}
       
   464 	
       
   465 	
       
   466 
       
   467 }