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)); |
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)) |
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 { |