sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceParser.java
changeset 5 844b047e260d
parent 2 b9ab3b238396
child 12 ae255c9aa552
equal deleted inserted replaced
4:615035072f7e 5:844b047e260d
    21 import java.io.DataOutputStream;
    21 import java.io.DataOutputStream;
    22 import java.io.EOFException;
    22 import java.io.EOFException;
    23 import java.io.File;
    23 import java.io.File;
    24 import java.io.FileInputStream;
    24 import java.io.FileInputStream;
    25 import java.io.IOException;
    25 import java.io.IOException;
    26 import java.util.Collection;
    26 import java.util.ArrayList;
    27 import java.util.Enumeration;
    27 import java.util.HashMap;
    28 import java.util.Hashtable;
    28 import java.util.Hashtable;
    29 import java.util.Iterator;
    29 import java.util.List;
       
    30 import java.util.Map;
    30 import java.util.StringTokenizer;
    31 import java.util.StringTokenizer;
    31 import java.util.Vector;
       
    32 
    32 
    33 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
    33 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
    34 import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
       
    35 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
    34 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
    36 import com.nokia.carbide.cpp.internal.pi.model.Parser;
    35 import com.nokia.carbide.cpp.internal.pi.model.Parser;
    37 import com.nokia.carbide.cpp.internal.pi.model.TraceDataContainer;
    36 import com.nokia.carbide.cpp.internal.pi.model.TraceDataContainer;
    38 
    37 
    39 
    38 
    43   private boolean debug = false;
    42   private boolean debug = false;
    44   private String profilerVersion;
    43   private String profilerVersion;
    45   private String samplerVersion;
    44   private String samplerVersion;
    46   private Hashtable<Integer,GppProcess> processes;
    45   private Hashtable<Integer,GppProcess> processes;
    47   private Hashtable<Integer,GppThread> threads;
    46   private Hashtable<Integer,GppThread> threads;
    48   private GppSample[] traceData;
    47   private HashMap<Long,String> threadAddressToName;
    49   private GppThread[] sortedThreads;
    48 
    50   private TraceDataContainer container; 
    49   // smp specific
    51   private Hashtable<Long,String> threadAddressToName;
    50   private int currentCpuNumber = 0;
       
    51   private int cpuCount = 0;
       
    52 
    52 
    53 
    53   public GppTraceParser() throws IOException
    54   public GppTraceParser() throws IOException
    54   {
    55   {
    55     this.processes = new Hashtable<Integer,GppProcess>();
    56     this.processes = new Hashtable<Integer,GppProcess>();
    56     this.threads   = new Hashtable<Integer,GppThread>();
    57     this.threads   = new Hashtable<Integer,GppThread>();
    57     this.threadAddressToName = new Hashtable<Long,String>();
    58     this.threadAddressToName = new HashMap<Long,String>();
    58   }
    59   }
    59 
    60 
    60   public ParsedTraceData parse(File traceInput) throws IOException
    61 	/**
       
    62 	 * Parses all given input trace files and returns the resulting ParsedTraceData. 
       
    63 	 * @param traceInputs the trace data files to parse
       
    64 	 * @return ParsedTraceData containing parsed trace
       
    65 	 * @throws IOException
       
    66 	 */
       
    67 	public ParsedTraceData parse(File[] traceInputs) throws IOException {
       
    68 		List<GppSample> samples = new ArrayList<GppSample>();
       
    69 		
       
    70 		for (File traceInput : traceInputs) {
       
    71 			//each part of the trace file is independent of each other 
       
    72 			//so clear previous state
       
    73 			processes.clear();
       
    74 			threads.clear();
       
    75 			internalParse(traceInput, samples);			
       
    76 		}
       
    77 
       
    78 		ParsedTraceData pd = new ParsedTraceData();
       
    79 		pd.traceData = this.getTrace(samples);
       
    80 		pd.staticData = createTraceContainer();
       
    81 		return pd;
       
    82 	}
       
    83 
       
    84 	private TraceDataContainer createTraceContainer() {
       
    85 		TraceDataContainer container = new TraceDataContainer("GPP_address2threadname",new String[]{"address","threadname"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
       
    86 		for (Map.Entry<Long, String> entry : threadAddressToName.entrySet()) {
       
    87 	    	container.addDataToColumn("threadname",entry.getKey()); //$NON-NLS-1$
       
    88 	    	container.addDataToColumn("address",entry.getValue()); //$NON-NLS-1$			
       
    89 		}
       
    90 	    this.threadAddressToName = null;
       
    91 		return container;
       
    92 	}
       
    93 
       
    94 	/**
       
    95 	 * Parses the given input trace file and returns the resulting ParsedTraceData. 
       
    96 	 * @param traceInput the trace data file to parse
       
    97 	 * @return ParsedTraceData containing parsed trace
       
    98 	 * @throws IOException
       
    99 	 */
       
   100 	@Override
       
   101 	public ParsedTraceData parse(File traceInput) throws IOException {
       
   102 		return parse(new File[]{traceInput});
       
   103 	}
       
   104 	
       
   105   private void internalParse(File traceInput, List<GppSample> gppSamples) throws IOException
    61   {
   106   {
    62     if (!traceInput.exists())
   107     if (!traceInput.exists())
    63     	throw new IOException(Messages.getString("GppTraceParser.0"));  //$NON-NLS-1$
   108     	throw new IOException(Messages.getString("GppTraceParser.0"));  //$NON-NLS-1$
    64 
   109 
    65     DataInputStream dis = new DataInputStream(new FileInputStream(traceInput));
   110     DataInputStream dis = new DataInputStream(new FileInputStream(traceInput));
    72     int threadIndexer = 0;
   117     int threadIndexer = 0;
    73     int count = 1;
   118     int count = 1;
    74     int samples = 0;
   119     int samples = 0;
    75     long time = 0;
   120     long time = 0;
    76 
   121 
    77     Vector<GppSample> intermediateTraceData = new Vector<GppSample>();
       
    78     
       
    79     // determine the base sampling period (address/thread sampling period) 
   122     // determine the base sampling period (address/thread sampling period) 
    80     int addrThreadPeriod = 1;
   123     int addrThreadPeriod = 1;
    81     
   124     
    82     if (traceVersion.indexOf("V2.01") != -1) { //$NON-NLS-1$
   125     if (traceVersion.indexOf("V2.01") != -1) { //$NON-NLS-1$
    83     	addrThreadPeriod =   (dis.readUnsignedByte() << 24)
   126     	addrThreadPeriod =   (dis.readUnsignedByte() << 24)
    87     }
   130     }
    88 
   131 
    89 	// initialize the address/thread base sampling rate
   132 	// initialize the address/thread base sampling rate
    90 	NpiInstanceRepository.getInstance().activeUidSetPersistState(
   133 	NpiInstanceRepository.getInstance().activeUidSetPersistState(
    91 								"com.nokia.carbide.cpp.pi.address.samplingInterval", //$NON-NLS-1$
   134 								"com.nokia.carbide.cpp.pi.address.samplingInterval", //$NON-NLS-1$
    92 								new Integer(addrThreadPeriod)); //$NON-NLS-1$
   135 								Integer.valueOf(addrThreadPeriod)); //$NON-NLS-1$
    93     
   136     
    94     while (dis.available() > 0)
   137     while (dis.available() > 0)
    95     {
   138     {
    96       try
   139       try
    97       {
   140       {
   113         while (--count >= 0)
   156         while (--count >= 0)
   114         {
   157         {
   115           samples++;
   158           samples++;
   116           time += addrThreadPeriod;
   159           time += addrThreadPeriod;
   117           
   160           
   118           if (samples == 1 && thread == null)
   161           if (samples < 3 && thread == null)
   119           {
   162           {
   120 	       	// the first sample may be recorded before its thread's name
   163 	       	// the first sample (or couple of samples for SMP) may be recorded before its thread's name
   121 
   164 
   122         	// create a new sample object for this sample
   165         	// create a new sample object for this sample
   123             GppSample gppSample = new GppSample();
   166             GppSample gppSample = new GppSample();
   124             long pcMod = pc << 32;
   167             long pcMod = pc << 32;
   125             pcMod = pcMod >>> 32;
   168             pcMod = pcMod >>> 32;
   141             gppSample.thread = unknownThread;
   184             gppSample.thread = unknownThread;
   142 
   185 
   143             this.threads.put(-1,unknownThread);
   186             this.threads.put(-1,unknownThread);
   144 
   187 
   145             gppSample.thread = unknownThread;
   188             gppSample.thread = unknownThread;
   146             intermediateTraceData.add(gppSample);
   189         	gppSample.cpuNumber = currentCpuNumber;
       
   190             
       
   191         	gppSamples.add(gppSample);
   147           }
   192           }
   148           else if (thread.index >= -1)
   193           else if (thread.index >= -1)
   149 	      {
   194 	      {
   150             if (thread.index == -1) thread.index = threadIndexer++;
   195             if (thread.index == -1) thread.index = threadIndexer++;
   151 
   196 
   162             
   207             
   163             //System.out.println("PC value:"+pc+" "+Long.toHexString(pc));
   208             //System.out.println("PC value:"+pc+" "+Long.toHexString(pc));
   164             
   209             
   165             gppSample.sampleSynchTime = time;
   210             gppSample.sampleSynchTime = time;
   166             gppSample.thread = thread;
   211             gppSample.thread = thread;
       
   212         	gppSample.cpuNumber = currentCpuNumber;
   167             thread.samples++;
   213             thread.samples++;
   168             intermediateTraceData.add(gppSample);
   214             gppSamples.add(gppSample);
   169           }
   215           }
   170         }
   216         }
   171       }
   217       }
   172       catch (EOFException e) {}
   218       catch (EOFException e) {}
   173     }
   219     }
   174     if (debug) System.out.println(Messages.getString("GppTraceParser.2"));  //$NON-NLS-1$
   220     if (debug) System.out.println(Messages.getString("GppTraceParser.2"));  //$NON-NLS-1$
   175     // all samples have been parsed
   221     // all samples have been parsed
   176     this.traceData = new GppSample[intermediateTraceData.size()];
       
   177 
       
   178     // store the trace data into an array
       
   179     intermediateTraceData.toArray(this.traceData);
       
   180 
       
   181     // sort the threads into an ordered array
       
   182     this.sortThreads();
       
   183     
       
   184     container = new TraceDataContainer("GPP_address2threadname",new String[]{"address","threadname"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
       
   185     Enumeration<Long> ke = this.threadAddressToName.keys();
       
   186     Iterator<String>  vi = this.threadAddressToName.values().iterator();
       
   187     
       
   188     while(ke.hasMoreElements())
       
   189     {
       
   190     	Long address = ke.nextElement();
       
   191     	String name = vi.next();
       
   192     	container.addDataToColumn("threadname",name); //$NON-NLS-1$
       
   193     	container.addDataToColumn("address",address); //$NON-NLS-1$
       
   194     }
       
   195     this.threadAddressToName.clear();
       
   196     this.threadAddressToName = null;
       
   197     
       
   198     ParsedTraceData pd = new ParsedTraceData();
       
   199     pd.traceData = this.getTrace();
       
   200         
       
   201     return pd;
       
   202   }
       
   203   
       
   204   private void sortThreads()
       
   205   {
       
   206     if (this.threads != null)
       
   207     {
       
   208       boolean sorted = false;
       
   209 
       
   210       GppThread[] tArray = new GppThread[this.threads.size()];
       
   211       Collection<GppThread> threadCollection = this.threads.values();
       
   212       threadCollection.toArray(tArray);
       
   213 
       
   214       // set initial sort order to the order in which
       
   215       // the threads appear in the array
       
   216       for (int i = 0; i < tArray.length; i++)
       
   217       {
       
   218         tArray[i].sortOrder = i;
       
   219       }
       
   220 
       
   221       // sort threads using bubble sort
       
   222       while (sorted == false)
       
   223       {
       
   224         sorted = true;
       
   225         for (int i = 0; i < tArray.length - 1; i++)
       
   226         {
       
   227           if (tArray[i].samples < tArray[i + 1].samples)
       
   228           {
       
   229               // switch the sort order
       
   230               GppThread store = tArray[i];
       
   231               tArray[i] = tArray[i + 1];
       
   232               tArray[i + 1] = store;
       
   233               sorted = false;
       
   234           }
       
   235         }
       
   236       }
       
   237 
       
   238       // finally, store the ordered array
       
   239       this.sortedThreads = tArray;
       
   240       for (int i=0;i<this.sortedThreads.length;i++)
       
   241       {
       
   242         this.sortedThreads[i].sortOrder = i;
       
   243       }
       
   244 
       
   245     }
       
   246   }
   222   }
   247 
   223 
   248   private boolean validate(DataInputStream dis) throws IOException
   224   private boolean validate(DataInputStream dis) throws IOException
   249   {
   225   {
   250     String data = decodeName(dis);
   226     String data = decodeName(dis);
   274     		}
   250     		}
   275     		else if (id.equals("Samp"))  //$NON-NLS-1$
   251     		else if (id.equals("Samp"))  //$NON-NLS-1$
   276     		{
   252     		{
   277     			this.samplerVersion = st.nextToken();
   253     			this.samplerVersion = st.nextToken();
   278     		}
   254     		}
       
   255     		else if(id.equals("CPU"))
       
   256     		{
       
   257     			
       
   258     			this.currentCpuNumber = Integer.parseInt(st.nextToken());
       
   259     			cpuCount++;
       
   260     		}
   279     	}
   261     	}
   280                
   262                
   281         System.out.println(Messages.getString("GppTraceParser.4")+traceVersion+Messages.getString("GppTraceParser.5")+profilerVersion+Messages.getString("GppTraceParser.6")+samplerVersion);    //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
   263         System.out.println(Messages.getString("GppTraceParser.4")+traceVersion+Messages.getString("GppTraceParser.5")+profilerVersion+Messages.getString("GppTraceParser.6")+samplerVersion+" CPU: "+currentCpuNumber);    //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
   282 		
   264 		
   283 		if (   (traceVersion.indexOf("V1.10") != -1)	//$NON-NLS-1$
   265 		if (   (traceVersion.indexOf("V1.10") != -1)	//$NON-NLS-1$
   284 			|| (traceVersion.indexOf("V1.64") != -1)	//$NON-NLS-1$
   266 			|| (traceVersion.indexOf("V1.64") != -1)	//$NON-NLS-1$
       
   267 			|| (traceVersion.indexOf("V2.00") != -1)	//$NON-NLS-1$
   285 			|| (traceVersion.indexOf("V2.01") != -1))	//$NON-NLS-1$
   268 			|| (traceVersion.indexOf("V2.01") != -1))	//$NON-NLS-1$
   286             return true;
   269             return true;
   287       	else
   270       	else
   288       		return false;
   271       		return false;
   289     }
   272     }
   290     
   273     
   291     return false;
   274     return false;
   292   }
   275   }
   293 
   276 
   294   	public static void encodeInt(int number, DataOutputStream dos) throws IOException
   277   private static void encodeInt(int number, DataOutputStream dos) throws IOException
   295 	{
   278 	{
   296 		int digit;
   279 		int digit;
   297 		for (;;) {
   280 		for (;;) {
   298 			digit = number & 0x7f;
   281 			digit = number & 0x7f;
   299 			if ((number >> 6) == (number >> 7))
   282 			if ((number >> 6) == (number >> 7))
   304 		dos.write(digit | 0x80);
   287 		dos.write(digit | 0x80);
   305 		
   288 		
   306 		dos.flush();
   289 		dos.flush();
   307 	}
   290 	}
   308 	
   291 	
   309 	public static void encodeUInt(int number, DataOutputStream dos) throws IOException
   292   private static void encodeUInt(int number, DataOutputStream dos) throws IOException
   310 	{
   293 	{
   311 		int digit;
   294 		int digit;
   312 		for (;;) {
   295 		for (;;) {
   313 			digit = number & 0x7f;
   296 			digit = number & 0x7f;
   314 			number >>= 7;
   297 			number >>= 7;
   317 			dos.write(digit);
   300 			dos.write(digit);
   318 		}
   301 		}
   319 		dos.write(digit | 0x80);		
   302 		dos.write(digit | 0x80);		
   320 	}
   303 	}
   321   
   304   
   322   public static long decodeInt(DataInputStream dis) throws IOException
   305   private static long decodeInt(DataInputStream dis) throws IOException
   323   {
   306   {
   324     //System.out.println("DECODING INT");
   307     //System.out.println("DECODING INT");
   325 
   308 
   326 	int val = 0;
   309 	int val = 0;
   327     int shift = 0;
   310     int shift = 0;
   345 
   328 
   346     return (val);
   329     return (val);
   347   }
   330   }
   348 
   331 
   349 
   332 
   350   public static long decodeUInt(DataInputStream dis) throws IOException
   333   private static long decodeUInt(DataInputStream dis) throws IOException
   351   {
   334   {
   352     //System.out.println("DECODING UINT");
   335     //System.out.println("DECODING UINT");
   353     long val = 0;
   336     long val = 0;
   354     int shift = 0;
   337     int shift = 0;
   355     int data;
   338     int data;
   381   }
   364   }
   382 
   365 
   383   private GppProcess decodeProcess(DataInputStream dis) throws IOException
   366   private GppProcess decodeProcess(DataInputStream dis) throws IOException
   384   {
   367   {
   385     //System.out.println("DECODING PROCESS");
   368     //System.out.println("DECODING PROCESS");
   386     Integer pid = new Integer((int)decodeUInt(dis));
   369     Integer pid = Integer.valueOf((int)decodeUInt(dis));
   387 
   370 
   388     if (this.processes.containsKey(pid))
   371     if (this.processes.containsKey(pid))
   389     {
   372     {
   390       return (GppProcess)this.processes.get(pid);
   373       return (GppProcess)this.processes.get(pid);
   391     }
   374     }
   400   }
   383   }
   401 
   384 
   402   private GppThread decodeThread(DataInputStream dis) throws IOException
   385   private GppThread decodeThread(DataInputStream dis) throws IOException
   403   {
   386   {
   404     //System.out.println("DECODING THREAD");
   387     //System.out.println("DECODING THREAD");
   405     Integer tid = new Integer((int)decodeUInt(dis));
   388     Integer tid = Integer.valueOf((int)decodeUInt(dis));
   406 
   389 
   407     if (this.threads.containsKey(tid))
   390     if (this.threads.containsKey(tid))
   408     {
   391     {
   409       return (GppThread)this.threads.get(tid);
   392       return (GppThread)this.threads.get(tid);
   410     }
   393     }
   416 	{
   399 	{
   417     	if (name.endsWith("]")) //$NON-NLS-1$
   400     	if (name.endsWith("]")) //$NON-NLS-1$
   418     	{
   401     	{
   419     		String l = name.substring(name.lastIndexOf("[")+1,name.lastIndexOf("]")); //$NON-NLS-1$ //$NON-NLS-2$
   402     		String l = name.substring(name.lastIndexOf("[")+1,name.lastIndexOf("]")); //$NON-NLS-1$ //$NON-NLS-2$
   420     		Long threadAddress = Long.decode("0x"+l); //$NON-NLS-1$
   403     		Long threadAddress = Long.decode("0x"+l); //$NON-NLS-1$
   421     		this.threadAddressToName.put(threadAddress,name);
   404 //    		this.threadAddressToName.put(threadAddress,name);
       
   405     		this.threadAddressToName.put(threadAddress,p.name+"::"+name);
   422     		name = name.substring(0,name.lastIndexOf("[")); //$NON-NLS-1$
   406     		name = name.substring(0,name.lastIndexOf("[")); //$NON-NLS-1$
   423     	}
   407     	}
   424 	}
   408 	}
   425     catch (Exception e)
   409     catch (Exception e)
   426 	{
   410 	{
   436     this.threads.put(tid,nt);
   420     this.threads.put(tid,nt);
   437 
   421 
   438     return nt;
   422     return nt;
   439   }
   423   }
   440   
   424   
   441   private GenericTrace getTrace()
   425   private GppTrace getTrace(List<GppSample> samples)
   442   {
   426   {
   443   	GppTrace trace = new GppTrace();
   427   	GppTrace trace = new GppTrace();
   444   	for (int i = 0; i < traceData.length; i++)
   428   	for (GppSample gppSample : samples) {
   445   	{
   429   		trace.addSample(gppSample);
   446   		trace.addSample(this.traceData[i]);
   430 	}
   447   	}
   431   	trace.setCPUCount(cpuCount == 0 ? 1 : cpuCount);
   448   	return trace;
   432   	return trace;
   449   }
   433   }
   450 }
   434 }
   451 
   435