Several changes:
authorjjenista <jjenista>
Tue, 7 Sep 2010 19:40:31 +0000 (19:40 +0000)
committerjjenista <jjenista>
Tue, 7 Sep 2010 19:40:31 +0000 (19:40 +0000)
-Can control space allocated for coreprof events with a buildscript option.

-Attempted to exit ooojava worker threads gracefully with pthread_cleanup_XXX
and pthread_cancel in asynchronous mode.  Cleanup doesn't trigger from asynch
cancel, so this doesn't do the trick.  The reason this is nice is that COREPROF_EXIT
is never called by worker threads, so the timestamp of the MAIN duration is being
fudged by using the last timestamp of a sub event.  If we wanted to add more
interesting functionality to COREPROF_EXIT we can't use the workaround and we'll
have to revisit this--left the commented pthread code as a starting point for later.

-Adjusted event IDs and the baseshift so same number of bits are used, but
it is easier to look at the coreprof output file in a hex editor to visually
inspect the raw data, for debugging.

Robust/src/Benchmarks/oooJava/sor/makefile
Robust/src/IR/Flat/BuildCode.java
Robust/src/Runtime/coreprof/coreprof.h
Robust/src/Runtime/workschedule.c
Robust/src/Runtime/workschedule.h
Robust/src/buildscript

index 6eda14ddb835654e50b652f8cfc9307ca4fc1e24..d1de74d317a290bbcd2f49b81a209f4b193238ba 100644 (file)
@@ -5,7 +5,7 @@ SOURCE_FILES=JGFSORBenchSizeD.java
 BUILDSCRIPT=../../../buildscript
 
 USEOOO= -ooojava 24 2  -ooodebug  
-BSFLAGS= -64bit -mainclass $(PROGRAM)  -heapsize-mb 1024 -garbagestats -debug -joptimize -noloop -optimize #-coreprof -coreprof-checkoverflow 
+BSFLAGS= -64bit -mainclass $(PROGRAM)  -heapsize-mb 1024 -garbagestats -debug -joptimize -noloop -optimize -coreprof -coreprof-eventwords 1024*1024*128 -coreprof-checkoverflow 
 DISJOINT= -disjoint -disjoint-k 1 -enable-assertions #-disjoint-desire-determinism
 
 default:
index a94cf7b8fca3026557cac5f4a89c8c82c21a475d..d5729c55bab283bdca387e3c8d9b88c4ff94430c 100644 (file)
@@ -2423,9 +2423,10 @@ public class BuildCode {
       ) {
        outmethod.println(  "      /* work scheduler works forever, explicitly exit */");
        if (state.COREPROF) {
-         outmethod.println("CP_EXIT();");
-         outmethod.println("CP_DUMP();");
+         outmethod.println("      CP_EXIT();");
+         outmethod.println("      CP_DUMP();");
        }
+        outmethod.println(  "      workScheduleExit();");
        outmethod.println(  "      exit( 0 );");
       }
 
index 2a176658d29a48dff5fadb9f4fc92d5764a71d89..97f5749b7dd94f0edfb1484bc2b65230c719f4fe 100644 (file)
@@ -17,9 +17,7 @@
 #include <stdlib.h>
 #include "runtime.h"
 
-
 #ifndef CP_MAXEVENTWORDS
-//#define CP_MAXEVENTWORDS (1024*1024*128)
 #define CP_MAXEVENTWORDS (1024*128)
 #endif
 
 // and BASESHIFT is for shifting IDs
 // past the type bits
 #define CP_EVENT_MASK       3
-#define CP_EVENT_BASESHIFT  2
+#define CP_EVENT_BASESHIFT  8
 
-#define CP_EVENTTYPE_BEGIN  0
-#define CP_EVENTTYPE_END    1
-#define CP_EVENTTYPE_ONEOFF 2
+#define CP_EVENTTYPE_BEGIN  1
+#define CP_EVENTTYPE_END    2
+#define CP_EVENTTYPE_ONEOFF 3
 
 // Event IDs
-#define CP_EVENTID_MAIN         0
-#define CP_EVENTID_RUNMALLOC    1
-#define CP_EVENTID_RUNFREE      2
-#define CP_EVENTID_TASKDISPATCH 3
-#define CP_EVENTID_TASKRETIRE   4
-#define CP_EVENTID_TASKSTALLVAR 5
-#define CP_EVENTID_TASKSTALLMEM 6
+#define CP_EVENTID_MAIN         0x04
+#define CP_EVENTID_RUNMALLOC    0x05
+#define CP_EVENTID_RUNFREE      0x06
+#define CP_EVENTID_TASKDISPATCH 0x07
+#define CP_EVENTID_TASKRETIRE   0x08
+#define CP_EVENTID_TASKSTALLVAR 0x09
+#define CP_EVENTID_TASKSTALLMEM 0x0a
+// Note: application-specific events (assigned
+// during code gen) start at 0x100
+
 
 
 extern __thread int                     cp_threadnum;
@@ -65,7 +66,7 @@ struct coreprofmonitor {
 #define CP_CHECKOVERFLOW ;
 #else
 #define CP_CHECKOVERFLOW if \
-  ( cp_monitor->numWords == CP_MAXEVENTWORDS ) \
+  ( cp_monitor->numWords >= CP_MAXEVENTWORDS ) \
   { cp_reportOverflow(); }
 #endif
 
@@ -96,16 +97,16 @@ void cp_reportOverflow();
 
 
 static inline void* cp_calloc( int size ) {
-  //CP_LOGEVENT( CP_EVENTID_RUNMALLOC, CP_EVENTTYPE_BEGIN );
+  CP_LOGEVENT( CP_EVENTID_RUNMALLOC, CP_EVENTTYPE_BEGIN );
   void* mem = calloc( 1, size );
-  //CP_LOGEVENT( CP_EVENTID_RUNMALLOC, CP_EVENTTYPE_END );
+  CP_LOGEVENT( CP_EVENTID_RUNMALLOC, CP_EVENTTYPE_END );
   return mem;
 }
 
 static inline void cp_free( void* ptr ) {
-  //CP_LOGEVENT( CP_EVENTID_RUNFREE, CP_EVENTTYPE_BEGIN );
+  CP_LOGEVENT( CP_EVENTID_RUNFREE, CP_EVENTTYPE_BEGIN );
   free( ptr );
-  //CP_LOGEVENT( CP_EVENTID_RUNFREE, CP_EVENTTYPE_END );
+  CP_LOGEVENT( CP_EVENTID_RUNFREE, CP_EVENTTYPE_END );
 }
 
 
index 82c57278c310998423f4b51a54ab59b7e8cfee63..9375b4314f69d9f6037c2390e19ff854dbef2fca 100644 (file)
@@ -50,19 +50,33 @@ extern __thread SESEcommon* seseCommon;
 
 __thread int oid;
 
+
+
+void workerExit( void* arg ) {
+  //printf( "Thread %d canceled.\n", pthread_self() );
+  CP_EXIT();
+}
+
+
+
 void* workerMain( void* arg ) {
-  void* workUnit;
+  void*       workUnit;
   WorkerData* myData = (WorkerData*) arg;
-  //Start profiler
+  int         oldState;
+
+  // once-per-thread stuff
   CP_CREATE();
+
+  //pthread_cleanup_push( workerExit, NULL );  
   
-  oid=myData->id;
-  // make sure init mlp once-per-thread stuff
+  oid = myData->id;
 
-  // all workers wait until system is ready
+  //pthread_setcanceltype ( PTHREAD_CANCEL_ASYNCHRONOUS, &oldState );
+  //pthread_setcancelstate( PTHREAD_CANCEL_ENABLE,       &oldState );
 
   // then continue to process work
   while( 1 ) {
+
     pthread_mutex_lock( &systemLockOut );
     // wait for work
     if (headqi->next==NULL) {
@@ -75,7 +89,6 @@ void* workerMain( void* arg ) {
     workUnit = headqi->value;
     pthread_mutex_unlock( &systemLockOut );
     free(tmp);
-
     
     pthread_mutex_lock(&gclistlock);
     threadcount++;
@@ -103,7 +116,7 @@ void* workerMain( void* arg ) {
     pthread_mutex_unlock(&gclistlock);
   }
 
-  CP_EXIT();
+  //pthread_cleanup_pop( 0 );
 
   return NULL;
 }
@@ -112,6 +125,11 @@ void workScheduleInit( int numProcessors,
                        void(*func)(void*) ) {
   int i, status;
 
+  // the original thread must call this now to
+  // protect memory allocation events coming, but it
+  // will also add itself to the worker pool and therefore
+  // try to call it again, CP_CREATE should just ignore
+  // duplicate calls
   CP_CREATE();
 
   pthread_mutex_init(&gclock, NULL);
@@ -128,18 +146,24 @@ void workScheduleInit( int numProcessors,
   status = pthread_mutex_init( &systemLockIn, NULL );
   status = pthread_mutex_init( &systemLockOut, NULL );
 
-  workerDataArray = RUNMALLOC( sizeof( WorkerData ) * numWorkers );
+  // allocate space for one more--the original thread (running
+  // this code) will become a worker thread after setup
+  workerDataArray = RUNMALLOC( sizeof( WorkerData ) * (numWorkers+1) );
+
+  for( i = 0; i < numWorkers; ++i ) {
+
+    // the original thread is ID 1, start counting from there
+    workerDataArray[i].id = 2 + i;
 
-  for( i = 0; i < numWorkers; ++i ) {   
-    workerDataArray[i].id=i+2;
     status = pthread_create( &(workerDataArray[i].workerThread), 
                              NULL,
                              workerMain,
                              (void*) &(workerDataArray[i])
                            );
+
     if( status != 0 ) { printf( "Error\n" ); exit( -1 ); }
 
-    // yield and let all workers get to the beginx3
+    // yield and let all workers get to the begin
     // condition variable, waiting--we have to hold them
     // so they don't all see empty work queues right away
     if( sched_yield() == -1 ) { printf( "Error thread trying to yield.\n" ); exit( -1 ); }
@@ -158,15 +182,41 @@ void workScheduleSubmit( void* workUnit ) {
 }
 
 
-// really should be named "wait until work is finished"
+// really should be named "add original thread as a worker"
 void workScheduleBegin() {
-  int i;  
-  WorkerData *workerData = RUNMALLOC( sizeof( WorkerData ) );
-  workerData->id=1;
-  workerMain(workerData);
+  int i;
 
-  // tell all workers to begin
-  for( i = 0; i < numWorkers; ++i ) {
-    pthread_join( workerDataArray[i].workerThread, NULL );
-  }
+  // space was saved for the original thread to become a
+  // worker after setup is complete
+  workerDataArray[numWorkers].id           = 1;
+  workerDataArray[numWorkers].workerThread = pthread_self();
+  ++numWorkers;
+
+  workerMain( &(workerDataArray[numWorkers-1]) );
+}
+
+
+// the above function does NOT naturally join all the worker
+// threads at exit, once the main SESE/Rblock/Task completes
+// we know all worker threads are finished executing other
+// tasks so we can explicitly kill the workers, and therefore
+// trigger any worker-specific cleanup (like coreprof!)
+void workScheduleExit() {
+  int i;
+
+  // This is not working well--canceled threads don't run their
+  // thread-level exit routines?  Anyway, its not critical for
+  // coreprof but if we ever need a per-worker exit routine to
+  // run we'll have to look back into this.
+
+  //printf( "Thread %d performing schedule exit.\n", pthread_self() );
+  //
+  //for( i = 0; i < numWorkers; ++i ) {   
+  //  if( pthread_self() != workerDataArray[i].workerThread ) {
+  //    pthread_cancel( workerDataArray[i].workerThread );      
+  //  }
+  //}
+  //
+  //// how to let all the threads actually get canceled?  
+  //sleep( 2 );
 }
index da0e3581e6cf6761f6abe696c2a68047996d4f58..ac496da5bf8c9a8db47ad57650779eaa4bec4164 100644 (file)
 void workScheduleInit( int numProcessors,
                        void(*workFunc)(void*) );
 
+// as the scheduler evolves, looks like this is
+// a better way to shut down the system
+void workScheduleExit();
+
+
 // your main program, before beginning this
 // system, or the execution of worker threads
 // themselves use this submit function to
index a0d05e2537758a15bf2964978d00284584a8cf8a..dd5f0823ef06141faec6f0af7490b2ba8a94e6a0 100755 (executable)
@@ -18,6 +18,7 @@ echo "-eventmonitor turn on transaction event trace recording"
 echo
 echo OOOJava options
 echo -coreprof turn on profiling API
+echo -coreprof-eventwords NUM  space in words/thread for coreprof events
 echo -coreprof-checkoverflow ONLY use for debugging event overflow
 echo "-ooojava <numberofcores> <maxseseage>"
 echo -ooodebug general OOOJava debugging messages
@@ -538,6 +539,11 @@ COREPROF=true
 JAVAOPTS="$JAVAOPTS -coreprof"
 EXTRAOPTIONS="$EXTRAOPTIONS -DCOREPROF -I$ROBUSTROOT/Runtime/coreprof"
 
+elif [[ $1 = '-coreprof-eventwords' ]]
+then
+EXTRAOPTIONS="$EXTRAOPTIONS -DCP_MAXEVENTWORDS=($2)"
+shift
+
 elif [[ $1 = '-coreprof-checkoverflow' ]]
 then
 EXTRAOPTIONS="$EXTRAOPTIONS -DCOREPROF_CHECKOVERFLOW"