Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff AnimationMaster.c @ 273:40e7625e57bd
Compiles and runs, up to end of process, working on end process and shutdown
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Sat, 02 Mar 2013 09:43:45 -0800 |
| parents | bc5030385120 |
| children | 1d7ea1b0f176 |
line diff
1.1 --- a/AnimationMaster.c Tue Feb 05 20:23:27 2013 -0800 1.2 +++ b/AnimationMaster.c Sat Mar 02 09:43:45 2013 -0800 1.3 @@ -12,23 +12,30 @@ 1.4 #include "PR.h" 1.5 #include "VSs_impl/VSs.h" 1.6 1.7 -/* 1.8 -void PRHandle_CreateTask_SL(SlaveVP *slave); 1.9 +//========================= Local Declarations ======================== 1.10 +inline PRProcess * 1.11 +pickAProcess( AnimSlot *slot ); 1.12 +inline bool32 1.13 +assignWork( PRProcess *process, AnimSlot *slot ); 1.14 1.15 -void PRHandle_CreateSlave_SL(SlaveVP *slave); 1.16 -void PRHandle_Dissipate_SL(SlaveVP *slave); 1.17 -void PR_int__handle_PRServiceReq_SL(SlaveVP *slave); 1.18 -*/ 1.19 -inline void PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ); 1.20 -inline void PRHandle__EndTask( PRReqst *req, SlaveVP *slave ); 1.21 -inline void PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave ); 1.22 -void PRHandle__EndSlave( PRReqst *req, SlaveVP *slave ); 1.23 +inline void 1.24 +PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ); 1.25 +inline void 1.26 +PRHandle__EndTask( PRReqst *req, SlaveVP *slave ); 1.27 +inline void 1.28 +PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave ); 1.29 +inline void 1.30 +PRHandle__EndSlave( PRReqst *req, SlaveVP *slave ); 1.31 1.32 +inline void 1.33 +PRHandle__LangShutdown( PRReqst *req, SlaveVP *requestingSlv ); 1.34 1.35 -//inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot ); 1.36 -inline PRProcess * pickAProcess( AnimSlot *slot ); 1.37 -inline bool32 assignWork( PRProcess *process, AnimSlot *slot ); 1.38 +inline void 1.39 +handleMakeProbe( PRServiceReq *langReq, PRLangEnv *protoLangEnv ); 1.40 +inline void 1.41 +handleThrowException( PRServiceReq *langReq, PRLangEnv *protoLangEnv ); 1.42 1.43 +//=========================================================================== 1.44 1.45 /*Note: there used to be a coreController that was another animation 1.46 * layer below both the masterVP and the slaveVPs.. in that case, the 1.47 @@ -59,7 +66,7 @@ 1.48 PRLangEnv *langEnv; 1.49 PRReqst *req; 1.50 PRProcess *process; 1.51 - bool32 foundWork; 1.52 + bool32 didAssignWork; 1.53 1.54 //Check if newly-done slave in slot, which will need request handled 1.55 //NOTE: left over from when had a coreController & MasterVP managed 1.56 @@ -67,53 +74,58 @@ 1.57 if( slot->workIsDone ) 1.58 { slot->workIsDone = FALSE; 1.59 slot->needsWorkAssigned = TRUE; 1.60 + 1.61 + //An Idle VP has no request to handle, so skip to assign.. 1.62 + if( slot->slaveAssignedToSlot->typeOfVP != IdleVP ) 1.63 + { 1.64 + HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot 1.65 + MEAS__startReqHdlr; 1.66 1.67 - HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot 1.68 - MEAS__startReqHdlr; 1.69 1.70 + //process the request made by the slave (held inside slave struc) 1.71 + slave = slot->slaveAssignedToSlot; 1.72 + req = slave->request; 1.73 1.74 - //process the request made by the slave (held inside slave struc) 1.75 - slave = slot->slaveAssignedToSlot; 1.76 - req = slave->request; 1.77 + //If the requesting slave is a slot slave, and request is not 1.78 + // task-end, then turn it into a free task slave & continue 1.79 + if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd ) 1.80 + PR_int__replace_with_new_slot_slv( slave ); 1.81 1.82 - //If the requesting slave is a slot slave, and request is not 1.83 - // task-end, then turn it into a free task slave. 1.84 - if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd ) 1.85 - PR_int__replace_with_new_slot_slv( slave ); 1.86 - 1.87 - //Handle task create and end first -- they're special cases.. 1.88 - switch( req->reqType ) 1.89 - { case TaskEnd: 1.90 - { //do PR handler, which calls lang's hdlr and does recycle of 1.91 - // free task slave if needed -- PR handler checks for free task Slv 1.92 - PRHandle__EndTask( req, slave ); break; 1.93 + //Handle task create and end first -- they're special cases.. 1.94 + switch( req->reqType ) 1.95 + { case TaskEnd: 1.96 + { //do PR handler, which calls lang's hdlr and does recycle of 1.97 + // free task slave if needed -- PR handler checks for free task Slv 1.98 + PRHandle__EndTask( req, slave ); break; 1.99 + } 1.100 + case TaskCreate: 1.101 + { //Do PR's create-task handler, which calls the lang's hdlr 1.102 + // PR handler checks for free task Slv 1.103 + PRHandle__CreateTask( req, slave ); break; 1.104 + } 1.105 + case SlvCreate: PRHandle__CreateSlave( req, slave ); break; 1.106 + case SlvDissipate: PRHandle__EndSlave( req, slave ); break; 1.107 + case Service: PRHandle__ServiceReq( slave ); break; //resumes into Service lang env 1.108 + case Hardware: //for future expansion 1.109 + case IO: //for future expansion 1.110 + case OSCall: //for future expansion 1.111 + PR_int__throw_exception("Not implemented", slave, NULL); break; 1.112 + case LangShutdown: PRHandle__LangShutdown( req, slave ); break; 1.113 + case Language: //normal lang request 1.114 + { magicNumber = req->langMagicNumber; 1.115 + langEnv = PR_PI__give_lang_env_for_slave( slave, magicNumber ); 1.116 + (*req->handler)( req->langReq, slave, langEnv ); 1.117 + } 1.118 } 1.119 - case TaskCreate: 1.120 - { //Do PR's create-task handler, which calls the lang's hdlr 1.121 - // PR handler checks for free task Slv 1.122 - PRHandle__CreateTask( req, slave ); break; 1.123 - } 1.124 - case SlvCreate: PRHandle__CreateSlave( req, slave ); break; 1.125 - case SlvDissipate: PRHandle__EndSlave( req, slave ); break; 1.126 - case Service: PRHandle__ServiceReq( slave ); break; //resumes into Service lang env 1.127 - case Hardware: //for future expansion 1.128 - case IO: //for future expansion 1.129 - case OSCall: //for future expansion 1.130 - PR_int__throw_exception("Not implemented", slave, NULL); break; 1.131 - case Language: //normal lang request 1.132 - { magicNumber = req->langMagicNumber; 1.133 - langEnv = PR_PI__give_lang_env_for( slave, magicNumber ); 1.134 - (*req->handler)( req->langReq, slave, langEnv ); 1.135 - } 1.136 - } 1.137 - 1.138 + 1.139 MEAS__endReqHdlr; 1.140 HOLISTIC__Record_AppResponder_end; 1.141 + }//if not idleVP 1.142 } //if have request to be handled 1.143 1.144 //NOTE: IF statement is leftover from when master managed many slots 1.145 - foundWork = FALSE; 1.146 - if( slot->needsWorkAssigned ) //can probably remove IF, not that only one slot 1.147 + didAssignWork = FALSE; 1.148 + if( slot->needsWorkAssigned ) //can probably remove IF, now that only one slot 1.149 { 1.150 HOLISTIC__Record_Assigner_start; 1.151 1.152 @@ -122,15 +134,19 @@ 1.153 1.154 //Scan lang environs, looking for langEnv with ready work. 1.155 // call the Assigner for that lang Env, to get a slave for the slot 1.156 - foundWork = 1.157 - assignWork( process, slot ); 1.158 - 1.159 + if( process != NULL ) 1.160 + { didAssignWork = 1.161 + assignWork( process, slot ); 1.162 + } 1.163 HOLISTIC__Record_Assigner_end; 1.164 1.165 -// fixme; //make this a while loop that tries a different process if this one fails 1.166 + if( !didAssignWork ) //if no work assigned, be sure idle slave is in slot 1.167 + { slot->slaveAssignedToSlot = _PRTopEnv->idleSlv[slot->coreSlotIsOn][0]; 1.168 + } 1.169 +// fixme; //make into a loop that tries more processes if fails to assign 1.170 }//if slot needs slave assigned 1.171 1.172 - return foundWork; 1.173 + return didAssignWork; 1.174 } 1.175 1.176 /*When several processes exist, use some pattern for picking one to give 1.177 @@ -201,19 +217,19 @@ 1.178 } 1.179 1.180 //If here, then no override assigner, so search language envs for work 1.181 - int32 envIdx, numEnvs; PRLangEnv **langEnvsList, *langEnv; 1.182 - langEnvsList = process->langEnvsList; 1.183 + int32 envIdx, numEnvs; PRLangEnv **protoLangEnvsList, *protoLangEnv; 1.184 + protoLangEnvsList = process->protoLangEnvsList; 1.185 numEnvs = process->numLangEnvs; 1.186 for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array 1.187 - { langEnv = langEnvsList[envIdx]; 1.188 - if( langEnv->numReadyWork > 0 ) 1.189 + { protoLangEnv = protoLangEnvsList[envIdx]; 1.190 + if( protoLangEnv->numReadyWork > 0 ) 1.191 { bool32 1.192 didAssignWork = 1.193 - (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot 1.194 + (*protoLangEnv->workAssigner)( PR_int__give_lang_env(protoLangEnv), slot ); //assigner calls PR to put slave/task into slot 1.195 1.196 if(didAssignWork) 1.197 - { langEnv->numReadyWork -= 1; 1.198 - if( langEnv->numReadyWork == 0 ) 1.199 + { protoLangEnv->numReadyWork -= 1; 1.200 + if( protoLangEnv->numReadyWork == 0 ) 1.201 { process->numEnvsWithWork -= 1; 1.202 } 1.203 goto ReturnAfterAssigningWork; //quit for-loop, 'cause found work 1.204 @@ -260,6 +276,124 @@ 1.205 } 1.206 1.207 1.208 +//================================= 1.209 +//=== 1.210 +//= 1.211 +/*Create task is a special form, that has PR behavior in addition to plugin 1.212 + * behavior. Master calls this first, and it then calls the plugin's 1.213 + * create task handler. 1.214 + * 1.215 + *Note: the requesting slave must be either generic slave or free task slave 1.216 + */ 1.217 +inline 1.218 +void 1.219 +PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ) 1.220 + { PRMetaTask *protoMetaTask; 1.221 + PRProcess *process; 1.222 + PRLangEnv *protoLangEnv; 1.223 + void *task; 1.224 + 1.225 + process = slave->processSlaveIsIn; 1.226 + 1.227 + protoLangEnv = PR_int__give_proto_lang_env_for_slave( slave, 1.228 + req->langMagicNumber ); 1.229 + 1.230 + //Do the langlet's create-task handler, which keeps the task 1.231 + // inside the langlet's lang env, but returns the langMetaTask 1.232 + // so that PR can then put stuff into the prolog 1.233 + //typedef void * (*CreateHandler)( void *, SlaveVP *, void * ); //req, slv, langEnv 1.234 + // 1.235 + task = 1.236 + (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv) ); 1.237 + protoMetaTask = PR_int__give_prolog_of_lang_meta_task( task ); 1.238 + protoMetaTask->ID = req->ID; //may be NULL 1.239 + protoMetaTask->topLevelFn = req->topLevelFn; 1.240 + protoMetaTask->initData = req->initData; 1.241 + protoMetaTask->processTaskIsIn = process; 1.242 + 1.243 + process->numLiveTasks += 1; 1.244 + protoLangEnv->numLiveWork += 1; //used in wait statements -- small added overhead 1.245 + 1.246 + return; 1.247 + } 1.248 + 1.249 +/*When a task ends, have two scenarios: 1) task ran to completion, or 2) task 1.250 + * has been suspended at some point in its code. 1.251 + *For 1, just decr count of live tasks (and check for end condition) -- the 1.252 + * master loop will decide what goes into the slot freed up by this task end, 1.253 + * so, here, don't worry about assigning a new task to the slot slave. 1.254 + *For 2, the task's slot slave has been converted to a free task slave, which 1.255 + * now has nothing more to do, so send it to the recycle Q (which includes 1.256 + * freeing all the langData and meta task structs alloc'd for it). Then 1.257 + * decrement the live task count and check end condition. 1.258 + * 1.259 + *PR has to update count of live tasks, and check end of process condition. 1.260 + * The "main" can invoke constructs that wait for a process to end, so when 1.261 + * end detected, have to resume what's waiting.. 1.262 + *Thing is, that wait involves the main OS thread. That means 1.263 + * PR internals have to do OS thread signaling. Want to do that in the 1.264 + * core controller, which has the original stack of an OS thread. So the 1.265 + * end process handling happens in the core controller. 1.266 + * 1.267 + *So here, when detect process end, signal to the core controller, which will 1.268 + * then do the condition variable notify to the OS thread that's waiting. 1.269 + * 1.270 + *Note: slave may be either a slot slave or a free task slave. 1.271 + */ 1.272 +inline 1.273 +void 1.274 +PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv ) 1.275 + { void *langEnv; 1.276 + PRLangEnv *protoLangEnv; 1.277 + PRProcess *process; 1.278 + void *langMetaTask; 1.279 + 1.280 + process = requestingSlv->processSlaveIsIn; 1.281 + langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req 1.282 + protoLangEnv = PR_int__give_proto_lang_env( langEnv ); 1.283 + 1.284 + langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber); 1.285 + 1.286 + //Do the langlet's request handler 1.287 + //Want to keep PR structs hidden from plugin, so extract langReq.. 1.288 + //This is supposed to free any langlet-malloc'd mem, including meta task 1.289 + (*req->handler)( req->langReq, requestingSlv, langEnv ); 1.290 + 1.291 + protoLangEnv->numLiveWork -= 1; //used in wait statements -- small added overhead 1.292 + if( protoLangEnv->numLiveWork == 0 && 1.293 + numInPrivQ( protoLangEnv->waitingForWorkToEndQ ) > 0 ) 1.294 + { SlaveVP * 1.295 + waitingSlave = readPrivQ( protoLangEnv->waitingForWorkToEndQ ); 1.296 + //can't resume into langlet that just ended its last work! 1.297 + // and don't have env that the waiter was created in, so resume 1.298 + // into PRServ env.. 1.299 + void * 1.300 + resumeEnv = PR_PI__give_lang_env_from_process( process, PRServ_MAGIC_NUMBER ); 1.301 + while( waitingSlave != NULL ) 1.302 + { //resume a slave that was waiting for work in this env to finish 1.303 + PR_PI__make_slave_ready( waitingSlave, resumeEnv ); 1.304 + //get next waiting slave, repeat.. 1.305 + waitingSlave = readPrivQ( protoLangEnv->waitingForWorkToEndQ ); 1.306 + } 1.307 + } 1.308 + 1.309 + 1.310 + //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv 1.311 + if( requestingSlv->typeOfVP == FreeTaskSlv ) 1.312 + PR_int__recycle_slaveVP( requestingSlv ); //Doesn't decr num live slaves 1.313 + 1.314 + process->numLiveTasks -= 1; 1.315 + //NOTE: end-task is unrelated to work available (just in case wondering) 1.316 + 1.317 + //check End Of Process Condition 1.318 + if( process->numLiveTasks == 0 && 1.319 + process->numLiveGenericSlvs == 0 ) 1.320 + { //Tell the core controller to do wakeup of any waiting OS thread 1.321 + PR_SS__end_process_normally( process ); 1.322 + } 1.323 + } 1.324 + 1.325 + 1.326 1.327 /*This is first thing called when creating a slave.. it hands off to the 1.328 * langlet's creator, then adds updates of its own.. 1.329 @@ -293,7 +427,7 @@ 1.330 PRLangEnv *protoLangEnv; 1.331 1.332 process = slave->processSlaveIsIn; 1.333 - protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber ); 1.334 + protoLangEnv = PR_int__give_proto_lang_env_for_slave( slave, req->langMagicNumber ); 1.335 1.336 //create handler, or a future request handler will call PR_PI__make_slave_ready 1.337 // which will in turn handle updating which langlets and which processes have 1.338 @@ -306,6 +440,7 @@ 1.339 newSlv->processSlaveIsIn = process; 1.340 newSlv->ID = req->ID; 1.341 process->numLiveGenericSlvs += 1; //not same as work ready! 1.342 + protoLangEnv->numLiveWork += 1; //used in wait statements -- small added overhead 1.343 } 1.344 1.345 /*The dissipate handler has to, update the number of slaves of the type, within 1.346 @@ -327,105 +462,60 @@ 1.347 process = slave->processSlaveIsIn; 1.348 1.349 //do the language's dissipate handler 1.350 - protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, slave->request->langMagicNumber ); 1.351 + protoLangEnv = PR_int__give_proto_lang_env_for_slave( slave, slave->request->langMagicNumber ); 1.352 1.353 if(req->handler != NULL) 1.354 (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) ); 1.355 1.356 + protoLangEnv->numLiveWork -= 1; //used in wait statements -- small added overhead 1.357 + if( protoLangEnv->numLiveWork == 0 && 1.358 + numInPrivQ( protoLangEnv->waitingForWorkToEndQ ) > 0 ) 1.359 + { SlaveVP * 1.360 + waitingSlave = readPrivQ( protoLangEnv->waitingForWorkToEndQ ); 1.361 + //can't resume into langlet that just ended its last work! 1.362 + // and don't have env that the waiter was created in, so resume 1.363 + // into PRServ env.. 1.364 + void * 1.365 + resumeEnv = PR_PI__give_lang_env_from_process( process, PRServ_MAGIC_NUMBER ); 1.366 + while( waitingSlave != NULL ) 1.367 + { //resume a slave that was waiting for work in this env to finish 1.368 + PR_PI__make_slave_ready( waitingSlave, resumeEnv ); 1.369 + //get next waiting slave, repeat.. 1.370 + waitingSlave = readPrivQ( protoLangEnv->waitingForWorkToEndQ ); 1.371 + } 1.372 + } 1.373 + 1.374 process->numLiveGenericSlvs -= 1; 1.375 - PR_int__recycle_slave( slave ); 1.376 + PR_int__recycle_slaveVP( slave ); 1.377 //NOTE: dissipate is unrelated to work available (just in case wondering) 1.378 1.379 //check End Of Process Condition 1.380 if( process->numLiveTasks == 0 && 1.381 process->numLiveGenericSlvs == 0 ) 1.382 - PR_SS__shutdown_process( process ); 1.383 + PR_SS__end_process_normally( process ); 1.384 } 1.385 1.386 -/*Create task is a special form, that has PR behavior in addition to plugin 1.387 - * behavior. Master calls this first, and it then calls the plugin's 1.388 - * create task handler. 1.389 - * 1.390 - *Note: the requesting slave must be either generic slave or free task slave 1.391 +//======================= 1.392 +//=== 1.393 +//= 1.394 +/*Langlet shutdown triggers this, which calls the registered shutdown 1.395 + * handler for the langlet, and removes the lang's env from the process 1.396 */ 1.397 inline 1.398 void 1.399 -PRHandle__CreateTask( PRReqst *req, SlaveVP *slave ) 1.400 - { PRMetaTask *metaTask; 1.401 - PRProcess *process; 1.402 - PRLangEnv *protoLangEnv; 1.403 - void *task; 1.404 - 1.405 - process = slave->processSlaveIsIn; 1.406 +PRHandle__LangShutdown( PRReqst *req, SlaveVP *requestingSlv ) 1.407 + { void *langEnv; 1.408 + PRLangEnv *protoLangEnv; 1.409 + PRProcess *process; 1.410 1.411 - protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, 1.412 - req->langMagicNumber ); 1.413 + process = requestingSlv->processSlaveIsIn; 1.414 + protoLangEnv = PR_int__give_proto_lang_env_from_process( process, req->langMagicNumber ); 1.415 + langEnv = PR_int__give_lang_env( protoLangEnv ); 1.416 1.417 - //Do the langlet's create-task handler, which keeps the task 1.418 - // inside the langlet's lang env, but returns the langMetaTask 1.419 - // so PR can put stuff into the prolog 1.420 - task = 1.421 - (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv) ); 1.422 - metaTask = PR_int__give_prolog_of_task( task ); 1.423 - metaTask->ID = req->ID; //may be NULL 1.424 - metaTask->topLevelFn = req->topLevelFn; 1.425 - metaTask->initData = req->initData; 1.426 - 1.427 - process->numLiveTasks += 1; 1.428 - 1.429 - return; 1.430 - } 1.431 - 1.432 -/*When a task ends, have two scenarios: 1) task ran to completion, or 2) task 1.433 - * has been suspended at some point in its code. 1.434 - *For 1, just decr count of live tasks (and check for end condition) -- the 1.435 - * master loop will decide what goes into the slot freed up by this task end, 1.436 - * so, here, don't worry about assigning a new task to the slot slave. 1.437 - *For 2, the task's slot slave has been converted to a free task slave, which 1.438 - * now has nothing more to do, so send it to the recycle Q (which includes 1.439 - * freeing all the langData and meta task structs alloc'd for it). Then 1.440 - * decrement the live task count and check end condition. 1.441 - * 1.442 - *PR has to update count of live tasks, and check end of process condition. 1.443 - * The "main" can invoke constructs that wait for a process to end, so when 1.444 - * end detected, have to resume what's waiting.. 1.445 - *Thing is, that wait involves the main OS thread. That means 1.446 - * PR internals have to do OS thread signaling. Want to do that in the 1.447 - * core controller, which has the original stack of an OS thread. So the 1.448 - * end process handling happens in the core controller. 1.449 - * 1.450 - *So here, when detect process end, signal to the core controller, which will 1.451 - * then do the condition variable notify to the OS thread that's waiting. 1.452 - * 1.453 - *Note: slave may be either a slot slave or a free task slave. 1.454 - */ 1.455 -inline 1.456 -void 1.457 -PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv ) 1.458 - { void *langEnv; 1.459 - PRProcess *process; 1.460 - void *langMetaTask; 1.461 + //call the langlet's registered handler 1.462 + (*protoLangEnv->shutdownHdlr)( langEnv ); 1.463 1.464 - langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req 1.465 - langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber); 1.466 - 1.467 - //Do the langlet's request handler 1.468 - //Want to keep PR structs hidden from plugin, so extract langReq.. 1.469 - (*req->handler)( req->langReq, requestingSlv, langEnv ); 1.470 - 1.471 - //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv 1.472 - if( requestingSlv->typeOfVP == FreeTaskSlv ) 1.473 - PR_int__recycle_slave( requestingSlv ); //Doesn't decr num live slaves 1.474 - 1.475 - process->numLiveTasks -= 1; 1.476 - //NOTE: end-task is unrelated to work available (just in case wondering) 1.477 - 1.478 - //check End Of Process Condition 1.479 - if( process->numLiveTasks == 0 && 1.480 - process->numLiveGenericSlvs == 0 ) 1.481 - { //Tell the core controller to do wakeup of any waiting OS thread 1.482 - PR_SS__shutdown_process( process ); 1.483 - } 1.484 + PR_int__remove_lang_env_from_process_and_free( langEnv ); //removes from process and frees 1.485 } 1.486 1.487 1.488 @@ -438,24 +528,58 @@ 1.489 */ 1.490 void inline 1.491 PRHandle__ServiceReq( SlaveVP *requestingSlv ) 1.492 - { PRReqst *req; 1.493 - PRServReq *langReq; 1.494 - void *langEnv; 1.495 - int32 magicNumber; 1.496 + { PRReqst *req; 1.497 + PRServiceReq *langReq; 1.498 + PRLangEnv *protoLangEnv; 1.499 + int32 magicNumber; 1.500 1.501 1.502 req = requestingSlv->request; 1.503 1.504 magicNumber = req->langMagicNumber; 1.505 - langEnv = PR_PI__give_lang_env_for( slave, magicNumber ); 1.506 + protoLangEnv = PR_int__give_proto_lang_env_for_slave( requestingSlv, magicNumber ); 1.507 1.508 langReq = PR_PI__take_lang_reqst_from(req); 1.509 if( langReq == NULL ) return; 1.510 switch( langReq->reqType ) //lang handlers are all in other file 1.511 { 1.512 - case make_probe: handleMakeProbe( langReq, langEnv ); 1.513 + case make_probe: handleMakeProbe( langReq, protoLangEnv ); 1.514 break; 1.515 - case throw_excp: handleThrowException( langReq, langEnv ); 1.516 + case throw_excp: handleThrowException( langReq, protoLangEnv ); 1.517 break; 1.518 } 1.519 } 1.520 + 1.521 + 1.522 +/*These handlers are special -- they don't belong to a language, because they 1.523 + * deal with things internal to PR, so put them here.. 1.524 + */ 1.525 +inline 1.526 +void 1.527 +handleMakeProbe( PRServiceReq *langReq, PRLangEnv *protoLangEnv ) 1.528 + { IntervalProbe *newProbe; 1.529 + 1.530 + newProbe = PR_int__malloc( sizeof(IntervalProbe) ); 1.531 + newProbe->nameStr = PR_int__strDup( langReq->nameStr ); 1.532 + newProbe->hist = NULL; 1.533 + newProbe->schedChoiceWasRecorded = FALSE; 1.534 + 1.535 + //This runs in masterVP, so no race-condition worries 1.536 + //BUG: move to process 1.537 + newProbe->probeID = 1.538 + addToDynArray( newProbe, _PRTopEnv->dynIntervalProbesInfo ); 1.539 + 1.540 + langReq->requestingSlv->dataRetFromReq = newProbe; 1.541 + 1.542 + (*protoLangEnv->makeSlaveReadyFn)( langReq->requestingSlv, PR_int__give_lang_env(protoLangEnv) ); 1.543 + } 1.544 + 1.545 +inline 1.546 +void 1.547 +handleThrowException( PRServiceReq *langReq, PRLangEnv *protoLangEnv ) 1.548 + { 1.549 + PR_int__throw_exception( langReq->msgStr, langReq->requestingSlv, langReq->exceptionData ); 1.550 + 1.551 + (*protoLangEnv->makeSlaveReadyFn)( langReq->requestingSlv, PR_int__give_lang_env(protoLangEnv) ); 1.552 + } 1.553 +
