# HG changeset patch # User Sean Halle # Date 1360124607 28800 # Node ID bc5030385120bb7a7ddb517edea4ed3ce4166824 # Parent 292393c6bef1eaa3b1cc48cb7a9e33064c0caa29 Progress -- back to compile process, fixing compile issues diff -r 292393c6bef1 -r bc5030385120 AnimationMaster.c --- a/AnimationMaster.c Wed Jan 16 01:50:26 2013 -0800 +++ b/AnimationMaster.c Tue Feb 05 20:23:27 2013 -0800 @@ -19,79 +19,37 @@ void PRHandle_Dissipate_SL(SlaveVP *slave); void PR_int__handle_PRServiceReq_SL(SlaveVP *slave); */ -inline void PRHandle_CreateTask( PRReqst *req, SlaveVP *slave ); -inline void PRHandle_EndTask( PRReqst *req, SlaveVP *slave ); -inline void PRHandle_CreateSlave(PRReqst *req, SlaveVP *slave ); -void PRHandle_EndSlave( PRReqst *req, SlaveVP *slave ); +inline void PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ); +inline void PRHandle__EndTask( PRReqst *req, SlaveVP *slave ); +inline void PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave ); +void PRHandle__EndSlave( PRReqst *req, SlaveVP *slave ); //inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot ); inline PRProcess * pickAProcess( 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. - * As such, it is the animationMaster, in combination with the plugin - * functions, that make the language constructs do their behavior. - * - *Within the code, this is the top-level-function of the masterVPs, and - * runs when the coreController has no more slave VPs. It's job is to - * refill the animation slots with slaves that have work. - * - *There are multiple versions of the master, each tuned to a specific - * combination of modes. This keeps the master simple, with reduced overhead, - * when the application is not using the extra complexity. - * - *As of Sept 2012, the versions available will be: - * 1) Single langauge, which only exposes slaves (such as SSR or Vthread) - * 2) Single language, which only exposes tasks (such as pure dataflow) - * 3) Single language, which exposes both (like Cilk, StarSs, and OpenMP) - * 4) Multi-language, which always assumes both tasks and slaves - * 5) Multi-language and multi-process, which also assumes both tasks and slaves - * - * - * + +/*Note: there used to be a coreController that was another animation + * layer below both the masterVP and the slaveVPs.. in that case, the + * masterVP was a virtual processor whose processor-state was the same + * as a slaveVP's processor sate, both implemented as a SlaveVP struct. + * Have removed that, and + * changed the masterVP implementation. Instead of being a special version + * of a proto-runtime virtual processor, using the slaveVP stuct, the + * Master "virtual processor" is now implemented as a pthread pinned to + * a physical core. */ -//This version of the master selects one of three loops, depending upon -// whether stand-alone single language (just slaves), or standalone with -// tasks, or multi-lang (implies multi-process) -void animationMaster( void *_environment, SlaveVP *masterVP ) - { - TopEnv *masterEnv = (TopEnv *)_environment; - int32 slotIdx; - AnimSlot *currSlot; - //Used while scanning and filling animation slots - AnimSlot **animSlots; - - //Local copies, for performance - int32 thisCoresIdx; - - //======================== Initializations ======================== - thisCoresIdx = masterVP->coreAnimatedBy; - animSlots = masterEnv->allAnimSlots[thisCoresIdx]; - - HOLISTIC__Insert_Master_Global_Vars; - - //======================== animationMaster ======================== - //Have three different modes, and the master behavior is different for - // each, so jump to the loop that corresponds to the mode. - // - while(1) - { MEAS__Capture_Pre_Master_Point - for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++) - { - currSlot = animSlots[ slotIdx ]; - - masterFunction( currSlot ); - } - MEAS__Capture_Post_Master_Point; - masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master - flushRegisters(); - } - } - - +/*This is the behavior of the Master. The physical processor switches + * between animating the master, and animating a slave. When a slave + * suspends, the PR "suspend" primitive switches the physical core over + * to animating the masterVP, which is implemented as a pinned pthread. + * This function is the behavior of that masterVP. + *This function's job is to manage processing + * requests and to trigger assignment of new work to the physical core, + * and to manage sharing the core among processes. + */ inline bool32 masterFunction( AnimSlot *slot ) @@ -104,6 +62,8 @@ bool32 foundWork; //Check if newly-done slave in slot, which will need request handled + //NOTE: left over from when had a coreController & MasterVP managed + // several slots if( slot->workIsDone ) { slot->workIsDone = FALSE; slot->needsWorkAssigned = TRUE; @@ -126,16 +86,16 @@ { case TaskEnd: { //do PR handler, which calls lang's hdlr and does recycle of // free task slave if needed -- PR handler checks for free task Slv - PRHandle_EndTask( req, slave ); break; + PRHandle__EndTask( req, slave ); break; } case TaskCreate: { //Do PR's create-task handler, which calls the lang's hdlr // PR handler checks for free task Slv - PRHandle_CreateTask( req, slave ); break; + PRHandle__CreateTask( req, slave ); break; } - case SlvCreate: PRHandle_CreateSlave( req, slave ); break; - case SlvDissipate: PRHandle_EndSlave( req, slave ); break; - case Service: PR_int__handle_PRServiceReq( slave ); break; //resumes into Service lang env + case SlvCreate: PRHandle__CreateSlave( req, slave ); break; + case SlvDissipate: PRHandle__EndSlave( req, slave ); break; + case Service: PRHandle__ServiceReq( slave ); break; //resumes into Service lang env case Hardware: //for future expansion case IO: //for future expansion case OSCall: //for future expansion @@ -151,10 +111,12 @@ HOLISTIC__Record_AppResponder_end; } //if have request to be handled - if( slot->needsWorkAssigned ) + //NOTE: IF statement is leftover from when master managed many slots + foundWork = FALSE; + if( slot->needsWorkAssigned ) //can probably remove IF, not that only one slot { HOLISTIC__Record_Assigner_start; - + //Pick a process to get this slot process = pickAProcess( slot ); @@ -164,6 +126,8 @@ assignWork( process, slot ); HOLISTIC__Record_Assigner_end; + +// fixme; //make this a while loop that tries a different process if this one fails }//if slot needs slave assigned return foundWork; @@ -223,9 +187,7 @@ inline bool32 assignWork( PRProcess *process, AnimSlot *slot ) - { SlaveVP *returnSlv; - int32 coreNum, slotNum; - PRMetaTask *assignedMetaTask; + { int32 coreNum; coreNum = slot->coreSlotIsOn; @@ -244,9 +206,21 @@ numEnvs = process->numLangEnvs; for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array { langEnv = langEnvsList[envIdx]; - if( langEnv->hasWork ) - { (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot - goto ReturnAfterAssigningWork; //quit for-loop, cause found work + if( langEnv->numReadyWork > 0 ) + { bool32 + didAssignWork = + (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot + + if(didAssignWork) + { langEnv->numReadyWork -= 1; + if( langEnv->numReadyWork == 0 ) + { process->numEnvsWithWork -= 1; + } + goto ReturnAfterAssigningWork; //quit for-loop, 'cause found work + } + else + goto NoWork; //quit for-loop, cause found work + //NOTE: bad search alg -- should start where left off, then wrap around } } @@ -255,7 +229,7 @@ NoWork: //No work, if end up here.. { #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC - returnSlv = process->idleSlv[coreNum][slotNum]; + returnSlv = process->idleSlv[coreNum][0]; //only one slot now, so [0] //things that would normally happen in resume(), but idle VPs // never go there @@ -313,24 +287,25 @@ */ inline void -PRHandle_CreateSlave( PRReqst *req, SlaveVP *slave ) +PRHandle__CreateSlave( PRReqst *req, SlaveVP *slave ) { SlaveVP *newSlv; PRProcess *process; PRLangEnv *protoLangEnv; process = slave->processSlaveIsIn; protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber ); - -// newSlv = PR_int__create_slave( req->topLevelFn, req->initData ); - - //create slv has diff prototype than standard reqst hdlr + + //create handler, or a future request handler will call PR_PI__make_slave_ready + // which will in turn handle updating which langlets and which processes have + // work available. + //NOTE: create slv has diff prototype than standard reqst hdlr newSlv = (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv)); newSlv->typeOfVP = GenericSlv; newSlv->processSlaveIsIn = process; newSlv->ID = req->ID; - process->numLiveGenericSlvs += 1; + process->numLiveGenericSlvs += 1; //not same as work ready! } /*The dissipate handler has to, update the number of slaves of the type, within @@ -345,7 +320,7 @@ */ inline void -PRHandle_EndSlave( PRReqst *req, SlaveVP *slave ) +PRHandle__EndSlave( PRReqst *req, SlaveVP *slave ) { PRProcess *process; PRLangEnv *protoLangEnv; @@ -357,13 +332,14 @@ if(req->handler != NULL) (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) ); - process->numLiveGenericSlvs -= 1; - PR_int__recycle_slave__ML( slave ); - + process->numLiveGenericSlvs -= 1; + PR_int__recycle_slave( slave ); + //NOTE: dissipate is unrelated to work available (just in case wondering) + //check End Of Process Condition if( process->numLiveTasks == 0 && process->numLiveGenericSlvs == 0 ) - PR_SS__shutdown_process__ML( process ); + PR_SS__shutdown_process( process ); } /*Create task is a special form, that has PR behavior in addition to plugin @@ -374,7 +350,7 @@ */ inline void -PRHandle_CreateTask( PRReqst *req, SlaveVP *slave ) +PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ) { PRMetaTask *metaTask; PRProcess *process; PRLangEnv *protoLangEnv; @@ -400,8 +376,8 @@ return; } -/*When a task ends, are two scenarios: 1) task ran to completion, or 2) task - * suspended at some point in its code. +/*When a task ends, have two scenarios: 1) task ran to completion, or 2) task + * has been suspended at some point in its code. *For 1, just decr count of live tasks (and check for end condition) -- the * master loop will decide what goes into the slot freed up by this task end, * so, here, don't worry about assigning a new task to the slot slave. @@ -425,13 +401,13 @@ */ inline void -PRHandle_EndTask( PRReqst *req, SlaveVP *requestingSlv ) +PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv ) { void *langEnv; PRProcess *process; void *langMetaTask; - langEnv = PR_int__give_lang_env_of_req__ML( req, requestingSlv ); //magic num in req - langMetaTask = PR_int__give_lang_meta_task_from_slave__ML( requestingSlv, req->langMagicNumber); + langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req + langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber); //Do the langlet's request handler //Want to keep PR structs hidden from plugin, so extract langReq.. @@ -439,15 +415,47 @@ //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv if( requestingSlv->typeOfVP == FreeTaskSlv ) - PR_int__recycle_slave__ML( requestingSlv ); + PR_int__recycle_slave( requestingSlv ); //Doesn't decr num live slaves process->numLiveTasks -= 1; + //NOTE: end-task is unrelated to work available (just in case wondering) //check End Of Process Condition if( process->numLiveTasks == 0 && process->numLiveGenericSlvs == 0 ) { //Tell the core controller to do wakeup of any waiting OS thread - PR_SS__shutdown_process__ML( process ); + PR_SS__shutdown_process( process ); } } + +/*This is for OS requests and PR infrastructure requests, which are not + * part of the PRServ language -- this is for things that have to be in the + * infrastructure of PR itself, such as I/O requests, which have to go through + * pthreads inside the core controller.. + * + *As of Jan 2013, doesn't do much of anything.. + */ +void inline +PRHandle__ServiceReq( SlaveVP *requestingSlv ) + { PRReqst *req; + PRServReq *langReq; + void *langEnv; + int32 magicNumber; + + + req = requestingSlv->request; + + magicNumber = req->langMagicNumber; + langEnv = PR_PI__give_lang_env_for( slave, magicNumber ); + + langReq = PR_PI__take_lang_reqst_from(req); + if( langReq == NULL ) return; + switch( langReq->reqType ) //lang handlers are all in other file + { + case make_probe: handleMakeProbe( langReq, langEnv ); + break; + case throw_excp: handleThrowException( langReq, langEnv ); + break; + } + } diff -r 292393c6bef1 -r bc5030385120 CoreController.c --- a/CoreController.c Wed Jan 16 01:50:26 2013 -0800 +++ b/CoreController.c Tue Feb 05 20:23:27 2013 -0800 @@ -90,7 +90,7 @@ thisCoresThdParams = (ThdParams *)paramsIn; thisCoresIdx = thisCoresThdParams->coreNum; - //Assembly that saves addr of label of return instr -- label in assmbly + //Assembly that saves addr of label of return instr -- addr used in assmbly recordCoreCtlrReturnLabelAddr((void**)&(_PRTopEnv->coreCtlrReturnPt)); //TODO: DEBUG: check get correct pointer here diff -r 292393c6bef1 -r bc5030385120 PR.h --- a/PR.h Wed Jan 16 01:50:26 2013 -0800 +++ b/PR.h Tue Feb 05 20:23:27 2013 -0800 @@ -91,8 +91,8 @@ //========================= Services ======================= -//#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h" -//#include "Services_Offered_by_PR/Services_Language/PRServ.h" +#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h" +#include "Services_Offered_by_PR/Services_Language/PRServ.h" //#include "Services_Offered_by_PR/Services_Language/libPRServ.h" //================================================ diff -r 292393c6bef1 -r bc5030385120 PR__PI.c --- a/PR__PI.c Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__PI.c Tue Feb 05 20:23:27 2013 -0800 @@ -23,6 +23,54 @@ */ +/*All langlets use this call to make their slaves ready.. this, in turn, + * calls the make_ready that was registered by the langlet. + */ +void +PR_PI__make_slave_ready( SlaveVP *slave, void *_langEnv ) + { PRLangEnv *protoLangEnv; + + if( _PRTopEnv->overrideAssigner != NULL ) + { + //put slave into override readyQ + + //update override hasWork flag ? + } + else + { //call langlet's registered make ready + protoLangEnv = PR_int__give_proto_lang_env( _langEnv ); + (*protoLangEnv->makeSlaveReadyFn)( slave, _langEnv ); + + //incr amount of work ready, in langlet's environ + protoLangEnv->numReadyWork += 1; + if(protoLangEnv->numReadyWork == 1) + { protoLangEnv->processEnvIsIn->numEnvsWithWork += 1; + } + } + } + +void +PR_PI__make_task_ready( void *_task, void *_langEnv ) + { PRLangEnv *protoLangEnv; + + if( _PRTopEnv->overrideAssigner != NULL ) + { + //put task into override readyQ + + //update override hasWork flag ? + } + else + { //call langlet's registered make ready + protoLangEnv = PR_int__give_proto_lang_env( _langEnv ); + (*protoLangEnv->makeTaskReadyFn)( _task, _langEnv ); + + //incr amount of work ready, in langlet's environ + protoLangEnv->numReadyWork += 1; + if(protoLangEnv->numReadyWork == 1) + { protoLangEnv->processEnvIsIn->numEnvsWithWork += 1; + } + } + } PRReqst * diff -r 292393c6bef1 -r bc5030385120 PR__PI.h --- a/PR__PI.h Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__PI.h Tue Feb 05 20:23:27 2013 -0800 @@ -36,9 +36,11 @@ * wrapper-library calls! */ +#define PR_PI__create_slaveVP PR_int__create_slaveVP_helper + inline SlaveVP * -PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask ); +PR_PI__give_slave_lang_meta_task_is_assigned_to( void *langMetaTask ); PRReqst * diff -r 292393c6bef1 -r bc5030385120 PR__SS.c --- a/PR__SS.c Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__SS.c Tue Feb 05 20:23:27 2013 -0800 @@ -126,7 +126,7 @@ process->numLangEnvs = 0; //A Process starts with one slave, the seed slave - seedSlv = PR_int__create_slaveVP__ML( seed_Fn, seedData, process ); + seedSlv = PR_int__create_slaveVP( seed_Fn, seedData, process ); seedSlv->typeOfVP = SeedSlv; seedSlv->processSlaveIsIn = process; process->numLiveGenericSlvs = 1; //count the seed @@ -188,12 +188,12 @@ * */ PRProcess * -PR__create_process__ML( TopLevelFnPtr seed_Fn, void *seedData ) +PR__create_process( TopLevelFnPtr seed_Fn, void *seedData ) { SlaveVP *seedSlv; PRProcess *process; PRLangEnv **langEnvs, **langEnvsList; - _PRTopEnv->mode = MultiLang; + _PRTopEnv->mode = MultiLang; //leftover, not used, but reminder //This runs outside of the master lock, so use PR_WL form of malloc process = PR_WL__malloc( sizeof(PRProcess) ); @@ -208,7 +208,7 @@ process->numLangEnvs = 0; //A Process starts with one slave, the seed slave - seedSlv = PR_int__create_slaveVP__ML( seed_Fn, seedData, process ); + seedSlv = PR_int__create_slaveVP( seed_Fn, seedData, process ); seedSlv->typeOfVP = SeedSlv; seedSlv->processSlaveIsIn = process; process->numLiveGenericSlvs = 1; //count the seed @@ -249,7 +249,7 @@ #endif } pthread_mutex_init( &(process->doneLock), NULL ); - pthread_cond_init( &(process->doneCond), NULL ); + pthread_cond_init( &(process->doneCond), NULL ); process->executionIsComplete = FALSE; return process; @@ -259,7 +259,7 @@ /*are already in Master when detect, inside end-task or dissipate, so call "PR_SS__shutdown_process" */ void -PR_SS__shutdown_process__ML( PRProcess *process ) +PR_SS__shutdown_process( PRProcess *process ) { int32 i, processIdx; PRProcess **processes; @@ -317,20 +317,19 @@ process->executionIsComplete = TRUE; pthread_mutex_unlock( &(process->doneLock) ); pthread_cond_broadcast( &(process->doneCond) ); - //BUG: process struct can be freed and re-allocated before waiter sees - // executionIsComplete + //now wait for woken waiter to Ack, then free the process struct + pthread_mutex_lock( &(process->doneAckLock) ); //BUG:? may be a race + pthread_mutex_unlock( &(process->doneAckLock) ); + PR_int__free(process); - //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 + //if no more processes, cause resume of "PR__wait_for_all_activity_to_end" + if( _PRTopEnv->numProcesses == 0) + { pthread_mutex_lock( &(_PRTopEnv->activityDoneLock) ); _PRTopEnv->allActivityIsDone = TRUE; pthread_mutex_unlock( &(_PRTopEnv->activityDoneLock) ); pthread_cond_broadcast( &(_PRTopEnv->activityDoneCond) ); } - - //lastly, free the PRProcess struct itself - PR_int__free(process); } /*This waits for the OS threads in the PR system to end. Causing them to end @@ -359,16 +358,25 @@ pthread_mutex_unlock( &(_PRTopEnv->activityDoneLock) ); } + void -PR__wait_for_process_to_end() - { - pthread_mutex_lock( &(_PRTopEnv->activityDoneLock) ); - while( !(_PRTopEnv->allActivityIsDone) ) +PR__wait_for_process_to_end( PRProcess *process ) + { //First get the "ACK" lock, then do normal wait for signal, then release + // ACK lock, to let end-process know it can free the process struct + pthread_mutex_lock( &(process->doneAckLock) ); + pthread_mutex_lock( &(process->doneLock) ); + while( process->executionIsComplete != TRUE ) { - pthread_cond_wait( &(_PRTopEnv->activityDoneCond), - &(_PRTopEnv->activityDoneLock) ); + pthread_cond_wait( &(process->doneCond), + &(process->doneLock) ); } - pthread_mutex_unlock( &(_PRTopEnv->activityDoneLock) ); + pthread_mutex_unlock( &(process->doneLock) ); + //now send "ACK" signal to process_end Fn, that it may proceed + pthread_mutex_unlock( &(process->doneAckLock) ); + + //TODO: BUG? -- can process be created and end, before this acquires the + // first lock? Can see some rare code that creates a bunch, before getting + // to waiting.. leave for now.. pain to fix.. } /*When all work in the process has completed, then return from this call. @@ -386,17 +394,26 @@ void * PR__give_results_from_process_when_ready( PRProcess *process ) { void *result; + //First get the "ACK" lock, then do normal wait for signal, then release + // ACK lock, to let end-process know it can free the process struct + pthread_mutex_lock( &(process->doneAckLock) ); pthread_mutex_lock( &(process->doneLock) ); - while( !(process->executionIsComplete) ) + while( process->executionIsComplete != TRUE ) { pthread_cond_wait( &(process->doneCond), &(process->doneLock) ); } + pthread_mutex_unlock( &(process->doneLock) ); result = process->resultToReturn; - pthread_mutex_unlock( &(process->doneLock) ); + + //now send "ACK" signal to process_end Fn, that it may proceed + pthread_mutex_unlock( &(process->doneAckLock) ); return result; + //TODO: BUG? -- can process be created and end, before this acquires the + // first lock? Can see some rare code that creates a bunch, before getting + // to waiting.. leave for now.. pain to fix.. } @@ -412,6 +429,54 @@ * found by using magic num to look it up in the process that the seedVP * is inside of. */ +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->workAssigner = assigner; + } +void +PR_SS__register_shutdown_handler( LangShutdownHdlr shutdownHdlr, SlaveVP *seedVP, + int32 magicNum ) + { PRLangEnv *langEnv; + + langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); + langEnv->shutdownHdlr = shutdownHdlr; + } +void +PR_SS__register_lang_data_creator( LangDataCreator langDataCreator, + SlaveVP *seedVP, int32 magicNum ) + { PRLangEnv *langEnv; + + langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); + langEnv->langDataCreator = langDataCreator; + } +void +PR_SS__register_lang_meta_task_creator( LangDataCreator langMetaTaskCreator, + SlaveVP *seedVP, int32 magicNum ) + { PRLangEnv *langEnv; + + langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); + langEnv->langMetaTaskCreator = langMetaTaskCreator; + } +void +PR_SS__register_make_slave_ready_fn( MakeSlaveReadyFn fn, SlaveVP *seedVP, + int32 magicNum ) + { PRLangEnv *langEnv; + + langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); + langEnv->makeSlaveReadyFn = fn; + } +void +PR_SS__register_make_task_ready_fn( MakeTaskReadyFn fn, SlaveVP *seedVP, + int32 magicNum ) + { PRLangEnv *langEnv; + + langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); + langEnv->makeTaskReadyFn = fn; + } + /* void PR_SS__register_create_task_handler( RequestHandler createTaskHandler, SlaveVP *seedVP, int32 magicNum ) @@ -449,31 +514,8 @@ 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->workAssigner = assigner; - } -void -PR_SS__register_shutdown_handler( LangShutdownHdlr shutdownHdlr, SlaveVP *seedVP, - int32 magicNum ) - { PRLangEnv *langEnv; - - langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); - langEnv->shutdownHdlr = shutdownHdlr; - } /* void -PR_SS__register_lang_data_creator( LangDataCreator langDataCreator, - SlaveVP *seedVP, int32 magicNum ) - { PRLangEnv *langEnv; - - langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); - langEnv->langDataCreator = langDataCreator; - } -void PR_SS__register_lang_data_initializer( LangDataInitializer langDataInitializer, SlaveVP *seedVP, int32 magicNum ) { PRLangEnv *langEnv; @@ -481,7 +523,6 @@ langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); langEnv->langDataInitializer = langDataInitializer; } -*/ void PR_SS__register_lang_data_freer( LangDataFreer langDataFreer, SlaveVP *seedVP, int32 magicNum ) @@ -490,6 +531,7 @@ langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum ); langEnv->langDataFreer = langDataFreer; } +*/ @@ -604,7 +646,7 @@ readyToAnimateQs[ coreIdx ] = makePRQ(); //Q: should give masterVP core-specific info as its init data? - masterVPs[ coreIdx ] = PR_int__create_slave( (TopLevelFnPtr)&animationMaster, (void*)_PRTopEnv ); + masterVPs[ coreIdx ] = PR_int__create_slaveVP_helper( (TopLevelFnPtr)&animationMaster, (void*)_PRTopEnv ); masterVPs[ coreIdx ]->coreAnimatedBy = coreIdx; masterVPs[ coreIdx ]->typeOfVP = Master; allAnimSlots[ coreIdx ] = create_anim_slots( coreIdx ); //makes for one core @@ -619,7 +661,7 @@ { //langEnv->coreIsDone[coreNum] = FALSE; //use during shutdown for( slotNum = 0; slotNum < NUM_ANIM_SLOTS; ++slotNum ) - { idleSlv = PR_int__create_slaveVP( &idle_fn, NULL ); + { idleSlv = PR_int__create_slaveVP_helper( &idle_fn, NULL ); idleSlv->coreAnimatedBy = coreNum; idleSlv->animSlotAssignedTo = _PRTopEnv->allAnimSlots[coreNum][slotNum]; @@ -666,7 +708,7 @@ _PRTopEnv->numProcesses = 0; _PRTopEnv->currProcessIdx = 0; _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 ); @@ -825,7 +867,7 @@ { SlaveVP* shutdownVP; - shutdownVP = PR_int__create_slave( &endOSThreadFn, NULL ); + shutdownVP = PR_int__create_slaveVP_helper( &endOSThreadFn, NULL ); shutdownVP->typeOfVP = Shutdown; return shutdownVP; diff -r 292393c6bef1 -r bc5030385120 PR__WL.h --- a/PR__WL.h Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__WL.h Tue Feb 05 20:23:27 2013 -0800 @@ -57,7 +57,10 @@ inline SlaveVP * -PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask ); +PR_PI__give_slave_lang_meta_task_is_assigned_to( void *langMetaTask ); + + +#define PR_WL__create_slaveVP PR_int__create_slaveVP_helper //============== Request Related =============== diff -r 292393c6bef1 -r bc5030385120 PR__int.c --- a/PR__int.c Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__int.c Tue Feb 05 20:23:27 2013 -0800 @@ -25,9 +25,12 @@ //=========================================================================== // //=========================================================================== +/*This does the basic work of creating the SlaveVP structure.. but doesn't + * know which process it goes in, nor what type of VP it is, etc.. + */ inline SlaveVP * -PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam ) +PR_int__create_slaveVP_helper( TopLevelFnPtr fnPtr, void *dataParam ) { SlaveVP *newSlv; void *stackLocs; @@ -43,8 +46,8 @@ newSlv->numTimesAssignedToASlot = 0; - newSlv->langData = NULL; - newSlv->metaTask = NULL; + newSlv->langDatas = NULL; + newSlv->metaTasks = NULL; PR_int__reset_slaveVP_to_TopLvlFn( newSlv, fnPtr, dataParam ); @@ -65,49 +68,49 @@ inline SlaveVP * -PR_int__create_slaveVP__ML( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process ) +PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process ) { SlaveVP *newSlv; - newSlv = PR_int__create_slaveVP( fnPtr, dataParam ); + newSlv = PR_int__create_slaveVP_helper( fnPtr, dataParam ); int32 * langDatas = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRLangData *) ); langDatas[0] = NUM_IN_COLLECTION; //size held in prolog - newSlv->langData = &(langDatas[1]); //skip over the size + newSlv->langDatas = &(langDatas[1]); //skip over the size int32 * metaTasks = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRMetaTask *) ); metaTasks[0] = NUM_IN_COLLECTION; //size held in prolog - newSlv->metaTask = &(metaTasks[1]); + newSlv->metaTasks = &(metaTasks[1]); process->numLiveGenericSlvs += 1; } -/* +/*A slot slave doesn't use array for lang data nor meta tasks, but it's in + * there anyway.. have to copy what create slave does, so can just change + * the type when a slot slave is converted.. */ -/* -inline SlaveVP * -PR_int__create_seed_slave__ML( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process ) - { SlaveVP *newSlv; +PR_int__create_slot_slave( ) + { SlaveVP *retSlv; - newSlv = PR_int__create_slaveVP( fnPtr, dataParam ); - + retSlv = PR_int__create_slaveVP_helper( &idle_fn, NULL ); + retSlv->typeOfVP = SlotTaskSlv; + int32 * langDatas = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRLangData *) ); - langDatas[0] = NUM_IN_COLLECTION; //size held in prolog - newSlv->langData = &(langDatas[1]); //skip over the size + langDatas[0] = NUM_IN_COLLECTION; //size held in prolog + retSlv->langDatas = &(langDatas[1]); //skip over the size int32 * metaTasks = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRMetaTask *) ); metaTasks[0] = NUM_IN_COLLECTION; //size held in prolog - newSlv->metaTask = &(metaTasks[1]); //make slave point to array + retSlv->metaTasks = &(metaTasks[1]); - newSlv->typeOfVP = SeedSlv; - process->numLiveGenericSlvs = 1; + return retSlv; } -*/ + /*Called when a new slot slave is needed.. takes from recycle pool, and @@ -130,26 +133,12 @@ retSlv->request = NULL; } else //if none to recycle, create a new one - { retSlv = PR_int__create_slaveVP_helper( &idle_fn, NULL ); - retSlv->typeOfVP = SlotTaskSlv; + { retSlv = PR_int__create_slot_slave(); } return retSlv; } -/*A slot slave has no array for lang data nor meta tasks -- it only ever has - * one meta task.. - */ -SlaveVP * -PR_int__create_slot_slave( ) - { SlaveVP *retSlv; - - retSlv = PR_int__create_slaveVP_helper( &idle_fn, NULL ); - retSlv->typeOfVP = SlotTaskSlv; - - return retSlv; - } - //========================================================================== /*When a task in a slot slave suspends, the slot slave has to be changed to * a free task slave, then the slot slave replaced. The replacement can be @@ -178,18 +167,7 @@ //Fix up requester, to be an extra slave now (but not an ended one) // because it's active, doesn't go into freeTaskSlvRecycleQ requestingSlv->typeOfVP = FreeTaskSlv; - requestingSlv->processSlaveIsIn = process; - - - int32 * - langDatas = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRLangData *) ); - langDatas[0] = NUM_IN_COLLECTION; //size held in prolog - newSlotSlv->langData = &(langDatas[1]); //skip over the size - - int32 * - metaTasks = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRMetaTask *) ); - metaTasks[0] = NUM_IN_COLLECTION; //size held in prolog - newSlotSlv->metaTask = &(metaTasks[1]); + requestingSlv->processSlaveIsIn = process; } void idle_fn(void* data, SlaveVP *animatingSlv) @@ -201,37 +179,6 @@ -/* This is for OS requests and PR infrastructure requests, such as to create - * a probe -- a probe is inside the heart of PR-core, it's not part of any - * language -- but it's also a semantic thing that's triggered from and used - * in the application.. so it crosses abstractions.. so, need some special - * pattern here for handling such requests. - * Doing this just like it were a second language sharing PR-core. - */ -void inline -PR_int__handle_PRServiceReq( SlaveVP *requestingSlv ) - { PRReqst *req; - PRServReq *langReq; - void *langEnv; - int32 magicNumber; - - - req = requestingSlv->request; - - magicNumber = req->langMagicNumber; - langEnv = PR_PI__give_lang_env_for( slave, magicNumber ); - - langReq = PR_PI__take_lang_reqst_from(req); - if( langReq == NULL ) return; - switch( langReq->reqType ) //lang handlers are all in other file - { - case make_probe: handleMakeProbe( langReq, langEnv ); - break; - case throw_excp: handleThrowException( langReq, langEnv ); - break; - } - } - //=========================================================================== /*there is a label inside this function -- save the addr of this label in * the callingSlv struc, as the pick-up point from which to start the next @@ -271,63 +218,25 @@ -/*This must be called by the request handler plugin -- it cannot be called - * from the semantic library "dissipate processor" function -- instead, the - * semantic layer has to generate a request, and the plug-in calls this - * function. - *The reason is that this frees the virtual processor's stack -- which is - * still in use inside semantic library calls! - * - *This frees or recycles all the state owned by and comprising the PR - * portion of the animating virtual procr. The request handler must first - * free any semantic data created for the processor that didn't use the - * PR_malloc mechanism. Then it calls this, which first asks the malloc - * system to disown any state that did use PR_malloc, and then frees the - * statck and the processor-struct itself. - *If the dissipated processor is the sole (remaining) owner of PR_int__malloc'd - * state, then that state gets freed (or sent to recycling) as a side-effect - * of dis-owning it. - */ -void -PR_int__dissipate_slaveVP__SL( SlaveVP *animatingSlv ) - { - DEBUG__printf2(dbgRqstHdlr, "PR int dissipate slaveNum: %d, alive: %d",animatingSlv->slaveNum, _PRTopEnv->numSlavesAlive-1); - //dis-own all locations owned by this processor, causing to be freed - // any locations that it is (was) sole owner of - _PRTopEnv->numSlavesAlive -= 1; - if( _PRTopEnv->numSlavesAlive == 0 ) - { //no more work, so shutdown - PR_SS__shutdown(); //note, creates shut-down processor on each core - } - - //NOTE: dataParam was given to the processor, so should either have - // been alloc'd with PR_int__malloc, or freed by the level above animSlv. - //So, all that's left to free here is the stack and the SlaveVP struc - // itself - //Note, should not stack-allocate initial data -- no guarantee, in - // general that creating processor will outlive ones it creates. - PR_int__free( animatingSlv->startOfStack ); - PR_int__free( animatingSlv ); - } - - /*In multi-lang mode, there are multiple langData in the slave.. * *At some point want to recycle rather than free.. * *For now, iterate through langData, call registered free-er on each, then * free the basic slave + * + *DOES NOT DECREMENT NUMBER OF LIVE SLAVES IN PROCESS */ void -PR_int__free_slaveVP__ML( SlaveVP *slave ) +PR_int__free_slaveVP( SlaveVP *slave ) { - PR_int__apply_Fn_to_all_in_collection( &recycleLangDataAsElem, - (PRCollElem**) slave->langData ); - PR_int__apply_Fn_to_all_in_collection( &recycleMetaTaskAsElem, - (PRCollElem**) slave->metaTask ); + PR_int__apply_Fn_to_all_in_collection( &freeLangDataAsElem, + (PRCollElem**) slave->langDatas ); + PR_int__apply_Fn_to_all_in_collection( &freeMetaTaskAsElem, + (PRCollElem**) slave->metaTasks ); - PR_int__free( &(((int32*)(slave->langData))[-1]) ); - PR_int__free( &(((int32*)(slave->metaTask))[-1]) ); + PR_int__free( &(((int32*)(slave->langDatas))[-1]) ); + PR_int__free( &(((int32*)(slave->metaTasks))[-1]) ); PR_int__free( slave->startOfStack ); PR_int__free( slave ); } @@ -335,39 +244,49 @@ /*This calls recycle handler registered for each langlet's lang data and meta * task. It also recycles the slave struct. * + *DOES NOT DECREMENT NUMBER OF LIVE SLAVES IN PROCESS + * *This assumes that each slave has an array of */ void -PR_int__recycle_slave__ML( SlaveVP *slave ) +PR_int__recycle_slave( SlaveVP *slave ) { - PR_int__apply_Fn_to_all_in_collection( &recycleLangDataAsElem, - (PRCollElem**) slave->langData ); - PR_int__apply_Fn_to_all_in_collection( &recycleMetaTaskAsElem, - (PRCollElem**) slave->metaTask ); + PR_int__apply_Fn_to_all_in_collection( &freeLangDataAsElem, + (PRCollElem**) slave->langDatas ); + PR_int__apply_Fn_to_all_in_collection( &freeMetaTaskAsElem, + (PRCollElem**) slave->metaTasks ); writePrivQ( slave, _PRTopEnv->slaveRecycleQ ); } +/*Receives a protoLangData, but in the form of a void, so have to cast + */ void -recycleLangDataAsElem( void *elem ) - { PRLangData *langData; +freeLangDataAsElem( void *elem ) + { PRLangData *protoLangData; - langData = (PRLangData *)elem; //recycler receives the prolog, and must call + protoLangData = (PRLangData *)elem; //recycler actually receives the prolog. + + //apply the free fn that's stored in the lang data prolog + //Note: freeing whole slave, so no need to remove from collection + //Note: langlet's freer only frees what langlet has malloc'd + if(protoLangData->freer != NULL) + { (*(protoLangData->freer))( PR_int__give_lang_data_of_prolog(protoLangData) ); + } + PR_int__free( protoLangData ); + } + +/*Receives a protoMetaTask, but in form of a void, so have to cast + */ +void +freeMetaTaskAsElem( void *elem ) + { PRMetaTask *protoMetaTask; + + protoMetaTask = (PRMetaTask *)elem; //recycler receives the prolog, and must call //a PR Fn to convert prolog to lang-specific version. - //apply the recycle fn that's stored in the lang data prolog - (*(langData->recycler))(langData); //lang registered the recycler - } - -void -recycleMetaTaskAsElem( void *elem ) - { PRMetaTask *metaTask; - - metaTask = (PRMetaTask *)elem; //recycler receives the prolog, and must call - //a PR Fn to convert prolog to lang-specific version. - - //apply the recycle fn that's stored in the lang data prolog - (*(metaTask->recycler))(metaTask); //lang registered the recycler + //apply the free fn that's stored in the meta task prolog + (*(protoMetaTask->freer))( PR_int__give_lang_meta_task_of_prolog(protoMetaTask) ); } @@ -427,7 +346,7 @@ inline void * -PR_int__give_lang_env_of_req__ML( PRReqst *req, SlaveVP *requestingSlv ) +PR_int__give_lang_env_of_req( PRReqst *req, SlaveVP *requestingSlv ) { return PR_int__give_lang_env_from_process( requestingSlv->processSlaveIsIn, req->langMagicNumber ); @@ -435,13 +354,13 @@ inline void * -PR_int__give_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNum ) +PR_int__give_lang_env_for_slave( SlaveVP *slave, int32 magicNum ) { return PR_int__give_lang_env_from_process( slave->processSlaveIsIn, magicNum ); } inline PRLangEnv * -PR_int__give_proto_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNum ) +PR_int__give_proto_lang_env_for_slave( SlaveVP *slave, int32 magicNum ) { return PR_int__give_proto_lang_env_for_process( slave->processSlaveIsIn, magicNum ); } @@ -470,6 +389,7 @@ return retLangEnv; //return prolog } +/* inline void PR_int__set_work_in_lang_env( void *_langEnv ) @@ -489,7 +409,8 @@ prototLangEnv->processEnvIsIn->numEnvsWithWork -= 1; } } - + */ + /*This is to be called by langlet's assigner. */ inline @@ -543,7 +464,7 @@ //point slave to task's function PR_int__reset_slaveVP_to_TopLvlFn( slotSlv, task->topLevelFn, task->initData ); - PR_int__insert_meta_task_into_slave__ML( task, slotSlv ); + PR_int__insert_meta_task_into_slave( task, slotSlv ); PR_int__put_slave_into_slot( slotSlv, slot ); } @@ -564,8 +485,8 @@ inline -void * -PR_int__create_lang_meta_task__ML( int32 size, int32 magicNum ) +PRMetaTask * +PR_int__create_proto_meta_task( int32 size, LangMetaTaskFreer freer, int32 magicNum ) { PRMetaTask *retMetaTask; //make the new meta task @@ -573,82 +494,132 @@ retMetaTask->chainedMetaTask = NULL; retMetaTask->langMagicNumber = magicNum; retMetaTask->slaveAssignedTo = NULL; - retMetaTask->taskType = SlotTask; + retMetaTask->taskType = SlotTask; //just common default retMetaTask->ID = NULL; + retMetaTask->freer = freer; + + return retMetaTask; //skip over prolog + } + +/*Might never need this fn -- think the slave dissipator does this work + */ +void +PR_int__free_lang_meta_task( void *langMetaTask) + { PRMetaTask *protoMetaTask; + + protoMetaTask = PR_int__give_prolog_of_task( langMetaTask ); + PR_int__remove_elem_from_collection( protoMetaTask->langMagicNumber, + protoMetaTask->slaveAssignedTo->metaTasks ); + + (*protoMetaTask->freer)(langMetaTask); + PR_int__free( protoMetaTask ); + } + +inline +void * +PR_int__create_lang_meta_task( int32 size, LangMetaTaskFreer freer, int32 magicNum ) + { PRMetaTask *retMetaTask; + + //make the new meta task + + retMetaTask = PR_int__create_proto_meta_task( size, freer, magicNum ); return &(retMetaTask[1]); //skip over prolog } +inline +void +PR_int__insert_meta_task_into_slave( PRMetaTask *task, SlaveVP *slave ) + { + task->slaveAssignedTo = slave; + PR_int__insert_elem_into_collection( (PRCollElem *)task, + (PRCollElem **)slave->metaTasks, task->langMagicNumber ); + } +inline +void +PR_int__insert_lang_meta_task_into_slave( void *langMetaTask, SlaveVP *slave ) + { PRMetaTask *metaTask = &(((PRMetaTask*)langMetaTask)[-1]); + metaTask->slaveAssignedTo = slave; + PR_int__insert_elem_into_collection( (PRCollElem *)metaTask, + (PRCollElem **)slave->metaTasks, metaTask->langMagicNumber ); + } + /*allocates space for a new lang-meta-task, and inserts it into the slave, * under the given magic number. */ inline void * -PR_int__create_lang_meta_task_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum ) +PR_int__create_lang_meta_task_in_slave( int32 size, LangMetaTaskFreer freer, SlaveVP *slave, int32 magicNum ) { PRMetaTask *retMetaTask; PRCollElem **metaTasks; //make the new meta task - retMetaTask = PR_int__malloc( sizeof(PRMetaTask) + size ); - retMetaTask->chainedMetaTask = NULL; - retMetaTask->langMagicNumber = magicNum; + retMetaTask = PR_int__create_proto_meta_task( size, freer, magicNum ); retMetaTask->slaveAssignedTo = slave; retMetaTask->taskType = GenericSlave; - retMetaTask->ID = NULL; - //multilang has a "collection" of meta tasks inside the slave - metaTasks = (PRCollElem **)slave->metaTask; + //have a "collection" of meta tasks inside the slave + metaTasks = (PRCollElem **)slave->metaTasks; PR_int__insert_elem_into_collection( (PRCollElem *)retMetaTask, metaTasks, magicNum ); return &(retMetaTask[1]); //skip over prolog } + + inline -void -PR_int__insert_meta_task_into_slave__ML( PRMetaTask *task, SlaveVP *slave ) - { - task->slaveAssignedTo = slave; - PR_int__insert_elem_into_collection( (PRCollElem *)task, - (PRCollElem **)slave->metaTask, task->langMagicNumber ); +void * +PR_int__give_lang_meta_task_from_slave( SlaveVP *slave, int32 magicNum ) + { PRMetaTask *retMetaTask; + PRCollElem **metaTasks; + PRLangEnv *protoLangEnv; + + metaTasks = (PRCollElem **)slave->metaTasks; + retMetaTask = PR_int__lookup_elem_in_collection( magicNum, metaTasks ); + if( retMetaTask != NULL ) + return &(retMetaTask[1]); //skip over prolog + else + { protoLangEnv = PR_int__give_proto_lang_env_for_slave( slave ); + if(protoLangEnv->langMetaTaskCreator == NULL) + PR_int__throw_exception("register a meta task creator"); + //This will call + return (*protoLangEnv->langMetaTaskCreator)( slave ); + } } + inline -void -PR_int__insert_lang_meta_task_into_slave__ML( void *langMetaTask, SlaveVP *slave ) +SlaveVP * +PR_PI__give_slave_lang_meta_task_is_assigned_to( void *langMetaTask ) { PRMetaTask *metaTask = &(((PRMetaTask*)langMetaTask)[-1]); - metaTask->slaveAssignedTo = slave; - PR_int__insert_elem_into_collection( (PRCollElem *)metaTask, - (PRCollElem **)slave->metaTask, metaTask->langMagicNumber ); + return metaTask->slaveAssignedTo; + } + +//================== langData ============================= +inline +PRLangData * +PR_int__give_prolog_of_lang_data( void *langData ) + { + return (PRLangData *) &(((PRLangData *)langData)[-1]); } inline void * -PR_int__give_lang_meta_task_from_slave__ML( SlaveVP *slave, int32 magicNum ) - { PRMetaTask *retMetaTask; - PRCollElem **metaTasks; - - metaTasks = (PRCollElem **)slave->metaTask; - retMetaTask = PR_int__lookup_elem_in_collection( magicNum, metaTasks ); - if( retMetaTask != NULL ) - return &(retMetaTask[1]); //skip over prolog - else - return NULL; +PR_int__give_lang_data_of_prolog( PRLangData *langData) + { + return (void *)&(langData[1]); } -inline -SlaveVP * -PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask ) - { PRMetaTask *metaTask = &(((PRMetaTask*)langMetaTask)[-1]); - return metaTask->slaveAssignedTo; - } - -//=============================================== -/*Allocates space for a new lang-lang-data, and inserts it into the slave, +/*Allocates space for a new lang-data, and inserts it into the slave, * under the given magic number. Also returns it. + * + *Langlet is responsible for using this to create lang data inside its + * create-slave handler */ inline void * -PR_int__create_lang_data_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum ) +PR_PI__create_lang_data_in_slave( int32 size, LangDataFreer freer, + SlaveVP *slave, int32 magicNum ) { PRLangData *retLangData; PRCollElem **langDatas; @@ -656,26 +627,45 @@ retLangData = PR_int__malloc( sizeof(PRLangData) + size ); retLangData->chainedLangData = NULL; retLangData->langMagicNumber = magicNum; + retLangData->freer = freer; + retLangData->slaveAssignedTo = slave; //multilang has a "collection" of lang datas inside the slave - langDatas = (PRCollElem **)slave->langData; + langDatas = (PRCollElem **)slave->langDatas; PR_int__insert_elem_into_collection( (PRCollElem *)retLangData, langDatas, magicNum ); return &(retLangData[1]); //skip over prolog } +void +PR_int__free_lang_data( void *langData) + { PRLangData *protoLangData; + + protoLangData = PR_int__give_prolog_of_lang_data( langData ); + PR_int__remove_elem_from_collection( protoLangData->langMagicNumber, + protoLangData->slaveAssignedTo->langDatas ); + + (*protoLangData->freer)(langData); + PR_int__free( protoLangData ); + } inline void * -PR_int__give_lang_data_from_slave__ML( SlaveVP *slave, int32 magicNum ) - { PRLangData *retLangData; +PR_int__give_lang_data_from_slave( SlaveVP *slave, int32 magicNum ) + { PRLangData *retLangData; PRCollElem **langDatas; + PRLangEnv *protoLangEnv; - langDatas = (PRCollElem **)slave->langData; + langDatas = (PRCollElem **)slave->langDatas; retLangData = PR_int__lookup_elem_in_collection( magicNum, langDatas ); if( retLangData != NULL ) - return &(retLangData[1]); //skip over prolog + return &( retLangData[1] ); //skip over prolog else - return NULL; + { protoLangEnv = PR_int__give_proto_lang_env_for_slave( slave ); + if(protoLangEnv->langDataCreator == NULL) + PR_int__throw_exception("register a lang data creator"); + //This will call PR_PI__create_lang_data_in_slave + return (*protoLangEnv->langDataCreator)( slave ); + } } diff -r 292393c6bef1 -r bc5030385120 PR__int.h --- a/PR__int.h Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__int.h Tue Feb 05 20:23:27 2013 -0800 @@ -19,17 +19,6 @@ * int: internal to the PR implementation */ - -inline SlaveVP * -PR_int__create_slave( TopLevelFnPtr fnPtr, void *dataParam ); -#define PR_PI__create_slaveVP PR_int__create_slave -#define PR_WL__create_slaveVP PR_int__create_slave - -inline -SlaveVP * -PR_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr, - void *dataParam, void *stackLocs ); - inline PRMetaTask * PR_int__create_generic_slave_meta_task( void *initData ); @@ -54,11 +43,11 @@ //=========================================================================== inline SlaveVP * -PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam ); +PR_int__create_slaveVP_helper( TopLevelFnPtr fnPtr, void *dataParam ); inline SlaveVP * -PR_int__create_slaveVP__ML( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process ); +PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process ); SlaveVP * PR_int__get_recycled_slot_slave( ); @@ -82,7 +71,7 @@ PR_int__put_slave_into_slot( SlaveVP *slave, AnimSlot *slot ); void inline -PR_int__handle_PRServiceReq( SlaveVP *requestingSlv ); +PRHandle__ServiceReq( SlaveVP *requestingSlv ); void PR_WL__suspend_slaveVP_and_send_req( SlaveVP *animatingSlv ); @@ -91,16 +80,16 @@ PR_int__dissipate_slaveVP__SL( SlaveVP *animatingSlv ); void -PR_int__free_slaveVP__ML( SlaveVP *slave ); +PR_int__free_slaveVP( SlaveVP *slave ); void -PR_int__recycle_slave__ML( SlaveVP *slave ); +PR_int__recycle_slave( SlaveVP *slave ); void -recycleLangDataAsElem( void *elem ); +freeLangDataAsElem( void *elem ); void -recycleMetaTaskAsElem( void *elem ); +freeMetaTaskAsElem( void *elem ); inline void * @@ -120,13 +109,13 @@ inline void * -PR_int__give_lang_env_of_req__ML( PRReqst *req, SlaveVP *requestingSlv ); +PR_int__give_lang_env_of_req( PRReqst *req, SlaveVP *requestingSlv ); inline void * -PR_int__give_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNum ); -#define PR_PI__give_lang_env_for PR_int__give_lang_env_for_slave__ML -#define PR_SS__give_lang_env_for_slave PR_int__give_lang_env_for_slave__ML +PR_int__give_lang_env_for_slave( SlaveVP *slave, int32 magicNum ); +#define PR_PI__give_lang_env_for PR_int__give_lang_env_for_slave +#define PR_SS__give_lang_env_for_slave PR_int__give_lang_env_for_slave //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable inline @@ -148,6 +137,7 @@ PRLangEnv * PR_int__give_proto_lang_env_for_process( PRProcess *process, int32 magicNum ); +/* inline void PR_int__set_work_in_lang_env( void *_langEnv ); @@ -155,6 +145,7 @@ inline void PR_int__clear_work_in_lang_env( void *_langEnv ); + */ inline PRMetaTask * @@ -166,15 +157,15 @@ inline void * -PR_int__create_lang_meta_task__ML( int32 size, int32 magicNum ); +PR_int__create_lang_meta_task( int32 size, int32 magicNum ); inline void * -PR_int__create_lang_meta_task_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum ); +PR_int__create_lang_meta_task_in_slave( int32 size, SlaveVP *slave, int32 magicNum ); inline void -PR_int__insert_meta_task_into_slave__ML( PRMetaTask *task, SlaveVP *slave ); +PR_int__insert_meta_task_into_slave( PRMetaTask *task, SlaveVP *slave ); inline void @@ -182,27 +173,27 @@ inline void * -PR_int__give_lang_meta_task_from_slave__ML( SlaveVP *slave, int32 magicNumer ); +PR_int__give_lang_meta_task_from_slave( SlaveVP *slave, int32 magicNumer ); //#define PR_int__give_lang_meta_task_from_slave__ML( slave, magicNumber )\ slave->metaTask->langMetaTask; -#define PR_PI__give_lang_meta_task_from_slave__ML PR_int__give_lang_meta_task_from_slave__ML -#define PR_SS__give_lang_meta_task_from_slave__ML PR_int__give_lang_meta_task_from_slave__ML -#define PR_WL__give_lang_meta_task_from_slave__ML PR_int__give_lang_meta_task_from_slave__ML +#define PR_PI__give_lang_meta_task_from_slave__ML PR_int__give_lang_meta_task_from_slave +#define PR_SS__give_lang_meta_task_from_slave__ML PR_int__give_lang_meta_task_from_slave +#define PR_WL__give_lang_meta_task_from_slave__ML PR_int__give_lang_meta_task_from_slave inline SlaveVP * -PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask ); +PR_PI__give_slave_lang_meta_task_is_assigned_to( void *langMetaTask ); inline void * -PR_int__create_lang_data_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum ); +PR_PI__create_lang_data_in_slave( int32 size, SlaveVP *slave, int32 magicNum ); inline void * -PR_int__give_lang_data_from_slave__ML( SlaveVP *slave, int32 magicNumer ); -#define PR_PI__give_lang_data PR_int__give_lang_data_from_slave__ML -#define PR_SS__give_lang_data PR_int__give_lang_data_from_slave__ML -#define PR_WL__give_lang_data PR_int__give_lang_data_from_slave__ML +PR_int__give_lang_data_from_slave( SlaveVP *slave, int32 magicNumer ); +#define PR_PI__give_lang_data PR_int__give_lang_data_from_slave +#define PR_SS__give_lang_data PR_int__give_lang_data_from_slave +#define PR_WL__give_lang_data PR_int__give_lang_data_from_slave inline void diff -r 292393c6bef1 -r bc5030385120 PR__structs.h --- a/PR__structs.h Wed Jan 16 01:50:26 2013 -0800 +++ b/PR__structs.h Tue Feb 05 20:23:27 2013 -0800 @@ -25,16 +25,21 @@ typedef struct _SlaveVP SlaveVP; typedef struct _MasterVP MasterVP; typedef struct _IntervalProbe IntervalProbe; -typedef struct _PRLangEnv PRLangEnv; //a prolog +typedef struct _PRLangEnv PRLangEnv; //a prolog typedef struct _PRMetaTask PRMetaTask; //a prolog -typedef struct _PRLangData PRLangData; //a prolog +typedef struct _PRLangData PRLangData; //a prolog typedef struct _PRCollElem PRCollElem; //generic form of the prologs 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 (*LangShutdownHdlr) ( void * ); //langEnv +typedef void *(*LangDataCreator) ( SlaveVP * ); +typedef void (*LangDataFreer) ( void * ); //lang data to free +typedef void *(*LangMetaTaskCreator)( SlaveVP * ); +typedef void (*LangMetaTaskFreer) ( void * ); //lang meta task to free +typedef void (*MakeSlaveReadyFn) ( SlaveVP *, void * ); //slave and langEnv +typedef void (*MakeTaskReadyFn) ( void *, void * ); //langTask and langEnv typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); @@ -84,6 +89,7 @@ bool32 executionIsComplete; pthread_mutex_t doneLock; pthread_cond_t doneCond; + pthread_mutex_t doneAckLock; //waiter gets, then releases when done waiting //=========== MEASUREMENT STUFF ============= IntervalProbe **intervalProbes; @@ -127,6 +133,8 @@ void *langReq; PRProcess *processReqIsIn; int32 langMagicNumber; + SlaveVP *requestingSlave; + TopLevelFnPtr topLevelFn; void *initData; int32 *ID; @@ -220,8 +228,8 @@ //For language specific data that needs to be in the slave //These are accessed directly for single-lang, but multi-lang places // a holder here instead, then uses magic num to get lang's version - void *langData; //Lang saves lang-specific things in slave here - void *metaTask; + void *langDatas; //Lang saves lang-specific things in slave here + void *metaTasks; //=========== MEASUREMENT STUFF ========== MEAS__Insert_Meas_Fields_into_Slave; @@ -250,7 +258,7 @@ //============ below this, no fields are used in asm ============= //Basic PR infrastructure - enum PRMode mode; +// enum PRMode mode; SlaveVP **masterVPs; AnimSlot ***allAnimSlots; PrivQueueStruc *slaveRecycleQ; @@ -272,14 +280,13 @@ int32 numProcesses; int32 currProcessIdx; //used to choose which process gets slot int32 firstProcessReady; //use while starting up coreCtlr - RequestHandler free_lang_data; //lang data persists after langlet stops - //so need freer when end slaves //initialize flags for waiting for activity within PR to complete - bool32 allActivityIsDone; - pthread_mutex_t activityDoneLock; - pthread_cond_t activityDoneCond; + bool32 allActivityIsDone; + pthread_mutex_t activityDoneLock; + pthread_cond_t activityDoneCond; + SlaveAssigner overrideAssigner; //============== Below this is only used by single-lang mode ============== void *protoLangEnv; @@ -323,19 +330,21 @@ //============================================================= SlaveAssigner workAssigner; -// RequestHandler requestHdlr; LangShutdownHdlr shutdownHdlr; //called when lang ended or process shutdown - + LangDataCreator langDataCreator; + LangMetaTaskCreator langMetaTaskCreator; + MakeSlaveReadyFn makeSlaveReadyFn; + MakeTaskReadyFn makeTaskReadyFn; /* CreateTaskHdlr createTaskHdlr; RequestHandler endTaskHdlr; CreateSlvHdlr createSlaveHdlr; RequestHandler dissipateSlaveHdlr; - RequestHandler langDataCreator; + LangDataFreer langDataFreer; + LangMetaTaskFreer langMetaTaskFreer; 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 @@ -343,6 +352,9 @@ PRProcess *processEnvIsIn; int32 idxInProcess; //index into array of langEnvs in the process + + int32 numReadyWork; + fixme; //make make_ready update the process's numEnvs with work }; //PRLangEnv -- this is the prolog of every lang's lang env @@ -362,7 +374,7 @@ SlaveVP *slaveAssignedTo; //no valid until task animated TopLevelFnPtr topLevelFn; //This is the Fn executes as the task void *initData; //The data taken by the function - void (*recycler)(void *); + LangMetaTaskFreer freer; //NOTE: info needed for "wait" functionality is inside lang's metaTask }; @@ -370,11 +382,11 @@ struct _PRLangData { //============== First two must match PRCollElem ============== - int32 langMagicNumber; - PRLangData *chainedLangData; + int32 langMagicNumber; + PRLangData *chainedLangData; //============================================================= - void (*recycler)(void *); - void *langLangData; + LangDataFreer freer; + SlaveVP *slaveAssignedTo; }; //PRLangData -- this is the prolog of each lang's lang data diff -r 292393c6bef1 -r bc5030385120 Services_Offered_by_PR/Services_Language/PRServ.h --- a/Services_Offered_by_PR/Services_Language/PRServ.h Wed Jan 16 01:50:26 2013 -0800 +++ b/Services_Offered_by_PR/Services_Language/PRServ.h Tue Feb 05 20:23:27 2013 -0800 @@ -6,13 +6,13 @@ * */ -#ifndef _PRServ_H -#define _PRServ_H #include "Queue_impl/PrivateQueue.h" #include "Hash_impl/PrivateHash.h" -#include "PR_impl/PR.h" -#include "Measurement/dependency.h" +//#include "../Measurement_and_Stats/" + +#ifndef _PRServ_H +#define _PRServ_H //=========================================================================== @@ -45,35 +45,9 @@ }; -enum PRServReqType - { - submit_task = 1, - end_task, - create_slave, - create_slave_w_aff, - dissipate_slave, - //=============================== - send_type_to, - receive_type_to, - send_from_to, - receive_from_to, - //=============================== - taskwait, - malloc_req, - free_req, - singleton_fn_start, - singleton_fn_end, - singleton_data_start, - singleton_data_end, - atomic, - trans_start, - trans_end - }; - struct _PRServSemReq { enum PRServReqType reqType; SlaveVP *callingSlv; - PRServTaskType *taskType; void *args; // PRServTaskStub *taskStub; //not needed -- get via PR accessor from slv @@ -95,9 +69,7 @@ void *ptrToFree; int32 singletonID; - PRServSingleton **singletonPtrAddr; - PtrToAtomicFn fnToExecInMaster; void *dataForFn; int32 transID; @@ -106,7 +78,7 @@ typedef struct - { PRSemEnv *protoSemEnv; + { PRLangEnv *protoLangEnv; PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) PrivQueueStruc *freeTaskSlvRecycleQ; //Shared PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) @@ -116,8 +88,6 @@ int32 primitiveStartTime; //fix limit on num with dynArray - PRServSingleton fnSingletons[NUM_STRUCS_IN_SEM_ENV]; - PRServTrans transactionStrucs[NUM_STRUCS_IN_SEM_ENV]; #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC ListOfArrays* unitList; @@ -164,9 +134,6 @@ //=========================================================================== -void -PRServ__create_seed_slave_and_do_work( TopLevelFnPtr fn, void *initData ); - int32 PRServ__giveMinWorkUnitCycles( float32 percentOverhead ); @@ -191,13 +158,8 @@ PRServ__cleanup_after_shutdown(); //======================= - -SlaveVP * -PRServ__create_thread( TopLevelFnPtr fnPtr, void *initData, - SlaveVP *creatingThd ); - void -PRServ__end_thread( SlaveVP *thdToEnd ); +PRServ__resume_slaveVP( SlaveVP *seedSlv, PRServLangEnv *servicesLangEnv ); //======================= @@ -207,89 +169,16 @@ //======================= -void -PRServ__submit_task( PRServTaskType *taskType, void *args, SlaveVP *animSlv); - -inline int32 * -PRServ__create_taskID_of_size( int32 numInts, SlaveVP *animSlv ); - -void -PRServ__submit_task_with_ID( PRServTaskType *taskType, void *args, int32 *taskID, - SlaveVP *animSlv); - -void -PRServ__end_task( SlaveVP *animSlv ); //========================= -void -PRServ__taskwait(SlaveVP *animSlv); - - -inline int32 * -PRServ__give_self_taskID( SlaveVP *animSlv ); - -void -PRServ__send_of_type_to( void *msg, const int32 type, int32 *receiverID, - SlaveVP *senderSlv ); - -void -PRServ__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ); - -void * -PRServ__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ); - -void * -PRServ__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ); - -//======================= Concurrency Stuff ====================== -void -PRServ__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ); - -void -PRServ__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ); - -void -PRServ__start_data_singleton( PRServSingleton **singeltonAddr, SlaveVP *animSlv ); - -void -PRServ__end_data_singleton( PRServSingleton **singletonAddr, SlaveVP *animSlv ); - -void -PRServ__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, - void *data, SlaveVP *animSlv ); - -void -PRServ__start_transaction( int32 transactionID, SlaveVP *animSlv ); - -void -PRServ__end_transaction( int32 transactionID, SlaveVP *animSlv ); //========================= Internal use only ============================= -void -PRServ__Request_Handler( SlaveVP *requestingSlv, void *_semEnv ); SlaveVP * PRServ__assign_work_to_slot( void *_semEnv, AnimSlot *slot ); -SlaveVP* -PRServ__create_slave_helper( TopLevelFnPtr fnPtr, void *initData, - PRServSemEnv *semEnv, int32 coreToAssignOnto ); - -PRMetaTask * -PR_int__create_generic_slave_meta_task( void *initData ); - - -SlaveVP * -PRServ__create_slave_with( TopLevelFnPtr fnPtr, void *initData, - SlaveVP *creatingSlv ); - -SlaveVP * -PRServ__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, - SlaveVP *creatingSlv, int32 coreToAssignOnto); - //===================== Measurement of Lang Overheads ===================== -#include "Measurement/PRServ_Measurement.h" //=========================================================================== #endif /* _PRServ_H */ diff -r 292393c6bef1 -r bc5030385120 Services_Offered_by_PR/Services_Language/PRServ_PluginFns.c --- a/Services_Offered_by_PR/Services_Language/PRServ_PluginFns.c Wed Jan 16 01:50:26 2013 -0800 +++ b/Services_Offered_by_PR/Services_Language/PRServ_PluginFns.c Tue Feb 05 20:23:27 2013 -0800 @@ -67,7 +67,7 @@ returnSlv = readPrivQ( semEnv->slavesReadyToResumeQ ); if( returnSlv != NULL ) //Yes, have a slave, so return it. { returnSlv->coreAnimatedBy = coreNum; - returnMetaTask = returnSlv->metaTask; + returnMetaTask = returnSlv->metaTasks; goto ReturnTheMetaTask; } @@ -102,7 +102,7 @@ newD.to_task = returnSlv->numTimesAssignedToASlot; addToListOfArrays(Dependency, newD, semEnv->ctlDependenciesList); } - returnMetaTask = returnSlv->metaTask; + returnMetaTask = returnSlv->metaTasks; } else //returnSlv != NULL { //assignSlv->numTimesAssigned++; diff -r 292393c6bef1 -r bc5030385120 Services_Offered_by_PR/Services_Language/PRServ_Request_Handlers.c --- a/Services_Offered_by_PR/Services_Language/PRServ_Request_Handlers.c Wed Jan 16 01:50:26 2013 -0800 +++ b/Services_Offered_by_PR/Services_Language/PRServ_Request_Handlers.c Tue Feb 05 20:23:27 2013 -0800 @@ -183,8 +183,8 @@ //For PRServ, caller needs ptr to created thread returned to it requestingSlv->dataRetFromReq = newSlv; - resume_slaveVP(requestingSlv , semEnv ); - resume_slaveVP( newSlv, semEnv ); + PR_PI__make_slave_ready(requestingSlv , semEnv ); + PR_PI__make_slave_ready( newSlv, semEnv ); } /*Initialize semantic data struct.. this initializer doesn't need any input, @@ -193,7 +193,7 @@ * use the PR_PI__give_sem_data inside the create handler, and fill in the * semData values there. */ -void * createInitialSemanticData( ) +void * PRServ__create_lang_data_in_slave( ) { PRServSemData *semData; semData = PR_PI__malloc( sizeof(PRServSemData) ); @@ -233,7 +233,7 @@ if( parentTaskStub->isWaitingForChildTasksToEnd ) return; //still waiting on tasks (should be impossible) else //parent free to resume - resume_slaveVP( PR_PI__give_slave_assigned_to(parentTaskStub), semEnv ); + PR_PI__make_slave_ready( PR_PI__give_slave_assigned_to(parentTaskStub), semEnv ); } //check if this is last child of ended parent (note, not possible to @@ -471,7 +471,7 @@ } //for argNum //resume the parent, creator - resume_slaveVP( semReq->callingSlv, semEnv ); + PR_PI__make_slave_ready( semReq->callingSlv, semEnv ); return; } @@ -539,7 +539,7 @@ parentStub->numLiveChildTasks == 0) { parentStub->isWaitingForChildTasksToEnd = FALSE; - resume_slaveVP( PR_PI__give_slave_assigned_to(parentStub), semEnv ); + PR_PI__make_slave_ready( PR_PI__give_slave_assigned_to(parentStub), semEnv ); } //Check if parent ended, and this was last descendent, then free it @@ -766,8 +766,8 @@ receiverSlv->dataRetFromReq = semReq->msg; //bring both processors back from suspend - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + PR_PI__make_slave_ready( senderSlv, semEnv ); + PR_PI__make_slave_ready( receiverSlv, semEnv ); return; } @@ -849,8 +849,8 @@ receiverSlv->dataRetFromReq = semReq->msg; //bring both processors back from suspend - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + PR_PI__make_slave_ready( senderSlv, semEnv ); + PR_PI__make_slave_ready( receiverSlv, semEnv ); return; } @@ -936,8 +936,8 @@ addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->receivers); #endif - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + PR_PI__make_slave_ready( senderSlv, semEnv ); + PR_PI__make_slave_ready( receiverSlv, semEnv ); return; } @@ -1005,8 +1005,8 @@ //bring both processors back from suspend PR_PI__free( waitingReq ); - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + PR_PI__make_slave_ready( senderSlv, semEnv ); + PR_PI__make_slave_ready( receiverSlv, semEnv ); return; } @@ -1028,7 +1028,7 @@ if( taskStub->numLiveChildTasks == 0 ) { //nobody to wait for, resume - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); } else //have to wait, mark waiting { @@ -1048,7 +1048,7 @@ ptr = PR_PI__malloc( semReq->sizeToMalloc ); requestingSlv->dataRetFromReq = ptr; - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); } /* @@ -1058,7 +1058,7 @@ { DEBUG__printf1(dbgRqstHdlr,"Free request from processor %d",requestingSlv->slaveID) PR_PI__free( semReq->ptrToFree ); - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); } @@ -1074,7 +1074,7 @@ if( singleton->hasFinished ) { //the code that sets the flag to true first sets the end instr addr reqstingSlv->dataRetFromReq = singleton->endInstrAddr; - resume_slaveVP( reqstingSlv, semEnv ); + PR_PI__make_slave_ready( reqstingSlv, semEnv ); return; } else if( singleton->hasBeenStarted ) @@ -1086,7 +1086,7 @@ { //hasn't been started, so this is the first attempt at the singleton singleton->hasBeenStarted = TRUE; reqstingSlv->dataRetFromReq = 0x0; - resume_slaveVP( reqstingSlv, semEnv ); + PR_PI__make_slave_ready( reqstingSlv, semEnv ); return; } } @@ -1139,10 +1139,10 @@ { //they will resume inside start singleton, then jmp to end singleton resumingSlv = readPrivQ( waitQ ); resumingSlv->dataRetFromReq = singleton->endInstrAddr; - resume_slaveVP( resumingSlv, semEnv ); + PR_PI__make_slave_ready( resumingSlv, semEnv ); } - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); } void inline @@ -1177,7 +1177,7 @@ { DEBUG__printf1(dbgRqstHdlr,"Atomic request from processor %d",requestingSlv->slaveID) semReq->fnToExecInMaster( semReq->dataForFn ); - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); } /*First, it looks at the VP's semantic data, to see the highest transactionID @@ -1223,7 +1223,7 @@ if( transStruc->VPCurrentlyExecuting == NULL ) { transStruc->VPCurrentlyExecuting = requestingSlv; - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); } else { //note, might make future things cleaner if save request with VP and @@ -1279,7 +1279,7 @@ transStruc->VPCurrentlyExecuting = waitingSlv; if( waitingSlv != NULL ) - resume_slaveVP( waitingSlv, semEnv ); + PR_PI__make_slave_ready( waitingSlv, semEnv ); - resume_slaveVP( requestingSlv, semEnv ); + PR_PI__make_slave_ready( requestingSlv, semEnv ); }