6 // everything defined here should match coreprof.h
8 public static final int CP_EVENT_MASK = 3;
9 public static final int CP_EVENT_BASESHIFT = 8;
11 public static final int CP_EVENTTYPE_BEGIN = 1;
12 public static final int CP_EVENTTYPE_END = 2;
13 public static final int CP_EVENTTYPE_ONEOFF = 3;
15 public static final int CP_EVENTID_MAIN = 0x04;
16 public static final int CP_EVENTID_RUNMALLOC = 0x10;
17 public static final int CP_EVENTID_RUNFREE = 0x11;
18 public static final int CP_EVENTID_COUNT_POOLALLOC = 0x15;
19 public static final int CP_EVENTID_COUNT_POOLREUSE = 0x16;
20 public static final int CP_EVENTID_WORKSCHEDGRAB = 0x20;
21 public static final int CP_EVENTID_TASKDISPATCH = 0x30;
22 public static final int CP_EVENTID_PREPAREMEMQ = 0x31;
23 public static final int CP_EVENTID_TASKEXECUTE = 0x40;
24 public static final int CP_EVENTID_TASKRETIRE = 0x50;
25 public static final int CP_EVENTID_TASKSTALLVAR = 0x60;
26 public static final int CP_EVENTID_TASKSTALLMEM = 0x61;
27 public static final int CP_EVENTID_DEBUG_A = 0x180;
28 public static final int CP_EVENTID_DEBUG_B = 0x181;
29 public static final int CP_EVENTID_DEBUG_C = 0x182;
30 public static final int CP_EVENTID_DEBUG_D = 0x183;
31 public static final int CP_EVENTID_DEBUG_E = 0x184;
32 public static final int CP_EVENTID_DEBUG_F = 0x185;
33 public static final int CP_EVENTID_DEBUG_G = 0x186;
34 public static final int CP_EVENTID_DEBUG_H = 0x187;
35 public static final int CP_EVENTID_DEBUG_I = 0x188;
36 public static final int CP_EVENTID_DEBUG_J = 0x189;
40 eid2name = new Hashtable<Integer, String>();
41 eid2name.put( CP_EVENTID_MAIN, "MAIN " );
42 eid2name.put( CP_EVENTID_RUNMALLOC, "RUNMALLOC " );
43 eid2name.put( CP_EVENTID_RUNFREE, "RUNFREE " );
44 eid2name.put( CP_EVENTID_RUNFREE, "POOLALLOC " );
45 eid2name.put( CP_EVENTID_RUNFREE, "POOLREUSE " );
46 eid2name.put( CP_EVENTID_WORKSCHEDGRAB, "WORKSCHEDGRAB" );
47 eid2name.put( CP_EVENTID_TASKDISPATCH, "TASKDISPATCH " );
48 eid2name.put( CP_EVENTID_PREPAREMEMQ, "PREPAREMEMQ " );
49 eid2name.put( CP_EVENTID_TASKEXECUTE, "TASKEXECUTE " );
50 eid2name.put( CP_EVENTID_TASKRETIRE, "TASKRETIRE " );
51 eid2name.put( CP_EVENTID_TASKSTALLVAR, "TASKSTALLVAR " );
52 eid2name.put( CP_EVENTID_TASKSTALLMEM, "TASKSTALLMEM " );
53 eid2name.put( CP_EVENTID_DEBUG_A, "DEBUG A " );
54 eid2name.put( CP_EVENTID_DEBUG_B, "DEBUG B " );
55 eid2name.put( CP_EVENTID_DEBUG_C, "DEBUG C " );
56 eid2name.put( CP_EVENTID_DEBUG_D, "DEBUG D " );
57 eid2name.put( CP_EVENTID_DEBUG_E, "DEBUG E " );
58 eid2name.put( CP_EVENTID_DEBUG_F, "DEBUG F " );
59 eid2name.put( CP_EVENTID_DEBUG_G, "DEBUG G " );
60 eid2name.put( CP_EVENTID_DEBUG_H, "DEBUG H " );
61 eid2name.put( CP_EVENTID_DEBUG_I, "DEBUG I " );
62 eid2name.put( CP_EVENTID_DEBUG_J, "DEBUG J " );
65 Hashtable<Integer, String> eid2name;
69 public static void main( String args[] ) {
70 if( args.length < 2 ||
72 System.out.println( "usage: [-2txt] <coreprof.dat file> <trace out file>" );
73 System.out.println( "The -2txt option will take the raw binary events and spit\n"+
74 "out every event as text in events.txt, useful for debugging\n"+
75 "event mis-matches." );
80 if( args[0].equals( "-2txt" ) ) {
81 t = new Trace( true, args[1], args[2] );
83 t = new Trace( false, args[0], args[1] );
89 // event IDs are a word, timestamps are long ints
90 public static final int WORD_SIZE = 4;
91 public static final int EVENT_SIZE = WORD_SIZE;
92 public static final int TIMESTAMP_SIZE = WORD_SIZE*2;
95 ThreadData[] threadData;
98 BufferedWriter txtStream;
102 public Trace( boolean c2txt, String inFile, String outFile ) {
106 openInputStreams( inFile );
110 for( int i = 0; i < numThreads; i++ ) {
114 printStats( outFile );
118 public static int readInt( InputStream is ) {
125 int retval = (b4<<24)|(b3<<16)|(b2<<8)|b1;
132 } catch( Exception e ) {
138 public static long readLong( InputStream is ) {
150 (b8<<56)|(b7<<48)|(b6<<40)|(b5<<32)|
151 (b4<<24)|(b3<<16)|(b2<< 8)|b1;
158 } catch( Exception e ) {
164 protected void openInputStreams( String filename ) {
166 BufferedInputStream bis = null;
170 bis = new BufferedInputStream( new FileInputStream( filename ) );
171 offset = readHeader( bis );
175 txtStream = new BufferedWriter( new FileWriter( "events.txt" ) );
178 } catch( Exception e ) {
183 for( int i = 0; i < numThreads; ++i ) {
185 // point a thread's event stream to the
186 // beginning of its data within the input file
187 threadData[i].dataStream =
188 new BufferedInputStream( new FileInputStream( filename ) );
192 skip -= threadData[i].dataStream.skip( skip );
195 offset += WORD_SIZE*threadData[i].numDataWords;
197 } catch( Exception e ) {
205 int readHeader( BufferedInputStream bis ) {
208 int version = readInt( bis );
210 throw new Error( "Unsupported Version" );
212 int offset = WORD_SIZE;
214 // read number of threads
215 numThreads = readInt( bis );
218 threadData = new ThreadData[numThreads];
220 // read number of words used for all events, per thread
221 for( int i = 0; i < numThreads; ++i ) {
222 threadData[i] = new ThreadData();
223 threadData[i].numDataWords = readInt( bis );
230 public void readThread( int tNum ) {
232 System.out.print( "Reading thread "+tNum );
236 txtStream.write( "\n\n\n\n" );
237 txtStream.write( "*************************************************\n" );
238 txtStream.write( "** Thread "+tNum+"\n" );
239 txtStream.write( "*************************************************\n" );
240 } catch( IOException e ) {
246 ThreadData tdata = threadData[tNum];
247 tdata.stackDepth = 0;
250 int numProgress = 10;
252 int progressChunk = tdata.numDataWords / numProgress;
254 boolean[] progress = new boolean[numProgress];
255 for( j = 0; j < numProgress; ++j ) {
260 while( i < tdata.numDataWords ) {
262 if( !progress[j] && i > j*progressChunk ) {
263 System.out.print( "." );
265 if( j < numProgress - 1 ) {
270 int eventRaw = readInt ( tdata.dataStream );
271 timeStamp = readLong( tdata.dataStream );
274 int eventType = eventRaw & CP_EVENT_MASK;
275 int eventID = eventRaw >> CP_EVENT_BASESHIFT;
277 switch( eventType ) {
279 case CP_EVENTTYPE_BEGIN: {
280 pushEvent( tdata, eventID, timeStamp );
283 case CP_EVENTTYPE_END: {
284 popEvent( tdata, eventID, timeStamp );
290 System.out.println( "" );
292 while( tdata.stackDepth > 0 ) {
293 // worker threads currently do not exit gracefully, and therefore
294 // may not register END events, so supply them with whatever the
295 // latest known timestamp is
296 EventSummary eventSummary = tdata.eventStack.get( tdata.stackDepth );
298 if( eventSummary == null ) {
299 // if there is no previous event it means there are no children
300 // events with a timestamp for the workaround, so just punt
304 popEvent( tdata, eventSummary.eventID, timeStamp );
311 protected void pushEvent( ThreadData tdata,
315 EventSummary eventSummary = null;
317 if( tdata.stackDepth == 0 ) {
318 // there are no parents, so look in the rootEvents
319 // for an existing EventSummary of this type
320 for( Iterator<EventSummary> itr = tdata.rootEvents.iterator();
323 EventSummary es = itr.next();
324 if( es.eventID == eventID ) {
329 if( eventSummary == null ) {
330 // there is no summary for this event type yet,
332 eventSummary = new EventSummary( eventID );
333 tdata.rootEvents.add( eventSummary );
337 // look through the parent's children for an existing
338 // EventSummary of this type
339 EventSummary esParent = tdata.eventStack.get( tdata.stackDepth - 1 );
340 for( Iterator<EventSummary> itr = esParent.children.iterator();
343 EventSummary es = itr.next();
344 if( es.eventID == eventID ) {
349 if( eventSummary == null ) {
350 // there is no summary for this event type yet,
351 // under this parent, so add it
352 eventSummary = new EventSummary( eventID );
353 esParent.children.add( eventSummary );
354 eventSummary.parent = esParent;
358 eventSummary.timeStampBeginLatestInstance = timeStamp;
360 eventSummary.instanceCount++;
362 if( tdata.eventStack.size() <= tdata.stackDepth ) {
363 tdata.eventStack.setSize( 2*tdata.stackDepth + 20 );
366 tdata.eventStack.set( tdata.stackDepth, eventSummary );
369 // print to the event text file (if needed) before
370 // updating the stack depth to get tabs right
373 for( int tabs = 0; tabs < tdata.stackDepth; ++tabs ) {
374 txtStream.write( " " );
376 txtStream.write( "begin "+getEventName( eventID )+"@"+timeStamp+"\n" );
377 } catch( IOException e ) {
388 protected void popEvent( ThreadData tdata,
394 // print to the event text file (if needed) after
395 // updating the stack depth to get tabs right
398 for( int tabs = 0; tabs < tdata.stackDepth; ++tabs ) {
399 txtStream.write( " " );
401 txtStream.write( "end "+getEventName( eventID )+"@"+timeStamp+"\n" );
402 } catch( IOException e ) {
409 if( tdata.stackDepth < 0 ) {
410 throw new Error( "Event stack underflow\n" );
413 EventSummary eventSummary = tdata.eventStack.get( tdata.stackDepth );
414 assert eventSummary != null;
416 if( eventSummary.eventID != eventID ) {
417 System.out.println( "Warning: event begin("+
418 getEventName( eventSummary.eventID )+
420 getEventName( eventID )+
425 timeStamp - eventSummary.timeStampBeginLatestInstance;
427 eventSummary.totalTime_ticks += elapsedTime;
428 eventSummary.selfTime_ticks += elapsedTime;
430 if( tdata.stackDepth - 1 >= 0 ) {
431 EventSummary esParent = tdata.eventStack.get( tdata.stackDepth-1 );
432 esParent.selfTime_ticks -= elapsedTime;
438 public void printStats( String filename ) {
440 System.out.println( "Printing..." );
444 new BufferedWriter( new FileWriter( filename ) );
446 for( int i = 0; i < numThreads; ++i ) {
448 ThreadData tdata = threadData[i];
450 bw.write( "----------------------------------\n" );
451 bw.write( "Thread "+i+"\n" );
453 for( Iterator<EventSummary> itr = tdata.rootEvents.iterator();
456 EventSummary es = itr.next();
457 printEventSummary( bw, es, 0 );
464 } catch( IOException e ) {
471 public String getEventName( int eventID ) {
473 eid2name.containsKey( eventID ) ?
474 eid2name.get ( eventID ) :
475 Integer.toString ( eventID );
479 public void printEventSummary( BufferedWriter bw,
484 String strIndent = "";
485 for( int i = 0; i < depth; ++i ) {
489 String strEventName = getEventName( es.eventID );
491 float tOfParent_perc;
492 String strPercParent = "";
493 if( es.parent != null ) {
494 float divisor = new Long( es.parent.totalTime_ticks ).floatValue();
495 if( divisor <= 0.00001f ) {
501 new Long( es.totalTime_ticks ).floatValue() /
504 strPercParent = String.format( " %%ofParent=%5.1f",
510 new Long( es.selfTime_ticks ).floatValue() /
511 new Long( es.totalTime_ticks ).floatValue();
513 String strSelfStats =
514 String.format( " total(ticks)=%12dK, %%self=%5.1f, count=%d",
515 es.totalTime_ticks/1000,
525 for( Iterator<EventSummary> itr = es.children.iterator();
528 EventSummary esChild = itr.next();
529 printEventSummary( bw, esChild, depth + 1 );