Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff AnimationMaster.c @ 267:608833ae2c5d
Checkpoint -- about to clean up AnimationMaster, deleting a bunch of stuff
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Sun, 04 Nov 2012 18:39:28 -0800 |
| parents | a5fa1e087c7e |
| children | e5bd470b562b |
line diff
1.1 --- a/AnimationMaster.c Thu Oct 25 23:35:36 2012 -0700 1.2 +++ b/AnimationMaster.c Sun Nov 04 18:39:28 2012 -0800 1.3 @@ -13,7 +13,7 @@ 1.4 #include "VSs_impl/VSs.h" 1.5 1.6 inline void 1.7 -replaceWithNewSlotSlv( SlaveVP *requestingSlv, PRProcessEnv *processEnv ); 1.8 +replaceWithNewSlotSlv( SlaveVP *slave ); 1.9 1.10 1.11 /*The animationMaster embodies most of the animator of the language. The 1.12 @@ -189,13 +189,13 @@ 1.13 if( currSlot->workIsDone ) 1.14 { 1.15 currSlot->workIsDone = FALSE; 1.16 - currSlot->needsSlaveAssigned = TRUE; 1.17 + currSlot->needsWorkAssigned = TRUE; 1.18 1.19 HOLISTIC__Record_AppResponder_start; 1.20 MEAS__startReqHdlr; 1.21 1.22 currSlot->workIsDone = FALSE; 1.23 - currSlot->needsSlaveAssigned = TRUE; 1.24 + currSlot->needsWorkAssigned = TRUE; 1.25 SlaveVP *currSlave = currSlot->slaveAssignedToSlot; 1.26 1.27 justAddedReqHdlrChg(); 1.28 @@ -223,7 +223,7 @@ 1.29 MEAS__endReqHdlr; 1.30 } 1.31 //If slot empty, hand to Assigner to fill with a slave 1.32 - if( currSlot->needsSlaveAssigned ) 1.33 + if( currSlot->needsWorkAssigned ) 1.34 { //Call plugin's Assigner to give slot a new slave 1.35 HOLISTIC__Record_Assigner_start; 1.36 assignedSlaveVP = 1.37 @@ -233,7 +233,7 @@ 1.38 if( assignedSlaveVP != NULL ) 1.39 { currSlot->slaveAssignedToSlot = assignedSlaveVP; 1.40 assignedSlaveVP->animSlotAssignedTo = currSlot; 1.41 - currSlot->needsSlaveAssigned = FALSE; 1.42 + currSlot->needsWorkAssigned = FALSE; 1.43 numSlotsFilled += 1; 1.44 1.45 HOLISTIC__Record_Assigner_end; 1.46 @@ -270,7 +270,6 @@ 1.47 //#ifdef MODE__MULTI_LANG 1.48 SlaveVP *slave; 1.49 PRProcess *process; 1.50 - PRConstrEnvHolder *constrEnvHolder; 1.51 int32 langMagicNumber; 1.52 //#endif 1.53 1.54 @@ -318,15 +317,15 @@ 1.55 slave = currSlot->slaveAssignedToSlot; 1.56 1.57 //check if the completed work was a task.. 1.58 - if( slave->taskMetaInfo->isATask ) 1.59 + if( slave->metaTask->isATask ) 1.60 { 1.61 - if( slave->reqst->type == TaskEnd ) 1.62 + if( slave->request->type == TaskEnd ) 1.63 { //do task end handler, which is registered separately 1.64 //note, end hdlr may use semantic data from reqst.. 1.65 //#ifdef MODE__MULTI_LANG 1.66 //get end-task handler 1.67 //taskEndHandler = lookup( slave->reqst->langMagicNumber, processEnv ); 1.68 - taskEndHandler = slave->taskMetaInfo->endTaskHandler; 1.69 + taskEndHandler = slave->metaTask->endTaskHandler; 1.70 //#endif 1.71 (*taskEndHandler)( slave, semanticEnv ); 1.72 1.73 @@ -353,7 +352,7 @@ 1.74 } //if has suspended slave that needs handling 1.75 1.76 //if slot empty, hand to Assigner to fill with a slave 1.77 - if( currSlot->needsSlaveAssigned ) 1.78 + if( currSlot->needsWorkAssigned ) 1.79 { //Call plugin's Assigner to give slot a new slave 1.80 HOLISTIC__Record_Assigner_start; 1.81 1.82 @@ -365,12 +364,12 @@ 1.83 if( assignedSlaveVP != NULL ) 1.84 { currSlot->slaveAssignedToSlot = assignedSlaveVP; 1.85 assignedSlaveVP->animSlotAssignedTo = currSlot; 1.86 - currSlot->needsSlaveAssigned = FALSE; 1.87 + currSlot->needsWorkAssigned = FALSE; 1.88 numSlotsFilled += 1; 1.89 } 1.90 else 1.91 { 1.92 - currSlot->needsSlaveAssigned = TRUE; //local write 1.93 + currSlot->needsWorkAssigned = TRUE; //local write 1.94 } 1.95 HOLISTIC__Record_Assigner_end; 1.96 }//if slot needs slave assigned 1.97 @@ -496,7 +495,6 @@ 1.98 //#ifdef MODE__MULTI_LANG 1.99 SlaveVP *slave; 1.100 PRProcess *process; 1.101 - PRConstrEnvHolder *constrEnvHolder; 1.102 int32 langMagicNumber; 1.103 //#endif 1.104 1.105 @@ -579,7 +577,7 @@ 1.106 } //if has suspended slave that needs handling 1.107 1.108 //if slot empty, hand to Assigner to fill with a slave 1.109 - if( currSlot->needsSlaveAssigned ) 1.110 + if( currSlot->needsWorkAssigned ) 1.111 { //Call plugin's Assigner to give slot a new slave 1.112 HOLISTIC__Record_Assigner_start; 1.113 1.114 @@ -591,12 +589,12 @@ 1.115 if( assignedSlaveVP != NULL ) 1.116 { currSlot->slaveAssignedToSlot = assignedSlaveVP; 1.117 assignedSlaveVP->animSlotAssignedTo = currSlot; 1.118 - currSlot->needsSlaveAssigned = FALSE; 1.119 + currSlot->needsWorkAssigned = FALSE; 1.120 numSlotsFilled += 1; 1.121 } 1.122 else 1.123 { 1.124 - currSlot->needsSlaveAssigned = TRUE; //local write 1.125 + currSlot->needsWorkAssigned = TRUE; //local write 1.126 } 1.127 HOLISTIC__Record_Assigner_end; 1.128 }//if slot needs slave assigned 1.129 @@ -618,7 +616,6 @@ 1.130 void animationMaster( void *initData, SlaveVP *masterVP ) 1.131 { 1.132 int32 slotIdx; 1.133 -// int32 numSlotsFilled; 1.134 AnimSlot *currSlot; 1.135 //Used while scanning and filling animation slots 1.136 AnimSlot **animSlots; 1.137 @@ -661,6 +658,77 @@ 1.138 #endif //MODE__MULTI_LANG 1.139 #endif //MODE__MULTI_PROCESS 1.140 1.141 + 1.142 +//This version of the master selects one of three loops, depending upon 1.143 +// whether stand-alone single language (just slaves), or standalone with 1.144 +// tasks, or multi-lang (implies multi-process) 1.145 +void animationMaster( void *initData, SlaveVP *masterVP ) 1.146 + { 1.147 + int32 slotIdx; 1.148 + AnimSlot *currSlot; 1.149 + //Used while scanning and filling animation slots 1.150 + AnimSlot **animSlots; 1.151 + 1.152 + //Local copies, for performance 1.153 + MasterEnv *masterEnv; 1.154 + int32 thisCoresIdx; 1.155 + 1.156 + //======================== Initializations ======================== 1.157 + masterEnv = (MasterEnv*)_PRTopEnv; 1.158 + 1.159 + thisCoresIdx = masterVP->coreAnimatedBy; 1.160 + animSlots = masterEnv->allAnimSlots[thisCoresIdx]; 1.161 + 1.162 + HOLISTIC__Insert_Master_Global_Vars; 1.163 + 1.164 + //======================== animationMaster ======================== 1.165 + //Have three different modes, and the master behavior is different for 1.166 + // each, so jump to the loop that corresponds to the mode. 1.167 + // 1.168 + switch(mode) 1.169 + { case StandaloneSlavesOnly: 1.170 + while(1) 1.171 + { MEAS__Capture_Pre_Master_Point 1.172 + for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++) 1.173 + { 1.174 + currSlot = animSlots[ slotIdx ]; 1.175 + 1.176 + masterFunction_StandaloneSlavesOnly( currSlot ); 1.177 + } 1.178 + MEAS__Capture_Post_Master_Point; 1.179 + masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master 1.180 + flushRegisters(); 1.181 + } 1.182 + case StandaloneWTasks: 1.183 + while(1) 1.184 + { MEAS__Capture_Pre_Master_Point 1.185 + for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++) 1.186 + { 1.187 + currSlot = animSlots[ slotIdx ]; 1.188 + 1.189 + masterFunction_StandaloneWTasks( currSlot ); 1.190 + } 1.191 + MEAS__Capture_Post_Master_Point; 1.192 + masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master 1.193 + flushRegisters(); 1.194 + } 1.195 + case MultiLang: 1.196 + while(1) 1.197 + { MEAS__Capture_Pre_Master_Point 1.198 + for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++) 1.199 + { 1.200 + currSlot = animSlots[ slotIdx ]; 1.201 + 1.202 + masterFunction_multiLang( currSlot ); 1.203 + } 1.204 + MEAS__Capture_Post_Master_Point; 1.205 + masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master 1.206 + flushRegisters(); 1.207 + } 1.208 + } 1.209 + } 1.210 + 1.211 + 1.212 inline 1.213 void 1.214 masterFunction_multiLang( AnimSlot *currSlot ) 1.215 @@ -675,6 +743,7 @@ 1.216 //Check if newly-done slave in slot, which will need request handled 1.217 if( currSlot->workIsDone ) 1.218 { currSlot->workIsDone = FALSE; 1.219 + currSlot->needsWorkAssigned = TRUE; 1.220 1.221 HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot 1.222 MEAS__startReqHdlr; 1.223 @@ -682,94 +751,56 @@ 1.224 1.225 //process the request made by the slave (held inside slave struc) 1.226 slave = currSlot->slaveAssignedToSlot; 1.227 - 1.228 - //check if the slave was doing a task.. 1.229 - //Action depends on both on the request type, and whether it's on 1.230 - // a generic slave vs a suspended task 1.231 - if( slave->metaTask->taskType == AtomicTask || 1.232 - slave->metaTask->taskType == SuspendedTask ) 1.233 - { 1.234 - switch( slave->request->reqType ) 1.235 - { case TaskEnd: 1.236 - { PRHandle_EndTask( slave ); //if free task slave, update count, put into recycle Q -- do handler before lang's handler 1.237 + req = slave->request; 1.238 1.239 - //do task end handler, which is registered separately 1.240 - //note, end hdlr may use semantic data from reqst.. 1.241 - //get end-task handler 1.242 + //If the requesting slave is a slot slave, and request is not 1.243 + // task-end, then turn it into a free task slave. 1.244 + if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd ) 1.245 + replaceWithNewSlotSlv( slave ); 1.246 1.247 - RequestHandler 1.248 - taskEndHandler = slave->request->handler; 1.249 - semanticEnv = PR_int__give_sem_env_for_slave( slave, 1.250 - slave->request->langMagicNumber ); 1.251 - (*taskEndHandler)( slave, semanticEnv ); 1.252 + //Handle task create and end first -- they're special cases.. 1.253 + switch( req->reqType ) 1.254 + { case TaskEnd: 1.255 + { //do PR handler, which calls lang's hdlr and does recycle of 1.256 + // free task slave if needed -- PR handler checks for free task Slv 1.257 + PRHandle_EndTask( slave ); break; 1.258 + } 1.259 + case TaskCreate: 1.260 + { //Do PR's create-task handler, which calls the lang's hdlr 1.261 + // PR handler checks for free task Slv 1.262 + PRHandle_CreateTask( slave ); break; 1.263 + } 1.264 + case SlvCreate: PRHandle_CreateSlave( slave ); break; 1.265 + case SlvDissipate: PRHandle_Dissipate( slave ); break; 1.266 + case Service: PR_int__handle_PRServiceReq( slave ); break; //resume into PR's own semantic env 1.267 + case Hardware: //for future expansion 1.268 + case IO: //for future expansion 1.269 + case OSCall: //for future expansion 1.270 + PR_int__throw_exception("Not implemented"); break; 1.271 + case Language: //normal sem request 1.272 + magicNumber = req->langMagicNumber; 1.273 + semanticEnv = PR_PI__give_sem_env_for( slave, magicNumber ); 1.274 + requestHandler = semanticEnv->requestHdlr; 1.275 + (*requestHandler)( req->semReq, slave, semanticEnv ); 1.276 + } 1.277 1.278 - goto AssignWork; 1.279 - } 1.280 - case TaskCreate: 1.281 - { PRHandle_CreateTask( slave ); 1.282 - RequestHandler 1.283 - taskCreateHandler = slave->request->handler; 1.284 - semanticEnv = PR_int__give_sem_env_for_slave( slave, 1.285 - slave->request->langMagicNumber ); 1.286 - (*taskCreateHandler)( slave, semanticEnv ); //resumes creating slave 1.287 - goto AssignWork; 1.288 - } 1.289 - default: 1.290 - { //is a task, and just suspended, so tied to a free task slave 1.291 - //First turn slot slave into free task slave & make replacement 1.292 - if( slave->typeOfVP == SlotTaskSlv ) 1.293 - replaceWithNewSlotSlv( slave, slave->processSlaveIsIn->processEnv ); 1.294 - 1.295 - //goto normal slave request handling 1.296 - goto SlaveReqHandling; 1.297 - } 1.298 - } 1.299 - } 1.300 - else //is a slave that suspended 1.301 - { 1.302 - 1.303 - SlaveReqHandling: 1.304 - //Q: put the switch in inline call, to clean up code? 1.305 - req = slave->request; 1.306 - switch( req->reqType ) 1.307 - { case SlvCreate: PRHandle_CreateSlave( slave ); break; 1.308 - case SlvDissipate: PRHandle_Dissipate( slave ); break; 1.309 - case Service: PR_int__handle_PRServiceReq( slave ); break; //resume into PR's own semantic env 1.310 - case Hardware: //for future expansion 1.311 - case IO: //for future expansion 1.312 - case OSCall: //for future expansion 1.313 - case Language: //normal sem request 1.314 - magicNumber = slave->request->langMagicNumber; 1.315 - semanticEnv = PR_PI__give_sem_env_for( slave, magicNumber ); 1.316 - requestHandler = semanticEnv->requestHdlr; 1.317 - (*requestHandler)( slave, semanticEnv ); //(note: indirect Fn call more efficient when use fewer params, instead re-fetch from slave) 1.318 - } 1.319 - 1.320 - HOLISTIC__Record_AppResponder_end; 1.321 - MEAS__endReqHdlr; 1.322 - 1.323 - goto AssignWork; 1.324 - } 1.325 - } //if has suspended slave that needs handling 1.326 + HOLISTIC__Record_AppResponder_end; 1.327 + MEAS__endReqHdlr; 1.328 + } //if have request to be handled 1.329 1.330 - //End up here when the slot did not have ended work in it (no req) 1.331 - //So, here, if slot empty, look for work to fill the slot 1.332 - if( currSlot->needsSlaveAssigned ) 1.333 - { HOLISTIC__Record_Assigner_start; 1.334 - 1.335 - AssignWork: 1.336 + if( currSlot->needsWorkAssigned ) 1.337 + { 1.338 + HOLISTIC__Record_Assigner_start; 1.339 + 1.340 //Scan sem environs, looking for semEnv with ready work. 1.341 // call the Assigner for that sem Env, to get a slave for the slot 1.342 assignedSlaveVP = assignWork( semanticEnv, currSlot ); 1.343 1.344 - //put the chosen slave into slot, and adjust flags and state 1.345 + //if work found, put into slot, and adjust flags and state 1.346 if( assignedSlaveVP != NULL ) 1.347 { currSlot->slaveAssignedToSlot = assignedSlaveVP; 1.348 assignedSlaveVP->animSlotAssignedTo = currSlot; 1.349 - currSlot->needsSlaveAssigned = FALSE; 1.350 - } 1.351 - else 1.352 - { currSlot->needsSlaveAssigned = TRUE; //local write 1.353 + currSlot->needsWorkAssigned = FALSE; 1.354 } 1.355 HOLISTIC__Record_Assigner_end; 1.356 }//if slot needs slave assigned 1.357 @@ -786,6 +817,9 @@ 1.358 replaceWithNewSlotSlv( SlaveVP *requestingSlv, PRProcess *process ) 1.359 { SlaveVP *newSlotSlv; 1.360 1.361 + When slot slave converted to a free task slave, insert the process pointer -- slot slaves are not assigned to any process; 1.362 + when convert from slot slave to free task slave, check what should do about num (live slaves + live tasks) inside VSs's task stub, and properly update process's count of liveFreeTaskSlaves 1.363 + 1.364 //get a new slave to be the slot slave 1.365 newSlotSlv = readPrivQ( process->freeTaskSlvRecycleQ ); 1.366 if( newSlotSlv == NULL ) 1.367 @@ -797,7 +831,7 @@ 1.368 //set slave values to make it the slot slave 1.369 newSlotSlv->metaTask = NULL; 1.370 newSlotSlv->typeOfVP = SlotTaskSlv; 1.371 - newSlotSlv->needsTaskAssigned = TRUE; 1.372 +// newSlotSlv->needsTaskAssigned = TRUE; 1.373 1.374 //a slot slave is pinned to a particular slot on a particular core 1.375 //Note, this happens before the request is seen by handler, so nothing 1.376 @@ -813,7 +847,7 @@ 1.377 //Fix up requester, to be an extra slave now (but not an ended one) 1.378 // because it's active, doesn't go into freeTaskSlvRecycleQ 1.379 requestingSlv->typeOfVP = FreeTaskSlv; 1.380 - check_if_need_to_change_metaTask_type_or_something; 1.381 + requestingSlv->metaTask->taskType = FreeTask; 1.382 } 1.383 1.384 1.385 @@ -841,30 +875,33 @@ 1.386 inline SlaveVP * 1.387 assignWork( PRProcess *process, AnimSlot *slot ) 1.388 { SlaveVP *returnSlv; 1.389 - //VSsSemEnv *semEnv; 1.390 - //VSsSemData *semData; 1.391 int32 coreNum, slotNum; 1.392 - PRMetaTask *newMetaTask, *assignedMetaTask; 1.393 - SlaveVP *freeTaskSlv; 1.394 + PRMetaTask *assignedMetaTask; 1.395 1.396 coreNum = slot->coreSlotIsOn; 1.397 1.398 - if( _PRTopEnv->overrideAssigner != NULL ) 1.399 - { assignedMetaTask = (*_PRTopEnv->overrideAssigner)( process, slot ); 1.400 + if( process->overrideAssigner != NULL ) 1.401 + { assignedMetaTask = (*process->overrideAssigner)( process, slot ); 1.402 if( assignedMetaTask != NULL ) 1.403 { 1.404 //have work, so reset Done flag (caused by work generated on other core) 1.405 - if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf 1.406 - process->coreIsDone[coreNum] = FALSE; //don't just write always 1.407 +// if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf 1.408 +// process->coreIsDone[coreNum] = FALSE; //don't just write always 1.409 1.410 - switch( assignedMetaTask->taskType ) 1.411 - { case GenericSlave: goto AssignSlave; 1.412 - case SuspendedTask: goto AssignSlave; 1.413 - case AtomicTask: goto AssignNewTask; 1.414 - default: PR_int__throw_exception( "unknown task type ret by assigner" ); 1.415 - } 1.416 +// switch( assignedMetaTask->taskType ) 1.417 +// { case GenericSlave: goto AssignSlave; 1.418 +// case FreeTask: goto AssignSlave; 1.419 +// case SlotTask: goto AssignNewTask; 1.420 +// default: PR_int__throw_exception( "unknown task type ret by assigner" ); 1.421 +// } 1.422 + //If meta task has a slave attached, then goto assign slave, 1.423 + // else it's a new task, so goto where assign it to a slot slave 1.424 + if( assignedMetaTask->slaveAssignedTo != NULL ) 1.425 + goto AssignSlave; 1.426 + else 1.427 + goto AssignNewTask; 1.428 } 1.429 - else 1.430 + else //metaTask is NULL, so no work.. 1.431 goto NoWork; 1.432 } 1.433 1.434 @@ -872,56 +909,60 @@ 1.435 int32 envIdx, numEnvs; PRSemEnv **semEnvs, *semEnv; SlaveAssigner assigner; 1.436 semEnvs = process->semEnvs; 1.437 numEnvs = process->numSemEnvs; 1.438 - for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep semEnvs in hash AND array 1.439 + for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep semEnvs in hash & array 1.440 { semEnv = semEnvs[envIdx]; 1.441 if( semEnv->hasWork ) 1.442 { assigner = semEnv->slaveAssigner; 1.443 assignedMetaTask = (*assigner)( semEnv, slot ); 1.444 1.445 //have work, so reset Done flag (caused by work generated on other core) 1.446 - if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf 1.447 - process->coreIsDone[coreNum] = FALSE; //don't just write always 1.448 +// if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf 1.449 +// process->coreIsDone[coreNum] = FALSE; //don't just write always 1.450 1.451 - switch( assignedMetaTask->taskType ) 1.452 - { case GenericSlave: goto AssignSlave; 1.453 - case SuspendedTask: goto AssignSlave; 1.454 - case AtomicTask: goto AssignNewTask; 1.455 - default: PR_int__throw_exception( "unknown task type ret by assigner" ); 1.456 - } 1.457 +// switch( assignedMetaTask->taskType ) 1.458 +// { case GenericSlave: goto AssignSlave; 1.459 +// case FreeTask: goto AssignSlave; 1.460 +// case SlotTask: goto AssignNewTask; 1.461 +// default: PR_int__throw_exception( "unknown task type ret by assigner" ); 1.462 +// } 1.463 + //If meta task has a slave attached, then goto assign slave, 1.464 + // else it's a new task, so goto where assign it to a slot slave 1.465 + if( assignedMetaTask->slaveAssignedTo != NULL ) 1.466 + goto AssignSlave; 1.467 + else 1.468 + goto AssignNewTask; 1.469 } 1.470 } 1.471 + //If reach here, then have searched all semEnv's & none have work.. 1.472 1.473 NoWork: 1.474 //No work, if reach here.. 1.475 { goto ReturnTheSlv; 1.476 } 1.477 1.478 - AssignSlave: //Have a metaTask attached to a slave, so get the slave out 1.479 - { //get slave pointed to by meta task. 1.480 - returnSlv = assignedMetaTask->slaveAssignedTo; 1.481 - 1.482 + AssignSlave: //Have a metaTask attached to a slave, so get the slave & ret it 1.483 + { returnSlv = assignedMetaTask->slaveAssignedTo; 1.484 returnSlv->coreAnimatedBy = coreNum; 1.485 1.486 goto ReturnTheSlv; 1.487 } 1.488 1.489 - AssignNewTask: 1.490 + AssignNewTask: //Have a new metaTask that has no slave yet.. assign to slot slv 1.491 { 1.492 //get the slot slave to assign the task to.. 1.493 - coreNum = slot->coreSlotIsOn; 1.494 slotNum = slot->slotIdx; 1.495 returnSlv = process->slotTaskSlvs[coreNum][slotNum]; 1.496 1.497 - //point slave to task's function, and mark slave as having task 1.498 + //point slave to task's function 1.499 PR_int__reset_slaveVP_to_TopLvlFn( returnSlv, 1.500 assignedMetaTask->topLevelFn, assignedMetaTask->initData ); 1.501 - returnSlv->metaTask = assignedMetaTask; 1.502 + returnSlv->metaTask = assignedMetaTask; 1.503 assignedMetaTask->slaveAssignedTo = returnSlv; 1.504 - returnSlv->needsTaskAssigned = FALSE; //slot slave is a "Task" slave type 1.505 +// returnSlv->needsTaskAssigned = FALSE; //slot slave is a "Task" slave type 1.506 1.507 //have work, so reset Done flag, if was set 1.508 - if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf 1.509 - process->coreIsDone[coreNum] = FALSE; //don't just write always 1.510 +// if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf 1.511 +// process->coreIsDone[coreNum] = FALSE; //don't just write always 1.512 1.513 goto ReturnTheSlv; 1.514 } 1.515 @@ -1005,12 +1046,12 @@ 1.516 process->numLiveGenericSlvs += 1; 1.517 metaTask = PR_int__create_slave_meta_task(); 1.518 metaTask->taskID = req->ID; 1.519 - metaTask->taskType = GenericSlave; 1.520 +// metaTask->taskType = GenericSlave; 1.521 1.522 - (*req->handler)(newSlv); 1.523 + (*req->handler)( req->semReq, newSlv, requestingSlv, semEnv ); 1.524 } 1.525 1.526 -/*The dissipate handler has to update the number of slaves of the type, within 1.527 +/*The dissipate handler has to, sdate the number of slaves of the type, within 1.528 * the process, and call the langlet handler linked into the request, 1.529 * and after that returns, then call the PR function that frees the slave state 1.530 * (or recycles the slave). 1.531 @@ -1027,52 +1068,53 @@ 1.532 process = slave->processSlaveIsIn; 1.533 1.534 //do the language's dissipate handler 1.535 - semEnv = PR_int__give_sem_env_for( slave, slave->request->langMagicNumber ); 1.536 - (*slave->request->handler)( slave, semEnv ); 1.537 + semEnv = PR_int__give_sem_env_for_slave( slave, slave->request->langMagicNumber ); 1.538 + (*slave->request->handler)( slave->request->semReq, slave, semEnv ); 1.539 1.540 process->numLiveGenericSlvs -= 1; 1.541 - PR_int__dissipate_slaveVP_multilang( slave ); //recycles and resets semDatas 1.542 - 1.543 + PR_int__recycle_slave_multilang( requestingSlv ); 1.544 + 1.545 //check End Of Process Condition 1.546 if( process->numLiveTasks == 0 && 1.547 process->numLiveGenericSlvs == 0 ) 1.548 - signalEndOfProcess; 1.549 + PR_SS__shutdown_process( process ); 1.550 } 1.551 1.552 /*Create task is a special form, that has PR behavior in addition to plugin 1.553 - * behavior. Master calls this first, and this in turn calls the plugin's 1.554 + * behavior. Master calls this first, and then calls the plugin's 1.555 * create task handler. 1.556 + * 1.557 + *Note: the requesting slave must be either generic slave or free task slave 1.558 */ 1.559 -inline void 1.560 -PRHandle_CreateTask( TopLevelFn topLevelFn, void *initData, PRReqst *req, 1.561 - SlaveVP *requestingSlv ) 1.562 - { PRMetaTask *metaTask; 1.563 - PRProcess *process; 1.564 - void *semEnv, _langMetaTask; 1.565 +inline PRMetaTask * 1.566 +PRHandle_CreateTask( PRReqst *req, SlaveVP *requestingSlv ) 1.567 + { PRMetaTask *metaTask; 1.568 + PRProcess *process; 1.569 PRLangMetaTask *langMetaTask; 1.570 - 1.571 + PRSemEnv *semanticEnv; 1.572 + 1.573 process = requestingSlv->processSlaveIsIn; 1.574 1.575 - metaTask = PR_int__create_meta_task( req ); 1.576 - metaTask->taskID = req->ID; //may be NULL 1.577 - metaTask->topLevelFn = topLevelFn; 1.578 - metaTask->initData = initData; 1.579 + metaTask = PR_int__create_meta_task( req ); 1.580 + metaTask->taskID = req->ID; //may be NULL 1.581 + metaTask->topLevelFn = req->topLevelFn; 1.582 + metaTask->initData = req->initData; 1.583 1.584 process->numLiveTasks += 1; 1.585 - 1.586 - //plugin tracks tasks ready, and has its own assigner, so task doesn't 1.587 - // come back from lang's handler -- it's consumed and stays in semEnv. 1.588 - //But handler gives back the language-specific meta-task it creates, and 1.589 - // then hook that into the PR meta-task 1.590 - //(Could also do PRMetaTask as a prolog -- make a Fn that takes the size 1.591 - // of the lang's metaTask, and alloc's that plus the prolog and returns 1.592 - // ptr to position just above the prolog) 1.593 - semEnv = PR_int__give_semEnv_of_req( req, requestingSlv ); //magic num in req 1.594 - _langMetaTask = (*requestingSlv->request->handler)(req, semEnv); 1.595 - langMetaTask = (PRLangMetaTask *)_langMetaTask; 1.596 + 1.597 + semanticEnv = PR_int__give_sem_env_for_slave( slave, 1.598 + req->langMagicNumber ); 1.599 + 1.600 + //Do the langlet's create-task handler, which keeps the task 1.601 + // inside the langlet's sem env, but returns the langMetaTask 1.602 + // so PR can hook it to the PRMetaTask. 1.603 + //(Could also do PRMetaTask as a prolog -- make a Fn that takes the size 1.604 + // of the lang's metaTask, and alloc's that plus the prolog and returns 1.605 + // ptr to position just above the prolog) 1.606 + langMetaTask = (*req->handler)(req->semReq, slave, semanticEnv); 1.607 metaTask->langMetaTask = langMetaTask; 1.608 langMetaTask->protoMetaTask = metaTask; 1.609 - 1.610 + 1.611 return; 1.612 } 1.613 1.614 @@ -1087,36 +1129,43 @@ 1.615 * decrement the live task count and check end condition. 1.616 * 1.617 *PR has to update count of live tasks, and check end of process condition. 1.618 - * There are constructs that wait for a process to end, so when end detected, 1.619 - * have to resume what's waiting.. 1.620 - *Thing is, the wait is used in "main", so it's an OS thread. That means 1.621 + * The "main" can invoke constructs that wait for a process to end, so when 1.622 + * end detected, have to resume what's waiting.. 1.623 + *Thing is, that wait involves the main OS thread. That means 1.624 * PR internals have to do OS thread signaling. Want to do that in the 1.625 - * core controller, which has the original stack of an OS thread. 1.626 + * core controller, which has the original stack of an OS thread. So the 1.627 + * end process handling happens in the core controller. 1.628 * 1.629 *So here, when detect process end, signal to the core controller, which will 1.630 - * then do the condition variable notify to the OS thread that's waiting. 1.631 + * then do the condition variable notify to the OS thread that's waiting. 1.632 + * 1.633 + *Note: slave may be either a slot slave or a free task slave. 1.634 */ 1.635 inline void 1.636 PRHandle_EndTask( SlaveVP *requestingSlv ) 1.637 - { void *semEnv; 1.638 - PRReqst *req; 1.639 - PRMetaTask *metaTask; 1.640 + { void *semEnv; 1.641 + PRReqst *req; 1.642 + PRLangMetaTask *langMetaTask; 1.643 PRProcess *process; 1.644 - 1.645 + 1.646 req = requestingSlv->request; 1.647 - semEnv = PR_int__give_semEnv_of_req( req, requestingSlv ); //magic num in req 1.648 - metaTask = req->metaTask; 1.649 - //Want to keep PRMetaTask hidden from plugin, so extract semReq.. 1.650 - (*req->handler)( metaTask, req->semReq, semEnv ); 1.651 + semEnv = PR_int__give_sem_env_of_req( req, requestingSlv ); //magic num in req 1.652 + langMetaTask = requestingSlv->metaTask->langMetaTask; 1.653 1.654 - recycleFreeTaskSlave( requestingSlv ); 1.655 + //Do the langlet's request handler 1.656 + //Want to keep PR structs hidden from plugin, so extract semReq.. 1.657 + (*req->handler)( langMetaTask, req->semReq, semEnv ); 1.658 + 1.659 + //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv 1.660 + if( requestingSlv->typeOfVP == FreeTaskSlv ) 1.661 + PR_int__recycle_slave_multilang( requestingSlv ); 1.662 1.663 process->numLiveTasks -= 1; 1.664 1.665 //check End Of Process Condition 1.666 if( process->numLiveTasks == 0 && 1.667 process->numLiveGenericSlvs == 0 ) 1.668 - signalEndOfProcessToCoreCtlr; 1.669 + //Tell the core controller to do wakeup of any waiting OS thread 1.670 + PR_SS__shutdown_process( process ); 1.671 } 1.672 1.673 - 1.674 \ No newline at end of file
