Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff AnimationMaster.c @ 272:bc5030385120
Progress -- back to compile process, fixing compile issues
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Tue, 05 Feb 2013 20:23:27 -0800 |
| parents | 292393c6bef1 |
| children | 40e7625e57bd |
line diff
1.1 --- a/AnimationMaster.c Wed Jan 16 01:50:26 2013 -0800 1.2 +++ b/AnimationMaster.c Tue Feb 05 20:23:27 2013 -0800 1.3 @@ -19,79 +19,37 @@ 1.4 void PRHandle_Dissipate_SL(SlaveVP *slave); 1.5 void PR_int__handle_PRServiceReq_SL(SlaveVP *slave); 1.6 */ 1.7 -inline void PRHandle_CreateTask( PRReqst *req, SlaveVP *slave ); 1.8 -inline void PRHandle_EndTask( PRReqst *req, SlaveVP *slave ); 1.9 -inline void PRHandle_CreateSlave(PRReqst *req, SlaveVP *slave ); 1.10 -void PRHandle_EndSlave( PRReqst *req, SlaveVP *slave ); 1.11 +inline void PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ); 1.12 +inline void PRHandle__EndTask( PRReqst *req, SlaveVP *slave ); 1.13 +inline void PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave ); 1.14 +void PRHandle__EndSlave( PRReqst *req, SlaveVP *slave ); 1.15 1.16 1.17 //inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot ); 1.18 inline PRProcess * pickAProcess( AnimSlot *slot ); 1.19 inline bool32 assignWork( PRProcess *process, AnimSlot *slot ); 1.20 1.21 -/*The animationMaster embodies most of the animator of the language. The 1.22 - * animator is what emodies the behavior of language constructs. 1.23 - * As such, it is the animationMaster, in combination with the plugin 1.24 - * functions, that make the language constructs do their behavior. 1.25 - * 1.26 - *Within the code, this is the top-level-function of the masterVPs, and 1.27 - * runs when the coreController has no more slave VPs. It's job is to 1.28 - * refill the animation slots with slaves that have work. 1.29 - * 1.30 - *There are multiple versions of the master, each tuned to a specific 1.31 - * combination of modes. This keeps the master simple, with reduced overhead, 1.32 - * when the application is not using the extra complexity. 1.33 - * 1.34 - *As of Sept 2012, the versions available will be: 1.35 - * 1) Single langauge, which only exposes slaves (such as SSR or Vthread) 1.36 - * 2) Single language, which only exposes tasks (such as pure dataflow) 1.37 - * 3) Single language, which exposes both (like Cilk, StarSs, and OpenMP) 1.38 - * 4) Multi-language, which always assumes both tasks and slaves 1.39 - * 5) Multi-language and multi-process, which also assumes both tasks and slaves 1.40 - * 1.41 - * 1.42 - * 1.43 + 1.44 +/*Note: there used to be a coreController that was another animation 1.45 + * layer below both the masterVP and the slaveVPs.. in that case, the 1.46 + * masterVP was a virtual processor whose processor-state was the same 1.47 + * as a slaveVP's processor sate, both implemented as a SlaveVP struct. 1.48 + * Have removed that, and 1.49 + * changed the masterVP implementation. Instead of being a special version 1.50 + * of a proto-runtime virtual processor, using the slaveVP stuct, the 1.51 + * Master "virtual processor" is now implemented as a pthread pinned to 1.52 + * a physical core. 1.53 */ 1.54 1.55 -//This version of the master selects one of three loops, depending upon 1.56 -// whether stand-alone single language (just slaves), or standalone with 1.57 -// tasks, or multi-lang (implies multi-process) 1.58 -void animationMaster( void *_environment, SlaveVP *masterVP ) 1.59 - { 1.60 - TopEnv *masterEnv = (TopEnv *)_environment; 1.61 - int32 slotIdx; 1.62 - AnimSlot *currSlot; 1.63 - //Used while scanning and filling animation slots 1.64 - AnimSlot **animSlots; 1.65 - 1.66 - //Local copies, for performance 1.67 - int32 thisCoresIdx; 1.68 - 1.69 - //======================== Initializations ======================== 1.70 - thisCoresIdx = masterVP->coreAnimatedBy; 1.71 - animSlots = masterEnv->allAnimSlots[thisCoresIdx]; 1.72 - 1.73 - HOLISTIC__Insert_Master_Global_Vars; 1.74 - 1.75 - //======================== animationMaster ======================== 1.76 - //Have three different modes, and the master behavior is different for 1.77 - // each, so jump to the loop that corresponds to the mode. 1.78 - // 1.79 - while(1) 1.80 - { MEAS__Capture_Pre_Master_Point 1.81 - for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++) 1.82 - { 1.83 - currSlot = animSlots[ slotIdx ]; 1.84 - 1.85 - masterFunction( currSlot ); 1.86 - } 1.87 - MEAS__Capture_Post_Master_Point; 1.88 - masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master 1.89 - flushRegisters(); 1.90 - } 1.91 - } 1.92 - 1.93 - 1.94 +/*This is the behavior of the Master. The physical processor switches 1.95 + * between animating the master, and animating a slave. When a slave 1.96 + * suspends, the PR "suspend" primitive switches the physical core over 1.97 + * to animating the masterVP, which is implemented as a pinned pthread. 1.98 + * This function is the behavior of that masterVP. 1.99 + *This function's job is to manage processing 1.100 + * requests and to trigger assignment of new work to the physical core, 1.101 + * and to manage sharing the core among processes. 1.102 + */ 1.103 inline 1.104 bool32 1.105 masterFunction( AnimSlot *slot ) 1.106 @@ -104,6 +62,8 @@ 1.107 bool32 foundWork; 1.108 1.109 //Check if newly-done slave in slot, which will need request handled 1.110 + //NOTE: left over from when had a coreController & MasterVP managed 1.111 + // several slots 1.112 if( slot->workIsDone ) 1.113 { slot->workIsDone = FALSE; 1.114 slot->needsWorkAssigned = TRUE; 1.115 @@ -126,16 +86,16 @@ 1.116 { case TaskEnd: 1.117 { //do PR handler, which calls lang's hdlr and does recycle of 1.118 // free task slave if needed -- PR handler checks for free task Slv 1.119 - PRHandle_EndTask( req, slave ); break; 1.120 + PRHandle__EndTask( req, slave ); break; 1.121 } 1.122 case TaskCreate: 1.123 { //Do PR's create-task handler, which calls the lang's hdlr 1.124 // PR handler checks for free task Slv 1.125 - PRHandle_CreateTask( req, slave ); break; 1.126 + PRHandle__CreateTask( req, slave ); break; 1.127 } 1.128 - case SlvCreate: PRHandle_CreateSlave( req, slave ); break; 1.129 - case SlvDissipate: PRHandle_EndSlave( req, slave ); break; 1.130 - case Service: PR_int__handle_PRServiceReq( slave ); break; //resumes into Service lang env 1.131 + case SlvCreate: PRHandle__CreateSlave( req, slave ); break; 1.132 + case SlvDissipate: PRHandle__EndSlave( req, slave ); break; 1.133 + case Service: PRHandle__ServiceReq( slave ); break; //resumes into Service lang env 1.134 case Hardware: //for future expansion 1.135 case IO: //for future expansion 1.136 case OSCall: //for future expansion 1.137 @@ -151,10 +111,12 @@ 1.138 HOLISTIC__Record_AppResponder_end; 1.139 } //if have request to be handled 1.140 1.141 - if( slot->needsWorkAssigned ) 1.142 + //NOTE: IF statement is leftover from when master managed many slots 1.143 + foundWork = FALSE; 1.144 + if( slot->needsWorkAssigned ) //can probably remove IF, not that only one slot 1.145 { 1.146 HOLISTIC__Record_Assigner_start; 1.147 - 1.148 + 1.149 //Pick a process to get this slot 1.150 process = pickAProcess( slot ); 1.151 1.152 @@ -164,6 +126,8 @@ 1.153 assignWork( process, slot ); 1.154 1.155 HOLISTIC__Record_Assigner_end; 1.156 + 1.157 +// fixme; //make this a while loop that tries a different process if this one fails 1.158 }//if slot needs slave assigned 1.159 1.160 return foundWork; 1.161 @@ -223,9 +187,7 @@ 1.162 inline 1.163 bool32 1.164 assignWork( PRProcess *process, AnimSlot *slot ) 1.165 - { SlaveVP *returnSlv; 1.166 - int32 coreNum, slotNum; 1.167 - PRMetaTask *assignedMetaTask; 1.168 + { int32 coreNum; 1.169 1.170 coreNum = slot->coreSlotIsOn; 1.171 1.172 @@ -244,9 +206,21 @@ 1.173 numEnvs = process->numLangEnvs; 1.174 for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array 1.175 { langEnv = langEnvsList[envIdx]; 1.176 - if( langEnv->hasWork ) 1.177 - { (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot 1.178 - goto ReturnAfterAssigningWork; //quit for-loop, cause found work 1.179 + if( langEnv->numReadyWork > 0 ) 1.180 + { bool32 1.181 + didAssignWork = 1.182 + (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot 1.183 + 1.184 + if(didAssignWork) 1.185 + { langEnv->numReadyWork -= 1; 1.186 + if( langEnv->numReadyWork == 0 ) 1.187 + { process->numEnvsWithWork -= 1; 1.188 + } 1.189 + goto ReturnAfterAssigningWork; //quit for-loop, 'cause found work 1.190 + } 1.191 + else 1.192 + goto NoWork; //quit for-loop, cause found work 1.193 + 1.194 //NOTE: bad search alg -- should start where left off, then wrap around 1.195 } 1.196 } 1.197 @@ -255,7 +229,7 @@ 1.198 NoWork: //No work, if end up here.. 1.199 { 1.200 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 1.201 - returnSlv = process->idleSlv[coreNum][slotNum]; 1.202 + returnSlv = process->idleSlv[coreNum][0]; //only one slot now, so [0] 1.203 1.204 //things that would normally happen in resume(), but idle VPs 1.205 // never go there 1.206 @@ -313,24 +287,25 @@ 1.207 */ 1.208 inline 1.209 void 1.210 -PRHandle_CreateSlave( PRReqst *req, SlaveVP *slave ) 1.211 +PRHandle__CreateSlave( PRReqst *req, SlaveVP *slave ) 1.212 { SlaveVP *newSlv; 1.213 PRProcess *process; 1.214 PRLangEnv *protoLangEnv; 1.215 1.216 process = slave->processSlaveIsIn; 1.217 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber ); 1.218 - 1.219 -// newSlv = PR_int__create_slave( req->topLevelFn, req->initData ); 1.220 - 1.221 - //create slv has diff prototype than standard reqst hdlr 1.222 + 1.223 + //create handler, or a future request handler will call PR_PI__make_slave_ready 1.224 + // which will in turn handle updating which langlets and which processes have 1.225 + // work available. 1.226 + //NOTE: create slv has diff prototype than standard reqst hdlr 1.227 newSlv = 1.228 (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv)); 1.229 1.230 newSlv->typeOfVP = GenericSlv; 1.231 newSlv->processSlaveIsIn = process; 1.232 newSlv->ID = req->ID; 1.233 - process->numLiveGenericSlvs += 1; 1.234 + process->numLiveGenericSlvs += 1; //not same as work ready! 1.235 } 1.236 1.237 /*The dissipate handler has to, update the number of slaves of the type, within 1.238 @@ -345,7 +320,7 @@ 1.239 */ 1.240 inline 1.241 void 1.242 -PRHandle_EndSlave( PRReqst *req, SlaveVP *slave ) 1.243 +PRHandle__EndSlave( PRReqst *req, SlaveVP *slave ) 1.244 { PRProcess *process; 1.245 PRLangEnv *protoLangEnv; 1.246 1.247 @@ -357,13 +332,14 @@ 1.248 if(req->handler != NULL) 1.249 (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) ); 1.250 1.251 - process->numLiveGenericSlvs -= 1; 1.252 - PR_int__recycle_slave__ML( slave ); 1.253 - 1.254 + process->numLiveGenericSlvs -= 1; 1.255 + PR_int__recycle_slave( slave ); 1.256 + //NOTE: dissipate is unrelated to work available (just in case wondering) 1.257 + 1.258 //check End Of Process Condition 1.259 if( process->numLiveTasks == 0 && 1.260 process->numLiveGenericSlvs == 0 ) 1.261 - PR_SS__shutdown_process__ML( process ); 1.262 + PR_SS__shutdown_process( process ); 1.263 } 1.264 1.265 /*Create task is a special form, that has PR behavior in addition to plugin 1.266 @@ -374,7 +350,7 @@ 1.267 */ 1.268 inline 1.269 void 1.270 -PRHandle_CreateTask( PRReqst *req, SlaveVP *slave ) 1.271 +PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ) 1.272 { PRMetaTask *metaTask; 1.273 PRProcess *process; 1.274 PRLangEnv *protoLangEnv; 1.275 @@ -400,8 +376,8 @@ 1.276 return; 1.277 } 1.278 1.279 -/*When a task ends, are two scenarios: 1) task ran to completion, or 2) task 1.280 - * suspended at some point in its code. 1.281 +/*When a task ends, have two scenarios: 1) task ran to completion, or 2) task 1.282 + * has been suspended at some point in its code. 1.283 *For 1, just decr count of live tasks (and check for end condition) -- the 1.284 * master loop will decide what goes into the slot freed up by this task end, 1.285 * so, here, don't worry about assigning a new task to the slot slave. 1.286 @@ -425,13 +401,13 @@ 1.287 */ 1.288 inline 1.289 void 1.290 -PRHandle_EndTask( PRReqst *req, SlaveVP *requestingSlv ) 1.291 +PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv ) 1.292 { void *langEnv; 1.293 PRProcess *process; 1.294 void *langMetaTask; 1.295 1.296 - langEnv = PR_int__give_lang_env_of_req__ML( req, requestingSlv ); //magic num in req 1.297 - langMetaTask = PR_int__give_lang_meta_task_from_slave__ML( requestingSlv, req->langMagicNumber); 1.298 + langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req 1.299 + langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber); 1.300 1.301 //Do the langlet's request handler 1.302 //Want to keep PR structs hidden from plugin, so extract langReq.. 1.303 @@ -439,15 +415,47 @@ 1.304 1.305 //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv 1.306 if( requestingSlv->typeOfVP == FreeTaskSlv ) 1.307 - PR_int__recycle_slave__ML( requestingSlv ); 1.308 + PR_int__recycle_slave( requestingSlv ); //Doesn't decr num live slaves 1.309 1.310 process->numLiveTasks -= 1; 1.311 + //NOTE: end-task is unrelated to work available (just in case wondering) 1.312 1.313 //check End Of Process Condition 1.314 if( process->numLiveTasks == 0 && 1.315 process->numLiveGenericSlvs == 0 ) 1.316 { //Tell the core controller to do wakeup of any waiting OS thread 1.317 - PR_SS__shutdown_process__ML( process ); 1.318 + PR_SS__shutdown_process( process ); 1.319 } 1.320 } 1.321 1.322 + 1.323 +/*This is for OS requests and PR infrastructure requests, which are not 1.324 + * part of the PRServ language -- this is for things that have to be in the 1.325 + * infrastructure of PR itself, such as I/O requests, which have to go through 1.326 + * pthreads inside the core controller.. 1.327 + * 1.328 + *As of Jan 2013, doesn't do much of anything.. 1.329 + */ 1.330 +void inline 1.331 +PRHandle__ServiceReq( SlaveVP *requestingSlv ) 1.332 + { PRReqst *req; 1.333 + PRServReq *langReq; 1.334 + void *langEnv; 1.335 + int32 magicNumber; 1.336 + 1.337 + 1.338 + req = requestingSlv->request; 1.339 + 1.340 + magicNumber = req->langMagicNumber; 1.341 + langEnv = PR_PI__give_lang_env_for( slave, magicNumber ); 1.342 + 1.343 + langReq = PR_PI__take_lang_reqst_from(req); 1.344 + if( langReq == NULL ) return; 1.345 + switch( langReq->reqType ) //lang handlers are all in other file 1.346 + { 1.347 + case make_probe: handleMakeProbe( langReq, langEnv ); 1.348 + break; 1.349 + case throw_excp: handleThrowException( langReq, langEnv ); 1.350 + break; 1.351 + } 1.352 + }
