From: jjenista Date: Tue, 7 Sep 2010 19:40:31 +0000 (+0000) Subject: Several changes: X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c49f3ca85da1e94cce7a3f795e9567f85194ff5e;p=IRC.git Several changes: -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. --- diff --git a/Robust/src/Benchmarks/oooJava/sor/makefile b/Robust/src/Benchmarks/oooJava/sor/makefile index 6eda14dd..d1de74d3 100644 --- a/Robust/src/Benchmarks/oooJava/sor/makefile +++ b/Robust/src/Benchmarks/oooJava/sor/makefile @@ -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: diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index a94cf7b8..d5729c55 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -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 );"); } diff --git a/Robust/src/Runtime/coreprof/coreprof.h b/Robust/src/Runtime/coreprof/coreprof.h index 2a176658..97f5749b 100644 --- a/Robust/src/Runtime/coreprof/coreprof.h +++ b/Robust/src/Runtime/coreprof/coreprof.h @@ -17,9 +17,7 @@ #include #include "runtime.h" - #ifndef CP_MAXEVENTWORDS -//#define CP_MAXEVENTWORDS (1024*1024*128) #define CP_MAXEVENTWORDS (1024*128) #endif @@ -29,20 +27,23 @@ // 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 ); } diff --git a/Robust/src/Runtime/workschedule.c b/Robust/src/Runtime/workschedule.c index 82c57278..9375b431 100644 --- a/Robust/src/Runtime/workschedule.c +++ b/Robust/src/Runtime/workschedule.c @@ -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 ); } diff --git a/Robust/src/Runtime/workschedule.h b/Robust/src/Runtime/workschedule.h index da0e3581..ac496da5 100644 --- a/Robust/src/Runtime/workschedule.h +++ b/Robust/src/Runtime/workschedule.h @@ -10,6 +10,11 @@ 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 diff --git a/Robust/src/buildscript b/Robust/src/buildscript index a0d05e25..dd5f0823 100755 --- a/Robust/src/buildscript +++ b/Robust/src/buildscript @@ -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 " 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"