sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/engine/statistic/ProcessInfo.java
author Matti Laitinen <matti.t.laitinen@nokia.com>
Thu, 11 Feb 2010 15:22:14 +0200
changeset 1 1050670c6980
child 6 f65f740e69f9
permissions -rw-r--r--
Initial version of AnalyzeTool under EPL

/*
 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "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:  Definitions for the class ProcessInfo
 *
 */
package com.nokia.s60tools.analyzetool.engine.statistic;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import com.nokia.s60tools.analyzetool.Activator;

/**
 * Contains information of process
 * 
 * @author kihe
 * 
 */
public class ProcessInfo {

	/** List of allocations and frees sorted as they arrive in time */
	AbstractList<BaseInfo> allocsFrees;

	/** List of dll loads */
	Hashtable<String, DllLoad> dllLoads;

	/** Process id */
	int processID;

	/** Process Name */
	String processName;

	/** Process start time */
	Long startTime;

	/** Process start time */
	Long endTime;

	/** Trace data format version number */
	int traceDataVersion = 1;

	/** active allocations account */
	private int allocCount = 0;
	/** total memory consumed by this process at each event */
	private int totalMemory = 0;
	/** highest memory consumed by this process */
	private int highestMemory =0;

	/** Map of potential leaks; to track allocations not yet freed */
	private Map<Long, List<AllocInfo>> potentialLeaksMap;

	/**
	 * Constructor
	 */
	public ProcessInfo() {
		dllLoads = new Hashtable<String, DllLoad>();
		allocsFrees = new ArrayList<BaseInfo>();
		allocCount = 0;
		potentialLeaksMap = new HashMap<Long, List<AllocInfo>>(); 
	}

	/**
	 * Adds one memory allocation to the list.
	 * 
	 * @param oneInfo
	 *            One memory allocation
	 */
	public void addOneAlloc(AllocInfo oneInfo) {
		allocCount++;
		totalMemory = totalMemory + oneInfo.getSizeInt();
		oneInfo.setTotalMem(totalMemory);
		if (totalMemory > highestMemory) {
			highestMemory = totalMemory;
		}
		allocsFrees.add(oneInfo);
		//add this alloc to the potential leaks map
		Long addr = oneInfo.getMemoryAddress();
		List<AllocInfo> allocsSameAddr = potentialLeaksMap.get(addr);
		if (allocsSameAddr == null){
			allocsSameAddr = new ArrayList<AllocInfo>();
			potentialLeaksMap.put(addr, allocsSameAddr);
		}
		allocsSameAddr.add(oneInfo);
	}

	/**
	 * Adds one dll load to the list.
	 * 
	 * @param dllLoad
	 *            One dll load
	 */
	public void addOneDllLoad(DllLoad dllLoad) {
		dllLoads.put(dllLoad.getName(), dllLoad);
	}

	/**
	 * Updates memory leaks list by given free information
	 * 
	 * @param info
	 *            Which memory allocation to be deallocated.
	 */
	public void free(FreeInfo info) {

		int freeSize = 0;
		
		//remove allocs with the same address from the potential leaks map
		Long freeAddr = info.getMemoryAddress();
		List<AllocInfo> allocsSameAddr = potentialLeaksMap.remove(freeAddr);
		if (allocsSameAddr != null && allocsSameAddr.size()>0){
			for(AllocInfo allocInfo : allocsSameAddr){
				allocInfo.setFreedBy(info);
				info.addFreedAlloc(allocInfo);
				allocCount--;
				int thisFreedSize = allocInfo.getSizeInt();
				freeSize = freeSize + thisFreedSize;
				totalMemory = totalMemory - thisFreedSize;
			}			
		}

		info.setSizeInt(freeSize);
		info.setTotalMem(totalMemory);
		
		if (info.getTime() == null || info.getTime() == 0 ) {
			// support old format
			//set time as last operation time or start time.
			Long time = getPreviousTime();
			if (time == null || time == -1L) {
				Activator.getDefault().log(IStatus.WARNING, String.format("AnalyzeTool encountered a process = %s, which starts with FREE.", processID), null);
				time = startTime;
			}
			info.setTime(time);
		}
		
		allocsFrees.add(info);
	}

	/**
	 * Returns the timestamp of the last memory operation
	 * @return the timestamp of the last memory operation, or -1 if there
	 * are no memory operations
	 */
	private Long getPreviousTime() {
		Long time = -1L;
		if (!allocsFrees.isEmpty()) {
			time = (allocsFrees.get(allocsFrees.size() -1)).getTime();
		}
		return time;
	}

	/**
	 * Returns list of allocations
	 * 
	 * @return List of allocations
	 */
	public AbstractList<AllocInfo> getAllocs() {
		AbstractList<AllocInfo> allocs = new ArrayList<AllocInfo>();
		for (BaseInfo alloc : allocsFrees) {
			if (alloc instanceof AllocInfo) {
				allocs.add((AllocInfo) alloc);
			}
		}
		return allocs;
	}

	/**
	 * Returns list of dll loads
	 * 
	 * @return List of dll loads
	 */
	public Hashtable<String, DllLoad> getDllLoads() {
		return dllLoads;
	}

	/**
	 * Returns list of memory leak from this process.
	 * 
	 * @return List of memory leaks.
	 */
	public AbstractList<AllocInfo> getMemLeaks() {
		AbstractList<AllocInfo> leaks = new ArrayList<AllocInfo>();
		for (List<AllocInfo> potLeaks : potentialLeaksMap.values()) {
			leaks.addAll(potLeaks);
		}
		return leaks;
	}

	/**
	 * Returns the number of memory leaks of this process.
	 * 
	 * @return number of memory leaks.
	 */
	public int getMemLeaksNumber() {
		int count = 0;
		for (List<AllocInfo> potLeaks : potentialLeaksMap.values()) {
			count += potLeaks.size();
		}
		return count;
	}

	/** 
	 * get list of frees
	 * @return List of FreeInfo
	 */
	public AbstractList<FreeInfo> getFrees() {
		AbstractList<FreeInfo> frees = new ArrayList<FreeInfo>();
		for (BaseInfo alloc : allocsFrees) {
			if (alloc instanceof FreeInfo) {
				frees.add((FreeInfo) alloc);
			}
		}
		return frees;
	}

	/**
	 * Returns process id
	 * 
	 * @return Process id
	 */
	public int getProcessID() {
		return processID;
	}

	/**
	 * Returns process start time
	 * 
	 * @return Process start time
	 */
	public Long getStartTime() {
		return startTime;
	}

	/**
	 * Returns trace data version number
	 * 
	 * @return Trace data version number
	 */
	public int getTraceDataVersion() {
		return traceDataVersion;
	}

	/**
	 * Sets process id
	 * 
	 * @param newProcessID
	 *            Process id
	 */
	public void setProcessID(int newProcessID) {
		this.processID = newProcessID;
	}

	/**
	 * Sets process start time
	 * 
	 * @param newTime
	 *            Process start time
	 */
	public void setStartTime(String newTime) {
		Long lValue = Long.parseLong(newTime, 16);
		this.startTime = lValue;
	}

	/**
	 * Updates trace version number
	 * 
	 * @param newTraceDataVersion
	 *            New trace data version number
	 */
	public void setTraceDataVersion(String newTraceDataVersion) {

		try {
			traceDataVersion = Integer.parseInt(newTraceDataVersion, 16);
		} catch (NumberFormatException nfe) {
			// exception while trying to set new version number
			// use the oldest version number, this version number is safest
			// but when use this version some information could be lost
			traceDataVersion = 1;
		}
	}

	/**
	 * Unloads one dll load from the stored items
	 * 
	 * @param dllLoad
	 *            Dll unload item
	 */
	public void unloadOneDll(DllLoad dllLoad) {
		if (dllLoads.containsKey(dllLoad.getName())) {
			dllLoads.remove(dllLoad.getName());
		}
	}

	/**
	 * set end time of the process
	 * @param aTime
	 */
	public void setEndTime(String aTime) {
		Long lValue = Long.parseLong(aTime, 16);
		endTime = lValue;
	}

	/**
	 * set process name
	 * @param aProcessName
	 */
	public void setProcessName(String aProcessName) {
		processName = aProcessName;
	}

	/**
	 * @return the process name
	 */
	public String getProcessName() {
		return processName;
	}

	/**
	 * get all events
	 * @return list of BaseInfo
	 */
	public AbstractList<BaseInfo> getAllocsFrees() {
		return allocsFrees;
	}

	/**
	 * get end time of the process
	 * @return
	 */
	public Long getEndTime() {
		return endTime;
	}

	/**
	 * get list of allocations freed by a FreeInfo
	 * 
	 * @param free
	 * @return AbstractList<AllocInfo> list of allocations freed by the provided
	 *         FreeInfo
	 */
	public AbstractList<AllocInfo> getAllocsFreedBy(FreeInfo free) {
		AbstractList<AllocInfo> allocs = new ArrayList<AllocInfo>();
		for (BaseInfo alloc : allocsFrees) {
			if (alloc instanceof AllocInfo && ((AllocInfo) alloc).getFreedBy() == free) {
				allocs.add((AllocInfo) alloc);
			}
		}
		return allocs;
	}
	/**
	 * Getter for highest memory allocation for the current process
	 * @return int containing highest memory usage
	 */
	public int getHighestCumulatedMemoryAlloc() {
		return highestMemory;
	}

}