# HG changeset patch # User Me # Date 1280347930 25200 # Node ID 0e008278fe3c0c8381450e4ee240b6af6746ae80 # Parent 8b9e4c333fe6f10a848b9c0f12faaad5c3a661cc Works Sequentially -- took out all threads and debugged -- works diff -r 8b9e4c333fe6 -r 0e008278fe3c CoreLoop.c --- a/CoreLoop.c Mon Jul 26 16:42:59 2010 -0700 +++ b/CoreLoop.c Wed Jul 28 13:12:10 2010 -0700 @@ -66,7 +66,7 @@ //To get label addr in non-gcc compiler, can trick it by making a call // to a fn that does asm that pulls the "return" // addr off the stack and stores it in a pointed-to location. - _VMSMasterEnv->coreLoopShutDownPt = &&CoreLoopEndPt; + _VMSMasterEnv->coreLoopEndPt = &&CoreLoopEndPt; //Core loop has no values live upon CoreLoopStartPt except workQ // every value in the code is defined by a statement in core loop, @@ -146,7 +146,7 @@ //To get label addr in non-gcc compiler, can trick it by making a call // to a fn that does asm that pulls the "return" // addr off the stack and stores it in a pointed-to location. - _VMSMasterEnv->coreLoopShutDownPt = &&CoreLoopEndPt; + _VMSMasterEnv->coreLoopEndPt = &&CoreLoopEndPt; //Core loop has no values live upon CoreLoopStartPt except workQ // every value in the code is defined by a statement in core loop, @@ -204,8 +204,13 @@ ); //======================================================================== - - //jmp to here when want to shut down the VMS system + //jmp to here when want to shut down the VMS system. A shutdown VP is + // made, one for each core loop -- its function sets the stack back + // to the core loop's stack then jumps to here. This causes the thread + // to exit, and so the entry point function, which has been waiting for + // all the threads to die will proceed, gather the result, and + // return to the calling application. CoreLoopEndPt: + VMS__handle_dissipate_reqst( currPr ); //free shutdown pr, that jmpd here return; } diff -r 8b9e4c333fe6 -r 0e008278fe3c MasterLoop.c --- a/MasterLoop.c Mon Jul 26 16:42:59 2010 -0700 +++ b/MasterLoop.c Wed Jul 28 13:12:10 2010 -0700 @@ -133,9 +133,10 @@ currSlot->needsProcrAssigned = FALSE; filledSlots[ numFilled ] = currSlot; - numFilled += 1; writeVMSQ( schedVirtPr, workQ ); + numFilled += 1; + if( numFilled == masterEnv->numToPrecede ) { writeVMSQ( masterEnv->masterVirtPr, workQ ); @@ -158,7 +159,7 @@ //TODO: look at dynamic behavior -- time-average numToPrecede or something if( numFilled < NUM_CORES - 1 ) { - masterEnv->numToPrecede = 0; + masterEnv->numToPrecede = 1; } else { masterEnv->numToPrecede = numFilled - NUM_CORES + 1; diff -r 8b9e4c333fe6 -r 0e008278fe3c VMS.c --- a/VMS.c Mon Jul 26 16:42:59 2010 -0700 +++ b/VMS.c Wed Jul 28 13:12:10 2010 -0700 @@ -389,8 +389,9 @@ { VMSReqst *req; req = procrWithReq->requests; + if( req == NULL ) return; procrWithReq->requests = procrWithReq->requests->nextReqst; - free( req ); + VMS__free_request( req ); } @@ -455,34 +456,6 @@ } -/*The semantic layer figures out when the work is done ( perhaps by a call - * in the application to "work all done", or perhaps all the virtual - * processors have dissipated.. a.s.o. ) - * - *The semantic layer is responsible for making sure all work has fully - * completed before using this to shutdown the VMS system. - * - *After the semantic layer has determined it wants to shut down, the - * next time the Master Loop calls the scheduler plug-in, the scheduler - * then calls this function and returns the virtual processor it gets back. - * - *When the shut-down processor runs, it first frees all locations malloc'd to - * the VMS system (that wasn't - * specified as return-locations). Then it creates one core-loop shut-down - * processor for each core loop and puts them all into the workQ. When a - * core loop animates a core loop shut-down processor, it causes exit-thread - * to run, and when all core loop threads have exited, then the "wait for - * work to finish" in the main thread is woken, and the function-call that - * started all the work returns. - * - *The function animated by this processor performs the shut-down work. - */ -VirtProcr * -VMS__create_the_shutdown_procr() - { - return VMS__create_procr( &shutdownFn, NULL ); - } - /*This must be called by the request handler plugin -- it cannot be called * from the semantic library "dissipate processor" function -- instead, the @@ -502,15 +475,14 @@ * of dis-owning it. */ void -VMS__free_procr_locs( VirtProcr *animatingPr ) +VMS__handle_dissipate_reqst( VirtProcr *animatingPr ) { //dis-own all locations owned by this processor, causing to be freed // any locations that it is (was) sole owner of - //TODO: implement VMS__malloc system, including "give up ownership" +//TODO: implement VMS__malloc system, including "give up ownership" //The dissipate request might still be attached, so remove and free it VMS__remove_and_free_top_request( animatingPr ); - free( animatingPr->startOfStack ); //NOTE: initialData was given to the processor, so should either have // been alloc'd with VMS__malloc, or freed by the level above animPr. @@ -521,54 +493,98 @@ } +//TODO: re-architect so that have clean separation between request handler +// and master loop, for dissipate, create, shutdown, and other non-semantic +// requests. Issue is chain: one removes requests from AppVP, one dispatches +// on type of request, and one handles each type.. but some types require +// action from both request handler and master loop -- maybe just give the +// request handler calls like: VMS__handle_X_request_type -/*This is the function run by the special "shut-down" processor +void +endOSThreadFn( void *initData, VirtProcr *animatingPr ); + +/*This is called by the semantic layer's request handler when it decides its + * time to shut down the VMS system. Calling this causes the core loop OS + * threads to exit, which unblocks the entry-point function that started up + * VMS, and allows it to grab the result and return to the original single- + * threaded application. * - *The _VMSMasterEnv is needed by this shut down function, so the "wait" - * function run in the main loop has to free it, and the thread-related - * locations (coreLoopThdParams a.s.o.). - *However, the semantic environment and all data malloc'd to VMS can be - * freed here. + *The _VMSMasterEnv is needed by this shut down function, so the create-seed- + * and-wait function has to free a bunch of stuff after it detects the + * threads have all died: the masterEnv, the thread-related locations, + * masterVP any AppVPs that might still be allocated and sitting in the + * semantic environment, or have been orphaned in the _VMSWorkQ. + * + *NOTE: the semantic plug-in is expected to use VMS__malloc_to to get all the + * locations it needs, and give ownership to masterVP. Then, they will be + * automatically freed when the masterVP is dissipated. (This happens after + * the core loop threads have all exited) * - *NOTE: the semantic plug-in is expected to use VMS__malloc to get all the - * locations it needs -- they will be automatically freed by the standard - * "free all owned locations" - * - *Free any locations malloc'd to the VMS system (that weren't - * specified as return-locations). - *Then create one core-loop shut-down processor for each core loop and puts - * them all into the workQ. + *In here,create one core-loop shut-down processor for each core loop and put + * them all directly into the workQ. + *Note, this function can ONLY be called after the semantic environment no + * longer cares if AppVPs get animated after the point this is called. In + * other words, this can be used as an abort, or else it should only be + * called when all AppVPs have finished dissipate requests -- only at that + * point is it sure that all results have completed. */ void -shutdownFn( void *dummy, VirtProcr *animatingPr ) +VMS__handle_shutdown_reqst( void *dummy, VirtProcr *animatingPr ) { int coreIdx; VirtProcr *shutDownPr; VMSQueueStruc *workQ = _VMSWorkQ; - //free all the locations owned within the VMS system - //TODO: write VMS__malloc and free.. -- take the DKU malloc as starting pt - - //make the core loop shut-down processors and put them into the workQ + //create the shutdown processors, one for each core loop -- put them + // directly into _VMSWorkQ -- each core will die when gets one, so + // the system distributes them evenly itself. for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) { - shutDownPr = VMS__create_procr( NULL, NULL ); - shutDownPr->nextInstrPt = _VMSMasterEnv->coreLoopShutDownPt; + shutDownPr = VMS__create_procr( &endOSThreadFn, NULL ); writeVMSQ( shutDownPr, workQ ); } - //This is an issue: the animating processor of this function may not - // get its request handled before all the cores have shutdown. - //TODO: after all the threads stop, clean out the MasterEnv, the - // SemanticEnv, and the workQ before returning. - VMS__dissipate_procr( animatingPr ); //will never come back from this } -/*This has to free anything allocated during VMS_init, and any other alloc'd +/*Am trying to be cute, avoiding IF statement in coreLoop that checks for + * a special shutdown procr. Ended up with extra-complex shutdown sequence. + *This function has the sole purpose of setting the stack and framePtr + * to the coreLoop's stack and framePtr.. it does that then jumps to the + * core loop's shutdown point -- might be able to just call Pthread_exit + * from here, but going back to the pthread's stack and setting everything + * up just as if it never jumped out, before calling pthread_exit. + *The end-point of core loop will free the stack and so forth of the + * processor that animates this function, (this fn is transfering the + * animator of the AppVP that is in turn animating this function over + * to core loop function -- note that this slices out a level of virtual + * processors). + */ +void +endOSThreadFn( void *initData, VirtProcr *animatingPr ) + { void *jmpPt, *coreLoopStackPtr, *coreLoopFramePtr; + + jmpPt = _VMSMasterEnv->coreLoopEndPt; + coreLoopStackPtr = animatingPr->coreLoopStackPtr; + coreLoopFramePtr = animatingPr->coreLoopFramePtr; + + + asm volatile("movl %0, %%eax; \ + movl %1, %%esp; \ + movl %2, %%ebp; \ + jmp %%eax " \ + /* outputs */ : \ + /* inputs */ : "m" (jmpPt), "m"(coreLoopStackPtr), "m"(coreLoopFramePtr)\ + /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi","%esi" \ + ); + } + + + +/*This is called has to free anything allocated during VMS_init, and any other alloc'd * locations that might be left over. */ void -VMS__shutdown() +VMS__cleanup_after_shutdown() { int i; free( _VMSWorkQ ); @@ -579,7 +595,7 @@ } free( _VMSMasterEnv->schedSlots); - VMS__free_procr_locs( _VMSMasterEnv->masterVirtPr ); + VMS__handle_dissipate_reqst( _VMSMasterEnv->masterVirtPr ); free( _VMSMasterEnv ); } diff -r 8b9e4c333fe6 -r 0e008278fe3c VMS.h --- a/VMS.h Mon Jul 26 16:42:59 2010 -0700 +++ b/VMS.h Wed Jul 28 13:12:10 2010 -0700 @@ -19,7 +19,8 @@ #define NUM_CORES 4 // make double-num-cores scheduling slots, plus extra for master -#define NUM_SCHED_SLOTS (2 * NUM_CORES + 1) +//#define NUM_SCHED_SLOTS (2 * NUM_CORES + 1) +#define NUM_SCHED_SLOTS 3 //128K stack.. compromise, want 10K virtPr #define VIRT_PROCR_STACK_SIZE 0x10000 @@ -117,7 +118,7 @@ void *semanticEnv; void *OSEventStruc; //for future, when add I/O to BLIS - void *coreLoopShutDownPt; //addr to jump to to shut down a coreLoop + void *coreLoopEndPt; //addr to jump to to shut down a coreLoop int setupComplete; } @@ -203,7 +204,10 @@ VMS__dissipate_procr( VirtProcr *prToDissipate ); void -VMS__shutdown(); +VMS__handle_dissipate_reqst( VirtProcr *procrToDissipate ); + +void +VMS__cleanup_after_shutdown(); //============================= Statistics ==================================