sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.memory/src/com/nokia/carbide/cpp/pi/memory/MemTrace.java
changeset 5 844b047e260d
parent 2 b9ab3b238396
equal deleted inserted replaced
4:615035072f7e 5:844b047e260d
    16  */
    16  */
    17 
    17 
    18 package com.nokia.carbide.cpp.pi.memory;
    18 package com.nokia.carbide.cpp.pi.memory;
    19 
    19 
    20 import java.util.ArrayList;
    20 import java.util.ArrayList;
       
    21 import java.util.Arrays;
    21 import java.util.Enumeration;
    22 import java.util.Enumeration;
    22 import java.util.HashSet;
    23 import java.util.HashSet;
    23 import java.util.Hashtable;
    24 import java.util.Hashtable;
    24 import java.util.Iterator;
    25 import java.util.Iterator;
    25 import java.util.SortedMap;
    26 import java.util.SortedMap;
    26 import java.util.TreeMap;
    27 import java.util.TreeMap;
    27 import java.util.Map.Entry;
       
    28 
       
    29 import org.eclipse.draw2d.IFigure;
       
    30 
    28 
    31 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
    29 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
    32 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
    30 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
    33 import com.nokia.carbide.cpp.internal.pi.model.GenericThread;
    31 import com.nokia.carbide.cpp.internal.pi.model.GenericThread;
    34 import com.nokia.carbide.cpp.internal.pi.model.TraceWithThreads;
    32 import com.nokia.carbide.cpp.internal.pi.model.TraceWithThreads;
    63 	transient private int intervalMaxTotal = 0;
    61 	transient private int intervalMaxTotal = 0;
    64 
    62 
    65 	transient private Hashtable<String, TreeMap<Long, MemSample>> drawDataByMemThread = null;
    63 	transient private Hashtable<String, TreeMap<Long, MemSample>> drawDataByMemThread = null;
    66 	transient private ArrayList<MemSampleByTime> drawDataByTime;
    64 	transient private ArrayList<MemSampleByTime> drawDataByTime;
    67 	transient private HashSet<MemThread> noDuplicateMemThreads;
    65 	transient private HashSet<MemThread> noDuplicateMemThreads;
    68 
    66 	
       
    67 	transient private Hashtable<String, ProfiledLibraryEvent> drawDataByLibraryEvent = null;
       
    68 	transient private TreeMap<Long, ArrayList<MemSample>> drawLibraryEventDataByTime = null;
       
    69 	
       
    70     transient private LibraryEventColorPalette libraryEventColorPalette = null;
    69 	transient private long intervalStart = -1;
    71 	transient private long intervalStart = -1;
    70 	transient private long intervalEnd = -1;
    72 	transient private long intervalEnd = -1;
       
    73 	
       
    74 	
    71 
    75 
    72 	private int version;
    76 	private int version;
    73 
    77 
    74 	public MemTrace() {
    78 	public MemTrace() {
    75 		firstSynchTimes = new Hashtable<Integer, Integer>();
    79 		firstSynchTimes = new Hashtable<Integer, Integer>();
    76 		lastSynchTimes = new Hashtable<Integer, Integer>();
    80 		lastSynchTimes = new Hashtable<Integer, Integer>();
    77 	}
       
    78 
       
    79 	public void addSample(MemSample sample) {
       
    80 		this.samples.add(sample);
       
    81 	}
    81 	}
    82 
    82 
    83 	public MemSample getMemSample(int number) {
    83 	public MemSample getMemSample(int number) {
    84 		return (MemSample) this.samples.elementAt(number);
    84 		return (MemSample) this.samples.elementAt(number);
    85 	}
    85 	}
   204 				// the first sample in each time period contains system-wide
   204 				// the first sample in each time period contains system-wide
   205 				// info
   205 				// info
   206 				if (memSample.thread.threadId == 0xffffffffbabbeaaaL) {
   206 				if (memSample.thread.threadId == 0xffffffffbabbeaaaL) {
   207 					usedMemory = memSample.heapSize;
   207 					usedMemory = memSample.heapSize;
   208 					freeMemory = memSample.stackSize;
   208 					freeMemory = memSample.stackSize;
   209 					memSample = (MemSample) e.nextElement();
   209 					if(e.hasMoreElements()){
       
   210 						memSample = (MemSample) e.nextElement();
       
   211 					}
       
   212 					else{
       
   213 						break;
       
   214 					}
   210 				}
   215 				}
   211 
   216 
   212 				// the 2nd sample in each time period has memory model and
   217 				// the 2nd sample in each time period has memory model and
   213 				// CodeSeg data
   218 				// CodeSeg data
   214 				if (memSample.thread.threadId == 0xffffffffbabbea20L) {
   219 				if (memSample.thread.threadId == 0xffffffffbabbea20L) {
   215 					usedMemory = memSample.heapSize;
   220 					usedMemory = memSample.heapSize;
   216 					freeMemory = memSample.stackSize;
   221 					freeMemory = memSample.stackSize;
   217 					memSample = (MemSample) e.nextElement();
   222 					if(e.hasMoreElements()){
       
   223 						memSample = (MemSample) e.nextElement();
       
   224 					}
       
   225 					else{
       
   226 						break;
       
   227 					}
       
   228 					
   218 				}
   229 				}
   219 
   230 
   220 				// Create MemSampleByTime object based on sample
   231 				// Create MemSampleByTime object based on sample
   221 				MemSampleByTime memSampleByTime = new MemSampleByTime(
   232 				MemSampleByTime memSampleByTime = new MemSampleByTime(
   222 						memSample.sampleSynchTime, usedMemory + freeMemory,
   233 						memSample.sampleSynchTime, usedMemory + freeMemory,
   267 	}
   278 	}
   268 
   279 
   269 	public void gatherEventBasedDrawData() {
   280 	public void gatherEventBasedDrawData() {
   270 		if (drawDataByMemThread != null)
   281 		if (drawDataByMemThread != null)
   271 			return; // already initialised
   282 			return; // already initialised
   272 
       
   273 		drawDataByMemThread = new Hashtable<String, TreeMap<Long, MemSample>>();
   283 		drawDataByMemThread = new Hashtable<String, TreeMap<Long, MemSample>>();
       
   284 		if(version >= 203){
       
   285 			drawDataByLibraryEvent = new Hashtable<String, ProfiledLibraryEvent>();
       
   286 		}
       
   287 
   274 		memoryModel = MemTrace.MEMORY_UNKNOWN;
   288 		memoryModel = MemTrace.MEMORY_UNKNOWN;
   275 		getThreadsFromTrace();
   289 		getThreadsFromTrace();
   276 
   290 
   277 		if (drawDataByTime == null)
   291 		if (drawDataByTime == null)
   278 			drawDataByTime = new ArrayList<MemSampleByTime>();
   292 			drawDataByTime = new ArrayList<MemSampleByTime>();
   293 				// info
   307 				// info
   294 				if (memSample.thread.threadId == 0xffffffffbabbeaaaL) {
   308 				if (memSample.thread.threadId == 0xffffffffbabbeaaaL) {
   295 					usedMemory = memSample.heapSize;
   309 					usedMemory = memSample.heapSize;
   296 					freeMemory = memSample.stackSize;
   310 					freeMemory = memSample.stackSize;
   297 					addSampleToThread(memSample);
   311 					addSampleToThread(memSample);
   298 					memSample = (MemSample) e.nextElement();
   312 					if(e.hasMoreElements()){
       
   313 						memSample = (MemSample) e.nextElement();
       
   314 					}
       
   315 					else{
       
   316 						break;
       
   317 					}
   299 
   318 
   300 				}
   319 				}
   301 
   320 
   302 				// Create MemSampleByTime object based on sample
   321 				// Create MemSampleByTime object based on sample
   303 				// MemSampleByTime memSampleByTime = new
   322 				// MemSampleByTime memSampleByTime = new
   324 
   343 
   325 	}
   344 	}
   326 
   345 
   327 	private void addSampleToThread(MemSample sample) {
   346 	private void addSampleToThread(MemSample sample) {
   328 
   347 
       
   348 		if (version >= 203) {
       
   349 			String library = getLibraryNameString(sample.thread.fullName);
       
   350 			if (library != null) {
       
   351 				ProfiledLibraryEvent ple = drawDataByLibraryEvent.get(library);
       
   352 				if (ple != null) {
       
   353 					// Add initial sample to library event
       
   354 					ple.addMemSample(sample);
       
   355 					return;
       
   356 				}
       
   357 			}
       
   358 
       
   359 		}
   329 		// get sample array from thread
   360 		// get sample array from thread
   330 		TreeMap<Long, MemSample> samples = drawDataByMemThread
   361 		TreeMap<Long, MemSample> samples = drawDataByMemThread
   331 				.get(sample.thread.fullName);
   362 				.get(sample.thread.fullName);
   332 
   363 
   333 		if (sample.type == MemTraceParser.SAMPLE_CODE_DELETE_CHUNK) {
   364 		if (sample.type == MemTraceParser.SAMPLE_CODE_DELETE_CHUNK) {
   340 			// Add initial sample to thread
   371 			// Add initial sample to thread
   341 			samples.put(sample.sampleSynchTime, sample);
   372 			samples.put(sample.sampleSynchTime, sample);
   342 			return;
   373 			return;
   343 		}
   374 		}
   344 
   375 
   345 		System.out.println("PI ERROR: Thread not found");
   376 		System.out.println("PI ERROR: Thread not found"); //$NON-NLS-1$
   346 
   377 
   347 	}
   378 	}
   348 
   379 
   349 	private void getThreadsFromTrace() {
   380 	private void getThreadsFromTrace() {
   350 
   381 
   353 		// the parser creates multiple copies of the same MemThread item,
   384 		// the parser creates multiple copies of the same MemThread item,
   354 		// so we have to use the full name of the MemThread to access sample
   385 		// so we have to use the full name of the MemThread to access sample
   355 		// data
   386 		// data
   356 		for (MemThread memThread : threads) {
   387 		for (MemThread memThread : threads) {
   357 			String processedThreadName = memThread.threadName;
   388 			String processedThreadName = memThread.threadName;
   358 
   389 			boolean libraryEvent = false;
   359 			// Add Thread ID into processedThreadName
   390 			// Add Thread ID into processedThreadName
   360 			// looking for _T and _C suffixes and remove them for thread
   391 			// looking for _T and _C suffixes and remove them for thread
   361 			if (processedThreadName.endsWith("_T")) //$NON-NLS-1$
   392 			if (processedThreadName.endsWith("_T")) //$NON-NLS-1$
   362 			{
   393 			{
   363 				processedThreadName = processedThreadName.substring(0,
   394 				processedThreadName = processedThreadName.substring(0,
   365 						+ "_" + memThread.threadId; //$NON-NLS-1$
   396 						+ "_" + memThread.threadId; //$NON-NLS-1$
   366 			} else if (processedThreadName.endsWith("_C")) { //$NON-NLS-1$
   397 			} else if (processedThreadName.endsWith("_C")) { //$NON-NLS-1$
   367 				processedThreadName = processedThreadName.substring(0,
   398 				processedThreadName = processedThreadName.substring(0,
   368 						processedThreadName.length() - 2)
   399 						processedThreadName.length() - 2)
   369 						+ " [0x" + Integer.toHexString(memThread.threadId) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
   400 						+ " [0x" + Integer.toHexString(memThread.threadId) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
   370 			} else {
   401 			} else if (processedThreadName.endsWith("_L")) { //$NON-NLS-1$
       
   402 				processedThreadName = processedThreadName.substring(0,
       
   403 						processedThreadName.length() - 2)
       
   404 						+ " [0x" + Integer.toHexString(memThread.threadId) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
       
   405 				libraryEvent = true;
       
   406 			}else {
   371 				processedThreadName += "_" + memThread.threadId; //$NON-NLS-1$
   407 				processedThreadName += "_" + memThread.threadId; //$NON-NLS-1$
   372 			}
   408 			}
   373 
   409 
   374 			// Full name contains process name, thread name and thread id
   410 			// Full name contains process name, thread name and thread id
   375 			memThread.fullName = memThread.processName
   411 			memThread.fullName = memThread.processName
   383 			memThread.maxMemoryItem = new MaxMemoryItem();
   419 			memThread.maxMemoryItem = new MaxMemoryItem();
   384 			memThread.maxMemoryItem.maxChunks = 0;
   420 			memThread.maxMemoryItem.maxChunks = 0;
   385 			memThread.maxMemoryItem.maxStackHeap = 0;
   421 			memThread.maxMemoryItem.maxStackHeap = 0;
   386 			memThread.maxMemoryItem.maxTotal = 0;
   422 			memThread.maxMemoryItem.maxTotal = 0;
   387 
   423 
   388 			if (drawDataByMemThread.get(memThread.fullName) == null) {
   424 			if (libraryEvent) {
   389 				drawDataByMemThread.put(memThread.fullName,
   425 				String name = getLibraryNameString(memThread.fullName);
   390 						new TreeMap<Long, MemSample>());
   426 				if (drawDataByLibraryEvent.get(name) == null) {
   391 				noDuplicateMemThreads.add(memThread);
   427 					ProfiledLibraryEvent ple = new ProfiledLibraryEvent(name);
       
   428 					ple.setColor(getLibraryEventColorPalette().getColor(name));
       
   429 					drawDataByLibraryEvent.put(name, ple);
       
   430 				}
       
   431 			} else {
       
   432 				if (drawDataByMemThread.get(memThread.fullName) == null) {
       
   433 					drawDataByMemThread.put(memThread.fullName,
       
   434 							new TreeMap<Long, MemSample>());
       
   435 					noDuplicateMemThreads.add(memThread);
       
   436 				}
   392 			}
   437 			}
   393 		}
   438 		}
   394 
   439 
   395 	}
   440 	}
   396 
   441 
   397 	public TreeMap<Long, MemSample> getDrawDataByMemThread(MemThread id) {
   442 	public TreeMap<Long, MemSample> getDrawDataByMemThread(MemThread id) {
   398 		return this.drawDataByMemThread.get(id.fullName);
   443 		return this.drawDataByMemThread.get(id.fullName);
   399 	}
   444 	}
       
   445 	
       
   446 	public Hashtable<String, TreeMap<Long, MemSample>> getDrawDataByMemThread() {
       
   447 		return this.drawDataByMemThread;
       
   448 	}
   400 
   449 
   401 	public ArrayList<MemSampleByTime> getDrawDataByTime() {
   450 	public ArrayList<MemSampleByTime> getDrawDataByTime() {
       
   451 		if (drawDataByTime.isEmpty() && getVersion() >= 202) {
       
   452 			TreeMap<Long, MemSample> events = drawDataByMemThread
       
   453 					.get("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814"); //$NON-NLS-1$
       
   454 
       
   455 			Iterator<MemSample> iterator = events.values().iterator();
       
   456 			while (iterator.hasNext()) {
       
   457 				MemSample memSample = iterator.next();
       
   458 				drawDataByTime.add(new MemSampleByTime(
       
   459 						memSample.sampleSynchTime, memSample.stackSize
       
   460 								+ memSample.heapSize, memSample.heapSize));
       
   461 			}
       
   462 		}
   402 		return this.drawDataByTime;
   463 		return this.drawDataByTime;
   403 	}
   464 	}
   404 
   465 
   405 	public HashSet<MemThread> getNoDuplicateMemThreads() {
   466 	public HashSet<MemThread> getNoDuplicateMemThreads() {
   406 		return this.noDuplicateMemThreads;
   467 		return this.noDuplicateMemThreads;
   432 				|| ((startTime == intervalStart) && (endTime == intervalEnd)))
   493 				|| ((startTime == intervalStart) && (endTime == intervalEnd)))
   433 			return item;
   494 			return item;
   434 
   495 
   435 		if (this.getVersion() >= 202) {
   496 		if (this.getVersion() >= 202) {
   436 			TreeMap<Long, MemSample> events = drawDataByMemThread
   497 			TreeMap<Long, MemSample> events = drawDataByMemThread
   437 					.get("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814");
   498 					.get("TOTAL_MEMORY::TOTAL_MEMORY_-1162089814"); //$NON-NLS-1$
   438 
   499 
   439 			Iterator<MemSample> values = events.values().iterator();
   500 			Iterator<MemSample> values = events.values().iterator();
   440 
   501 
   441 			while (values.hasNext()) {
   502 			while (values.hasNext()) {
   442 				MemSample memSample = values.next();
   503 				MemSample memSample = values.next();
   623 
   684 
   624 		}
   685 		}
   625 
   686 
   626 		return;
   687 		return;
   627 	}
   688 	}
       
   689 		
       
   690 	public void setMaxMemLibraryEventDataByInterval(long startTime, long endTime) {
       
   691 		// update memory usage for each library event that are used during the time slot
       
   692 		for (Enumeration<ProfiledLibraryEvent> e = drawDataByLibraryEvent
       
   693 				.elements(); e.hasMoreElements();) {
       
   694 			ProfiledLibraryEvent ple = (ProfiledLibraryEvent) e
       
   695 					.nextElement();
       
   696 			ple.updateSelection(startTime, endTime);
       
   697 		}
       
   698 	}
   628 
   699 
   629 	public long getMemoryModel() {
   700 	public long getMemoryModel() {
   630 		return this.memoryModel;
   701 		return this.memoryModel;
   631 	}
   702 	}
   632 
   703 
   650 		} catch (Exception e) {
   721 		} catch (Exception e) {
   651 			return null;
   722 			return null;
   652 		}
   723 		}
   653 
   724 
   654 	}
   725 	}
       
   726 	
       
   727 	public Hashtable<String, ProfiledLibraryEvent> getLibraryEvents(){
       
   728 		return drawDataByLibraryEvent;
       
   729 	}
       
   730 	
       
   731 	public LibraryEventColorPalette getLibraryEventColorPalette(){
       
   732 		if(libraryEventColorPalette == null){
       
   733 			libraryEventColorPalette = new LibraryEventColorPalette();
       
   734 		}
       
   735 		return libraryEventColorPalette;
       
   736 	}
       
   737 	
       
   738 	
       
   739 	public ArrayList<MemSample> getLibraryEventDataByTime(int graphIndex, long time, long scale) {
       
   740 		if(drawLibraryEventDataByTime == null){
       
   741 			// find library events by time
       
   742 			drawLibraryEventDataByTime = new TreeMap<Long, ArrayList<MemSample>>();
       
   743 			Iterator<ProfiledLibraryEvent> iterator = drawDataByLibraryEvent.values().iterator();
       
   744 			while(iterator.hasNext()){	
       
   745 				ProfiledLibraryEvent ple = iterator.next();	
       
   746 				Iterator<MemSample> iteratorMem = ple.getMemSamples().values().iterator();
       
   747 				while(iteratorMem.hasNext()){
       
   748 					MemSample memSample = iteratorMem.next();
       
   749 					ArrayList<MemSample> memSamples = drawLibraryEventDataByTime.get(memSample.sampleSynchTime);
       
   750 					if(memSamples == null){
       
   751 						memSamples = new ArrayList<MemSample>();
       
   752 					}
       
   753 					memSamples.add(memSample);					
       
   754 					drawLibraryEventDataByTime.put(memSample.sampleSynchTime, memSamples);
       
   755 				}		
       
   756 			}
       
   757 		}		
       
   758 		
       
   759 		ArrayList<MemSample> retMemSamples = new ArrayList<MemSample>();
       
   760 		ArrayList<MemSample> bestChoice = null;
       
   761 		scale = (long)scale * 5;
       
   762 		
       
   763 		if(scale == 0){
       
   764 			bestChoice = drawLibraryEventDataByTime.get(time);
       
   765 		} else {	
       
   766 			SortedMap<Long, ArrayList<MemSample>> sortedMap = drawLibraryEventDataByTime
       
   767 					.subMap(time - scale, time + scale);
       
   768 			long min = Long.MAX_VALUE;
       
   769 			long closest = time;
       
   770 			for (Long key : sortedMap.keySet()) {
       
   771 				final long diff = Math.abs(key - time);
       
   772 				if (diff < min) {
       
   773 					Iterator<MemSample> iterator = sortedMap.get(key).iterator();
       
   774 					while(iterator.hasNext()){
       
   775 						MemSample memSample = iterator.next();
       
   776 						if(memSample.thread.isEnabled(graphIndex)){
       
   777 							min = diff;
       
   778 							closest = key;
       
   779 						}
       
   780 					}					
       
   781 				}
       
   782 			}
       
   783 			bestChoice = sortedMap.get(closest);			
       
   784 		}
       
   785 		if(bestChoice != null){
       
   786 			Iterator<MemSample> iterator = bestChoice.iterator();
       
   787 			while(iterator.hasNext()){
       
   788 				MemSample memSample = iterator.next();
       
   789 				if(memSample.thread.isEnabled(graphIndex)){
       
   790 					retMemSamples.add(memSample);
       
   791 				}
       
   792 			}
       
   793 		}
       
   794 		return retMemSamples;
       
   795 	}	
       
   796 	
       
   797 	public String getLibraryNameString(String fullName){
       
   798 		int startIndex = fullName.indexOf("::") + 2; //$NON-NLS-1$
       
   799 		int lastIndex = fullName.indexOf(" ["); //$NON-NLS-1$
       
   800 		if(startIndex != -1 && lastIndex != -1){
       
   801 			return fullName.substring(startIndex, lastIndex);
       
   802 		}
       
   803 		return null;
       
   804 	}
       
   805 	
       
   806 	public String getProcessFromLibraryNameString(String fullName){
       
   807 		int lastIndex = fullName.indexOf("::"); //$NON-NLS-1$
       
   808 		if(lastIndex != -1){
       
   809 			return fullName.substring(0, lastIndex);
       
   810 		}
       
   811 		return null;
       
   812 	}
   655 
   813 
   656 }
   814 }