# HG changeset patch # User Sean Halle # Date 1358329826 28800 # Node ID 292393c6bef1eaa3b1cc48cb7a9e33064c0caa29 # Parent e6a68e7ea63fc1602fca10d6eb79f62d889246e7 about to recover probes, so need to commit current state diff -r e6a68e7ea63f -r 292393c6bef1 AnimationMaster.c --- a/AnimationMaster.c Mon Jan 14 16:10:37 2013 -0800 +++ b/AnimationMaster.c Wed Jan 16 01:50:26 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2010 OpenSourceResearchInstitute + * Copyright 2012 OpenSourceResearchInstitute.org * * Licensed under BSD */ @@ -26,9 +26,8 @@ //inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot ); -inline void masterFunction( AnimSlot *slot ); inline PRProcess * pickAProcess( AnimSlot *slot ); -inline SlaveVP * assignWork( PRProcess *process, AnimSlot *slot ); +inline bool32 assignWork( PRProcess *process, AnimSlot *slot ); /*The animationMaster embodies most of the animator of the language. The * animator is what emodies the behavior of language constructs. @@ -94,7 +93,7 @@ inline -void +bool32 masterFunction( AnimSlot *slot ) { //Scan the animation slots int32 magicNumber; @@ -102,6 +101,7 @@ PRLangEnv *langEnv; PRReqst *req; PRProcess *process; + bool32 foundWork; //Check if newly-done slave in slot, which will need request handled if( slot->workIsDone ) @@ -160,10 +160,13 @@ //Scan lang environs, looking for langEnv with ready work. // call the Assigner for that lang Env, to get a slave for the slot + foundWork = assignWork( process, slot ); HOLISTIC__Record_Assigner_end; }//if slot needs slave assigned + + return foundWork; } /*When several processes exist, use some pattern for picking one to give @@ -218,7 +221,7 @@ * but am making it possible. */ inline -SlaveVP * +bool32 assignWork( PRProcess *process, AnimSlot *slot ) { SlaveVP *returnSlv; int32 coreNum, slotNum; @@ -242,7 +245,7 @@ for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array { langEnv = langEnvsList[envIdx]; if( langEnv->hasWork ) - { (*langEnv->slaveAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot + { (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot goto ReturnAfterAssigningWork; //quit for-loop, cause found work //NOTE: bad search alg -- should start where left off, then wrap around } diff -r e6a68e7ea63f -r 292393c6bef1 CoreController.c --- a/CoreController.c Mon Jan 14 16:10:37 2013 -0800 +++ b/CoreController.c Wed Jan 16 01:50:26 2013 -0800 @@ -72,16 +72,14 @@ int32 thisCoresIdx; int32 numRepetitionsWithNoWork; bool32 foundWork; - SlaveVP *currVP; AnimSlot *animSlot; - int32 currSlotIdx; volatile int32 *addrOfMasterLock; //thing pointed to is volatile, not ptr SlaveVP *thisCoresMasterVP; //Variables used for pthread related things ThdParams *thisCoresThdParams; cpu_set_t coreMask; //used during pinning pthread to CPU core int32 errorCode; - //Variables used during measurements + //Variables used during measurements (inside macro!) TSCountLowHigh endSusp; //Variables used in random-backoff, for master-lock and waiting for work uint32_t seed1 = rand()%1000; // init random number generator for backoffs @@ -95,7 +93,8 @@ //Assembly that saves addr of label of return instr -- label in assmbly recordCoreCtlrReturnLabelAddr((void**)&(_PRTopEnv->coreCtlrReturnPt)); - animSlot = _PRTopEnv->allAnimSlots[ thisCoresIdx ]; + //TODO: DEBUG: check get correct pointer here + animSlot = _PRTopEnv->allAnimSlots[ thisCoresIdx ][0]; numRepetitionsWithNoWork = 0; addrOfMasterLock = &(_PRTopEnv->masterLock); thisCoresMasterVP = _PRTopEnv->masterVPs[ thisCoresIdx ]; @@ -123,7 +122,7 @@ DEBUG__printf1(TRUE, "started coreCtrlr", thisCoresIdx ); //====================== The Core Controller ====================== - while(1) //An endless loop is just one way of doing the control structure + while(1) { //Assembly code switches the core between animating a VP and // animating this core controller. The switch is done by // changing the stack-pointer and frame-pointer and then doing @@ -150,9 +149,9 @@ MEAS__Capture_Pre_Master_Lock_Point; int numTriesToGetLock = 0; int gotLock = 0; - while( currVP == NULL ) //keep going until get master lock + while( gotLock == FALSE ) //keep going until get master lock { - //At this point, first thing to do is get lock. But, want to + //want to // reduce lock contention from cores with no work, so first // check if this is a core with no work, and busy wait if so. //Then, if it's been way too long without work, yield pthread @@ -162,15 +161,15 @@ { numRepetitionsWithNoWork = 0; pthread_yield(); } - //Now, try to get the lock + //Try to get the lock gotLock = __sync_bool_compare_and_swap( addrOfMasterLock, UNLOCKED, LOCKED ); if( gotLock ) { //At this point, have successfully gotten master lock. //So, break out of get-lock loop. - break; //end while -- have a VP to animate now + break; } - //Get here only when failed to get lock + //Get here only when failed to get lock -- check in should do backoff numTriesToGetLock++; //if too many, means too much contention if( numTriesToGetLock > NUM_TRIES_BEFORE_DO_BACKOFF ) @@ -183,20 +182,24 @@ //have master lock, perform master function, which manages request // handling and assigning work to this core's slot foundWork = + masterFunction( animSlot ); + + PR_int__release_master_lock(); + if( foundWork ) numRepetitionsWithNoWork = 0; else numRepetitionsWithNoWork += 1; + //now that master is done, have work in the slot, so switch to it HOLISTIC__Record_Work_start; - switchToSlv(currVP); //Slave suspend makes core "return" from this call + switchToSlv(animSlot->slaveAssignedToSlot); //Slave suspend makes core "return" from this call flushRegisters(); //prevent GCC optimization from doing bad things MEAS__Capture_End_Susp_in_CoreCtlr_ForSys; HOLISTIC__Record_Work_end; - }//while(1) } diff -r e6a68e7ea63f -r 292393c6bef1 PR.h --- a/PR.h Mon Jan 14 16:10:37 2013 -0800 +++ b/PR.h Wed Jan 16 01:50:26 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2009 OpenSourceResearchInstitute.org + * Copyright 2012 OpenSourceResearchInstitute.org * Licensed under GNU General Public License version 2 * * Author: seanhalle@yahoo.com @@ -72,6 +72,8 @@ * wrapper-library calls! */ +inline bool32 masterFunction( AnimSlot *slot ); + //============== include internally used fn prototypes ================ //include fn prototypes used internally in the proto-runtime implementation diff -r e6a68e7ea63f -r 292393c6bef1 PR__PI.h --- a/PR__PI.h Mon Jan 14 16:10:37 2013 -0800 +++ b/PR__PI.h Wed Jan 16 01:50:26 2013 -0800 @@ -49,6 +49,14 @@ //PR_PI__take_lang_reqst_from( PRReqst *req ); #define PR_PI__take_lang_reqst_from( req ) req->langReqData +//=============== Startup and Shutdown ================ +void +PR_SS__shutdown_OS_threads(); + +void +PR_SS__print_out_measurements(); + + //================================================ #endif /* _PR__PI_H */ diff -r e6a68e7ea63f -r 292393c6bef1 PR__SS.c --- a/PR__SS.c Mon Jan 14 16:10:37 2013 -0800 +++ b/PR__SS.c Wed Jan 16 01:50:26 2013 -0800 @@ -104,6 +104,7 @@ *-] Counter of num live slaves and num live tasks in the process * */ +/* PRProcess * PR__create_process__SL( TopLevelFnPtr seed_Fn, void *seedData ) { SlaveVP *seedSlv; @@ -170,12 +171,13 @@ return process; } + */ /*This is only called in multi-lang mode. *It creates a seed slave, from the top-level fn and initial data passed into * this fn. *The only langlet in the created process is the default PRServ. The rest - * must b e started up via calls made by the seed VP's top-level fn (passed in + * must be started up via calls made by the seed VP's top-level fn (passed in * to this call). * *A process is represented by a structure that holds all the process-specific @@ -193,14 +195,14 @@ _PRTopEnv->mode = MultiLang; - - process = malloc( sizeof(PRProcess) ); + //This runs outside of the master lock, so use PR_WL form of malloc + process = PR_WL__malloc( sizeof(PRProcess) ); _PRTopEnv->processes[_PRTopEnv->numProcesses] = process; _PRTopEnv->numProcesses += 1; - langEnvs = malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRCollElem *) ); + langEnvs = PR_WL__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRCollElem *) ); ((int32 *)langEnvs)[0] = NUM_IN_COLLECTION; - langEnvsList = malloc( NUM_IN_COLLECTION * sizeof(PRCollElem *) ); + langEnvsList = PR_WL__malloc( NUM_IN_COLLECTION * sizeof(PRCollElem *) ); process->langEnvs = langEnvs; process->langEnvsList = langEnvsList; process->numLangEnvs = 0; @@ -214,7 +216,8 @@ PRServLangEnv * servicesLangEnv = - PR_int__create_lang_env_in_process( sizeof(PRServLangEnv), process, PRServ_MAGIC_NUMBER ); + PR_int__create_lang_env_in_process( sizeof(PRServLangEnv), process, + PRServ_MAGIC_NUMBER ); servicesLangEnv->slavesReadyToResumeQ = makePrivQ(); servicesLangEnv->taskReadyQ = makePrivQ(); @@ -245,8 +248,8 @@ pthread_cond_broadcast( &suspendCond ); #endif } - pthread_mutex_init( process->doneLock, NULL ); - pthread_cond_init( process->doneCond, NULL ); + pthread_mutex_init( &(process->doneLock), NULL ); + pthread_cond_init( &(process->doneCond), NULL ); process->executionIsComplete = FALSE; return process; @@ -262,14 +265,16 @@ //remove process from PR's list of processes.. processes = _PRTopEnv->processes; + //find the process within the list for( i = 0; i < _PRTopEnv->numProcesses; i++ ) { if( processes[i] == process ) { processIdx = i; break; } } + //move all the higher processes down, overwriting the target for( i = processIdx +1; i < _PRTopEnv->numProcesses; i++ ) - { processes[i-1] = process[i]; + { processes[i-1] = processes[i]; } _PRTopEnv->numProcesses -= 1; @@ -279,12 +284,12 @@ //call shutdown on each langlet started in process (which frees any // langlet-allocd data in langEnv); //Then free the lang env - PRLangEnv *langEnv; + PRLangEnv *protoLangEnv; for( i = 0; i < process->numLangEnvs; i++ ) - { langEnv = PR_int__give_proto_lang_env(process->langEnvsList[i]); + { protoLangEnv = PR_int__give_proto_lang_env(process->langEnvsList[i]); //The lang shutdowns should free any slaves or tasks in the langEnv - (*langEnv->shutdownHdlr)(&(langEnv[1])); - PR_int__free( langEnv ); + (*protoLangEnv->shutdownHdlr)(&(protoLangEnv[1])); + PR_int__free( protoLangEnv ); } PR_int__free( process->langEnvsList ); //list array PR_int__free( &(((int32 *)process->langEnvs)[-1]) ); //the collection array @@ -308,20 +313,20 @@ } //cause resume of "PR__wait_for_process_to_end()" call - pthread_mutex_lock( process->doneLock ); + pthread_mutex_lock( &(process->doneLock) ); process->executionIsComplete = TRUE; - pthread_mutex_unlock( process->doneLock ); - pthread_cond_broadcast( process->doneCond ); + pthread_mutex_unlock( &(process->doneLock) ); + pthread_cond_broadcast( &(process->doneCond) ); //BUG: process struct can be freed and re-allocated before waiter sees // executionIsComplete //if last process, cause resume of "PR__wait_for_all_activity_to_end" if( _PRTopEnv->numProcesses == 1 ) { implement_me(); //have to ensure that PRServ has no activity -- do later - pthread_mutex_lock( _PRTopEnv->activityDoneLock ); + pthread_mutex_lock( &(_PRTopEnv->activityDoneLock) ); _PRTopEnv->allActivityIsDone = TRUE; - pthread_mutex_unlock( _PRTopEnv->activityDoneLock ); - pthread_cond_broadcast( _PRTopEnv->activityDoneCond ); + pthread_mutex_unlock( &(_PRTopEnv->activityDoneLock) ); + pthread_cond_broadcast( &(_PRTopEnv->activityDoneCond) ); } //lastly, free the PRProcess struct itself @@ -345,25 +350,25 @@ void PR__wait_for_all_activity_to_end() { - pthread_mutex_lock( _PRTopEnv->activityDoneLock ); + pthread_mutex_lock( &(_PRTopEnv->activityDoneLock) ); while( !(_PRTopEnv->allActivityIsDone) ) { - pthread_cond_wait( _PRTopEnv->activityDoneCond, - _PRTopEnv->activityDoneLock ); + pthread_cond_wait( &(_PRTopEnv->activityDoneCond), + &(_PRTopEnv->activityDoneLock) ); } - pthread_mutex_unlock( _PRTopEnv->activityDoneLock ); + pthread_mutex_unlock( &(_PRTopEnv->activityDoneLock) ); } void PR__wait_for_process_to_end() { - pthread_mutex_lock( _PRTopEnv->activityDoneLock ); + pthread_mutex_lock( &(_PRTopEnv->activityDoneLock) ); while( !(_PRTopEnv->allActivityIsDone) ) { - pthread_cond_wait( _PRTopEnv->activityDoneCond, - _PRTopEnv->activityDoneLock ); + pthread_cond_wait( &(_PRTopEnv->activityDoneCond), + &(_PRTopEnv->activityDoneLock) ); } - pthread_mutex_unlock( _PRTopEnv->activityDoneLock ); + pthread_mutex_unlock( &(_PRTopEnv->activityDoneLock) ); } /*When all work in the process has completed, then return from this call. @@ -382,14 +387,14 @@ PR__give_results_from_process_when_ready( PRProcess *process ) { void *result; - pthread_mutex_lock( process->doneLock ); + pthread_mutex_lock( &(process->doneLock) ); while( !(process->executionIsComplete) ) { - pthread_cond_wait( process->doneCond, - process->doneLock ); + pthread_cond_wait( &(process->doneCond), + &(process->doneLock) ); } result = process->resultToReturn; - pthread_mutex_unlock( process->doneLock ); + pthread_mutex_unlock( &(process->doneLock) ); return result; } @@ -407,6 +412,7 @@ * found by using magic num to look it up in the process that the seedVP * is inside of. */ +/* void PR_SS__register_create_task_handler( RequestHandler createTaskHandler, SlaveVP *seedVP, int32 magicNum ) { PRLangEnv *langEnv; @@ -442,15 +448,17 @@ langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); langEnv->requestHdlr = reqHandler; } + */ void PR_SS__register_assigner( SlaveAssigner assigner, SlaveVP *seedVP, int32 magicNum ) { PRLangEnv *langEnv; langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); - langEnv->slaveAssigner = assigner; + langEnv->workAssigner = assigner; } void -PR_SS__register_shutdown_handler( RequestHandler shutdownHdlr, SlaveVP *seedVP, int32 magicNum ) +PR_SS__register_shutdown_handler( LangShutdownHdlr shutdownHdlr, SlaveVP *seedVP, + int32 magicNum ) { PRLangEnv *langEnv; langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); @@ -474,6 +482,14 @@ langEnv->langDataInitializer = langDataInitializer; } */ +void +PR_SS__register_lang_data_freer( LangDataFreer langDataFreer, + SlaveVP *seedVP, int32 magicNum ) + { PRLangEnv *langEnv; + + langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); + langEnv->langDataFreer = langDataFreer; + } @@ -485,7 +501,7 @@ */ char * PRServ___give_environment_string() - { char buffer[10000]; + { char *buffer = PR_WL__malloc(10000); int32 j; j = sizeof(int32); //put total num chars here when done @@ -652,8 +668,8 @@ _PRTopEnv->firstProcessReady = FALSE; //use while starting up coreCtlr //initialize flags for waiting for activity within PR to complete - pthread_mutex_init( _PRTopEnv->activityDoneLock, NULL ); - pthread_cond_init( _PRTopEnv->activityDoneCond, NULL ); + pthread_mutex_init( &(_PRTopEnv->activityDoneLock), NULL ); + pthread_cond_init( &(_PRTopEnv->activityDoneCond), NULL ); _PRTopEnv->allActivityIsDone = FALSE; //============================= MEASUREMENT STUFF ======================== diff -r e6a68e7ea63f -r 292393c6bef1 PR__WL.c --- a/PR__WL.c Mon Jan 14 16:10:37 2013 -0800 +++ b/PR__WL.c Wed Jan 16 01:50:26 2013 -0800 @@ -62,12 +62,12 @@ * to the plugin. */ void -PR_WL__send_create_slaveVP_req( void *langReq, CreateHandler handler, - int32 *slvID, SlaveVP *reqstingSlv, int32 magicNum ) +PR_WL__send_create_slaveVP_req( void *langReq, int32 *ID, CreateHandler handler, + SlaveVP *reqstingSlv, int32 magicNum ) { PRReqst req; req.reqType = SlvCreate; - req.ID = slvID; + req.ID = ID; req.langMagicNumber = magicNum; req.langReq = langReq; req.createHdlr = handler; diff -r e6a68e7ea63f -r 292393c6bef1 PR__WL.h --- a/PR__WL.h Mon Jan 14 16:10:37 2013 -0800 +++ b/PR__WL.h Wed Jan 16 01:50:26 2013 -0800 @@ -69,14 +69,16 @@ SlaveVP *callingSlv ); inline void -PR_WL__send_lang_request( void *langReq, SlaveVP *callingSlv, int32 magicNum ); +PR_WL__send_lang_request( void *langReq, RequestHandler handler, + SlaveVP *callingSlv, int32 magicNum ); void -PR_WL__send_create_slaveVP_req( void *langReq, CreateHandler handler, - int32 *slvID, SlaveVP *reqstingSlv, int32 magicNum ); +PR_WL__send_create_slaveVP_req( void *langReq, int32 *ID, CreateHandler handler, + SlaveVP *reqstingSlv, int32 magicNum ); void inline -PR_WL__send_end_slave_req( SlaveVP *prToDissipate, int32 magicNum ); +PR_WL__send_end_slave_req( void *langReq, RequestHandler handler, + SlaveVP *slvToDissipate, int32 magicNum ); inline void PR_WL__send_service_request( void *langReqData, SlaveVP *callingSlv ); diff -r e6a68e7ea63f -r 292393c6bef1 PR__int.h --- a/PR__int.h Mon Jan 14 16:10:37 2013 -0800 +++ b/PR__int.h Wed Jan 16 01:50:26 2013 -0800 @@ -112,7 +112,7 @@ inline void * -PR_int__create_lang_env_in_process( int32 size, PRProcess process, int32 magicNum ); +PR_int__create_lang_env_in_process( int32 size, PRProcess *process, int32 magicNum ); inline void * diff -r e6a68e7ea63f -r 292393c6bef1 PR__structs.h --- a/PR__structs.h Mon Jan 14 16:10:37 2013 -0800 +++ b/PR__structs.h Wed Jan 16 01:50:26 2013 -0800 @@ -33,6 +33,8 @@ typedef SlaveVP *(*SlaveAssigner) ( void *, AnimSlot* ); //langEnv, slot for HW info typedef void (*RequestHandler) ( void *, SlaveVP *, void * ); //req, slv, langEnv typedef void *(*CreateHandler) ( void *, SlaveVP *, void * ); //req, slv, langEnv +typedef void (*LangShutdownHdlr)( void * ); //langEnv +typedef void (*LangDataFreer) ( void * ); //lang data to free typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); @@ -65,9 +67,9 @@ int32 numEnvsWithWork; void *resultToReturn; - PRLangEnv *langEnvs[NUM_IN_COLLECTION]; //used as a hash table - PRLangEnv *langEnvsList[NUM_IN_COLLECTION]; //for fast linear scan of envs - int32 numLangEnvs; //for fast linear scan of envs + PRLangEnv **langEnvs; //used as a hash table + PRLangEnv **langEnvsList; //for fast linear scan of envs + int32 numLangEnvs; //for fast linear scan of envs SlaveVP *seedSlv; @@ -320,18 +322,20 @@ PRLangEnv *chainedLangEnv; //chains to langEnvs with same hash //============================================================= - SlaveAssigner slaveAssigner; - RequestHandler requestHdlr; - RequestHandler shutdownHdlr; //called when lang ended or process shutdown + SlaveAssigner workAssigner; +// RequestHandler requestHdlr; + LangShutdownHdlr shutdownHdlr; //called when lang ended or process shutdown /* CreateTaskHdlr createTaskHdlr; RequestHandler endTaskHdlr; CreateSlvHdlr createSlaveHdlr; RequestHandler dissipateSlaveHdlr; - */ - RequestHandler langDataCreator; - RequestHandler langDataInitializer; + + RequestHandler langDataCreator; + RequestHandler langDataInitializer; + */ + LangDataFreer langDataFreer; //when multi-lang, master polls lang env's to find one with work in it.. // in single-lang case, flag ignored, master always asks lang for work