|
1 /* |
|
2 * Copyright (c) 2009 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.priority2; |
|
19 |
|
20 import java.io.ByteArrayInputStream; |
|
21 import java.io.DataInputStream; |
|
22 import java.io.EOFException; |
|
23 import java.io.File; |
|
24 import java.io.FileInputStream; |
|
25 import java.util.Enumeration; |
|
26 import java.util.Vector; |
|
27 |
|
28 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace; |
|
29 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData; |
|
30 import com.nokia.carbide.cpp.internal.pi.model.Parser; |
|
31 import com.nokia.carbide.cpp.pi.util.GeneralMessages; |
|
32 |
|
33 |
|
34 public class NewPriTraceParser extends Parser |
|
35 { |
|
36 private boolean debug = false; |
|
37 |
|
38 private String version; |
|
39 |
|
40 private Vector<NewPriThread> priSamples = new Vector<NewPriThread>(); |
|
41 private String threadName; |
|
42 private String processName; |
|
43 private int threadId; |
|
44 private int sampleNum; |
|
45 private int threadPriority; |
|
46 private NewPriSample priSample; |
|
47 private NewPriTrace priTrace; |
|
48 private int readCount = 0; |
|
49 |
|
50 public NewPriTraceParser(File file) throws Exception |
|
51 { |
|
52 } |
|
53 |
|
54 public ParsedTraceData parse(File f) throws Exception |
|
55 { |
|
56 if (!f.exists() || f.isDirectory()) |
|
57 { |
|
58 throw new Exception(Messages.getString("NewPriTraceParser.cannotOpenMemoryTrace")); //$NON-NLS-1$ |
|
59 } |
|
60 if (debug) System.out.println(Messages.getString("NewPriTraceParser.memoryTraceFileLength")+f.length()); //$NON-NLS-1$ |
|
61 |
|
62 parsePriTrace(f); |
|
63 |
|
64 ParsedTraceData ptd = new ParsedTraceData(); |
|
65 ptd.traceData = this.getTrace(); |
|
66 return ptd; |
|
67 } |
|
68 |
|
69 private void parseV155PriFile(DataInputStream dis) throws Exception |
|
70 { |
|
71 // read the version again |
|
72 byte[] version = readElementWithLength(dis); |
|
73 System.out.println(Messages.getString("NewPriTraceParser.readVersion")+new String(version)); //$NON-NLS-1$ |
|
74 this.version = new String(version); |
|
75 |
|
76 this.readV155PriSample(dis); |
|
77 } |
|
78 |
|
79 public String getProfilerVersion() |
|
80 { |
|
81 return version; |
|
82 } |
|
83 |
|
84 private void readV155PriSample(DataInputStream dis) throws Exception |
|
85 { |
|
86 Vector<long[]> rawV155PriSamples = new Vector<long[]>(); |
|
87 Vector<long[]> lastSampleRaw = new Vector<long[]>(); |
|
88 |
|
89 //memTrace = new MemTrace(); |
|
90 priTrace = new NewPriTrace(); |
|
91 |
|
92 // first there should be 4 bytes of sample time |
|
93 long sample = this.readTUintWithLength(dis); |
|
94 |
|
95 // then read if there is thread name data |
|
96 int length = dis.readUnsignedByte();readCount++; |
|
97 if(length != 1) throw new Exception(Messages.getString("NewPriTraceParser.missingType")); //$NON-NLS-1$ |
|
98 |
|
99 int mode = dis.readUnsignedByte();readCount++; |
|
100 System.out.println(Messages.getString("NewPriTraceParser.firstMode")+Integer.toHexString(mode)); //$NON-NLS-1$ |
|
101 try |
|
102 { |
|
103 // read the first length |
|
104 length = dis.readUnsignedByte();readCount++; |
|
105 |
|
106 Thread.currentThread().setPriority(Thread.MIN_PRIORITY); |
|
107 |
|
108 while(true) |
|
109 { |
|
110 //System.out.println("ReadCount:"+this.readCount); |
|
111 if(length == 0) |
|
112 { |
|
113 // end of sample |
|
114 // read new length |
|
115 |
|
116 // first there should be 4 bytes of sample time |
|
117 sample = this.readTUintWithLength(dis); |
|
118 //System.out.println("Sample number:"+sample); |
|
119 |
|
120 length = dis.readUnsignedByte();readCount++; |
|
121 //System.out.println("New length "+length); |
|
122 //break; |
|
123 |
|
124 if(length == 4) |
|
125 { |
|
126 // there was only the sample header here |
|
127 System.out.println(Messages.getString("NewPriTraceParser.missingSampleNum")+sample); //$NON-NLS-1$ |
|
128 mode = 0x00; |
|
129 } |
|
130 else if(length != 1) |
|
131 { |
|
132 throw new Exception(Messages.getString("NewPriTraceParser.wrongLength")+length); //$NON-NLS-1$ |
|
133 } |
|
134 else |
|
135 { |
|
136 lastSampleRaw.clear(); |
|
137 } |
|
138 } |
|
139 |
|
140 if(length == 1) |
|
141 { |
|
142 mode = dis.readUnsignedByte();readCount++; |
|
143 //System.out.println("New Mode "+mode+" new length "+length); |
|
144 |
|
145 // read the next length |
|
146 length = dis.readUnsignedByte();readCount++; |
|
147 //System.out.println("Next length "+length); |
|
148 } |
|
149 |
|
150 if(mode == 0xbb) |
|
151 { |
|
152 // reading thread names |
|
153 String rawName = readThreadName(dis,length); |
|
154 long threadId = readTUint(dis); |
|
155 //System.out.println("Raw name "+rawName); |
|
156 int index = rawName.indexOf(':'); |
|
157 if(index != -1) |
|
158 { |
|
159 processName = rawName.substring(0,index); |
|
160 threadName = rawName.substring(rawName.lastIndexOf(':')+1,rawName.length()); |
|
161 //System.out.println("Thread: "+threadName+" process: "+processName+" id: "+threadId); |
|
162 } |
|
163 else |
|
164 { |
|
165 processName = rawName; |
|
166 threadName = rawName; |
|
167 } |
|
168 |
|
169 priTrace.addFirstSynchTime(new Integer((int)threadId), new Integer(sampleNum)); |
|
170 priSamples.add(new NewPriThread(new Integer((int)threadId), threadName, processName)); |
|
171 |
|
172 // read the next length |
|
173 length = dis.readUnsignedByte();readCount++; |
|
174 //System.out.println("Next length "+length); |
|
175 } |
|
176 else if(mode == 0xee) |
|
177 { |
|
178 // reading data |
|
179 long[] elements = this.readDataElements155Pri(dis,length,sample); |
|
180 |
|
181 rawV155PriSamples.add(elements); |
|
182 lastSampleRaw.add(elements); |
|
183 |
|
184 // read the next length |
|
185 length = dis.readUnsignedByte();readCount++; |
|
186 //System.out.println("Next length "+length); |
|
187 } |
|
188 else if(mode == 0x00) |
|
189 { |
|
190 // read the length, it is already known |
|
191 sample = readTUint(dis); |
|
192 System.out.println(Messages.getString("NewPriTraceParser.readNextSampleNum")+sample); //$NON-NLS-1$ |
|
193 length = dis.readUnsignedByte();readCount++;; |
|
194 } |
|
195 else |
|
196 { |
|
197 throw new Exception(Messages.getString("NewPriTraceParser.wrongMode")+mode); //$NON-NLS-1$ |
|
198 } |
|
199 } |
|
200 } |
|
201 catch (EOFException e) |
|
202 { |
|
203 System.out.println(Messages.getString("NewPriTraceParser.finishedReading")); //$NON-NLS-1$ |
|
204 this.addRawV155PriSamples(rawV155PriSamples); |
|
205 } |
|
206 } |
|
207 |
|
208 private void addRawV155PriSamples(Vector<long[]> rawV110PriSamples) |
|
209 { |
|
210 NewPriThread[] priThreads = new NewPriThread[priSamples.size()]; |
|
211 priSamples.copyInto((NewPriThread[]) priThreads); |
|
212 priTrace.setThreads(priThreads); |
|
213 |
|
214 Enumeration<long[]> rawEnum = rawV110PriSamples.elements(); |
|
215 while(rawEnum.hasMoreElements()) |
|
216 { |
|
217 long[] element = rawEnum.nextElement(); |
|
218 threadId = (int)element[0]; |
|
219 threadPriority = (int)element[1]; |
|
220 // for the null thread, converts 8bit unsigned to signed |
|
221 if (threadPriority > 32768) |
|
222 threadPriority = threadPriority - 65536; |
|
223 |
|
224 sampleNum = (int)element[2]; |
|
225 |
|
226 for (Enumeration<NewPriThread> e = priSamples.elements();e.hasMoreElements();) |
|
227 { |
|
228 NewPriThread pt = e.nextElement(); |
|
229 if (pt.threadId == threadId) |
|
230 { |
|
231 //int priority = solveAbsolutPriority(processPriority, threadPriority); |
|
232 priSample = new NewPriSample(pt, threadPriority, sampleNum); |
|
233 priTrace.addSample(priSample); |
|
234 break; |
|
235 } |
|
236 } |
|
237 priTrace.addLastSynchTime(new Integer(threadId), new Integer(sampleNum)); |
|
238 } |
|
239 System.out.println(Messages.getString("NewPriTraceParser.doneParsing")); //$NON-NLS-1$ |
|
240 } |
|
241 |
|
242 private long[] readDataElements155Pri(DataInputStream dis,int length,long sampleNum) throws Exception |
|
243 { |
|
244 if(length != 0) |
|
245 { |
|
246 long[] elements = new long[3]; |
|
247 elements[0] = this.readTUint(dis); //thread ID |
|
248 elements[1] = this.readShort(dis); //Priority |
|
249 elements[2] = sampleNum; //sample number |
|
250 |
|
251 return elements; |
|
252 } |
|
253 else |
|
254 { |
|
255 System.out.println(Messages.getString("NewPriTraceParser.lengthIs0")); //$NON-NLS-1$ |
|
256 return null; |
|
257 } |
|
258 } |
|
259 |
|
260 |
|
261 private String readThreadName(DataInputStream dis,int length) throws Exception |
|
262 { |
|
263 if (length != 0) |
|
264 { |
|
265 length-=4; |
|
266 //System.out.println("Thread name length "+length); |
|
267 byte[] element = new byte[length]; |
|
268 dis.read(element,0,length); |
|
269 readCount+=length; |
|
270 return new String(element); |
|
271 } |
|
272 else return null; |
|
273 } |
|
274 |
|
275 private byte[] readElementWithLength(DataInputStream dis) throws Exception |
|
276 { |
|
277 byte length = dis.readByte(); readCount++; |
|
278 if (length != 0) |
|
279 { |
|
280 //System.out.println("Element length "+length); |
|
281 byte[] element = new byte[length]; |
|
282 dis.read(element,0,length); |
|
283 readCount += length; |
|
284 return element; |
|
285 } |
|
286 else return null; |
|
287 } |
|
288 |
|
289 private long readShort(DataInputStream dis) throws Exception |
|
290 { |
|
291 long result = dis.readUnsignedByte(); |
|
292 readCount++; |
|
293 result += dis.readUnsignedByte() << 8; |
|
294 readCount++; |
|
295 return result; |
|
296 } |
|
297 |
|
298 private long readTUint(DataInputStream dis) throws Exception |
|
299 { |
|
300 long result = dis.readUnsignedByte(); |
|
301 readCount++; |
|
302 result += dis.readUnsignedByte() << 8; |
|
303 readCount++; |
|
304 result += dis.readUnsignedByte() << 16; |
|
305 readCount++; |
|
306 result += dis.readUnsignedByte() << 24; |
|
307 readCount++; |
|
308 return result; |
|
309 } |
|
310 |
|
311 private long readTUintWithLength(DataInputStream dis) throws Exception |
|
312 { |
|
313 byte length = (byte)dis.readUnsignedByte(); |
|
314 readCount++; |
|
315 //System.out.println("Pituus: "+length); |
|
316 if (length != 4) |
|
317 { |
|
318 throw new Exception(Messages.getString("NewPriTraceParser.TUINTLengthException1")+length+Messages.getString("NewPriTraceParser.TUINTLengthException2")); //$NON-NLS-1$ //$NON-NLS-2$ |
|
319 } |
|
320 long result = dis.readUnsignedByte(); |
|
321 readCount++; |
|
322 result += dis.readUnsignedByte() << 8; |
|
323 readCount++; |
|
324 result += dis.readUnsignedByte() << 16; |
|
325 readCount++; |
|
326 result += dis.readUnsignedByte() << 24; |
|
327 readCount++; |
|
328 |
|
329 //System.out.println("Read length ok"); |
|
330 return result; |
|
331 } |
|
332 |
|
333 private void parsePriTrace(File file) throws Exception |
|
334 { |
|
335 DataInputStream dis = new DataInputStream(new FileInputStream(file)); |
|
336 byte[] traceArray = new byte[(int)file.length()]; |
|
337 dis.readFully(traceArray); |
|
338 |
|
339 // test the mem trace version |
|
340 if (traceArray.length > 257) |
|
341 { |
|
342 String s = new String(traceArray,1,traceArray[0]); |
|
343 |
|
344 if (!s.startsWith("Bappea_V1.56")) //up to 1.0 version //$NON-NLS-1$ |
|
345 { |
|
346 String version = s.substring(8,12); |
|
347 String traceType = s.substring(13,s.length()); |
|
348 System.out.println(Messages.getString("NewPriTraceParser.foundVersion1")+version+Messages.getString("NewPriTraceParser.foundVersion2")+traceType+Messages.getString("NewPriTraceParser.foundVersion3")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
349 |
|
350 GeneralMessages.showErrorMessage(Messages.getString("NewPriTraceParser.wrongTraceType1")+traceType+Messages.getString("NewPriTraceParser.wrongTraceType2")); //$NON-NLS-1$ //$NON-NLS-2$ |
|
351 throw new Exception(Messages.getString("NewPriTraceParser.wrongTraceType1")+traceType+Messages.getString("NewPriTraceParser.wrongTraceType2")); //$NON-NLS-1$ //$NON-NLS-2$ |
|
352 } |
|
353 else //handling 1.10 and newer versions |
|
354 { |
|
355 parseVersion155Trace(traceArray,s); |
|
356 return; |
|
357 } |
|
358 } |
|
359 else |
|
360 { |
|
361 GeneralMessages.showErrorMessage(Messages.getString("NewPriTraceParser.wrongVersionforPRI")); //$NON-NLS-1$ |
|
362 throw new Exception(Messages.getString("NewPriTraceParser.wrongTypeforPRI")); //$NON-NLS-1$ |
|
363 } |
|
364 } |
|
365 |
|
366 private void parseVersion155Trace(byte[] traceArray, String version_data) throws Exception |
|
367 { |
|
368 ByteArrayInputStream bais = new ByteArrayInputStream(traceArray); |
|
369 DataInputStream dis = new DataInputStream(bais); |
|
370 |
|
371 if (version_data.indexOf("PRI")>0) //only pritrace //$NON-NLS-1$ |
|
372 { |
|
373 this.parseV155PriFile(dis); |
|
374 } |
|
375 } |
|
376 |
|
377 private GenericSampledTrace getTrace() |
|
378 { |
|
379 //MemTrace trace = new MemTrace(); |
|
380 return (GenericSampledTrace) priTrace; |
|
381 } |
|
382 } |