annotate 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
rev   line source
seanhalle@230 1 /*
seanhalle@270 2 * Copyright 2012 OpenSourceResearchInstitute.org
seanhalle@230 3 *
seanhalle@230 4 * Licensed under BSD
seanhalle@230 5 */
seanhalle@230 6
seanhalle@230 7
seanhalle@230 8
seanhalle@230 9 #include <stdio.h>
seanhalle@230 10 #include <stddef.h>
seanhalle@230 11
seanhalle@260 12 #include "PR.h"
seanhalle@261 13 #include "VSs_impl/VSs.h"
seanhalle@230 14
seanhalle@268 15 /*
seanhalle@268 16 void PRHandle_CreateTask_SL(SlaveVP *slave);
seanhalle@230 17
seanhalle@268 18 void PRHandle_CreateSlave_SL(SlaveVP *slave);
seanhalle@268 19 void PRHandle_Dissipate_SL(SlaveVP *slave);
seanhalle@268 20 void PR_int__handle_PRServiceReq_SL(SlaveVP *slave);
seanhalle@268 21 */
seanhalle@272 22 inline void PRHandle__CreateTask( PRReqst *req, SlaveVP *slave );
seanhalle@272 23 inline void PRHandle__EndTask( PRReqst *req, SlaveVP *slave );
seanhalle@272 24 inline void PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave );
seanhalle@272 25 void PRHandle__EndSlave( PRReqst *req, SlaveVP *slave );
seanhalle@268 26
seanhalle@268 27
seanhalle@268 28 //inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot );
seanhalle@268 29 inline PRProcess * pickAProcess( AnimSlot *slot );
seanhalle@270 30 inline bool32 assignWork( PRProcess *process, AnimSlot *slot );
seanhalle@230 31
seanhalle@272 32
seanhalle@272 33 /*Note: there used to be a coreController that was another animation
seanhalle@272 34 * layer below both the masterVP and the slaveVPs.. in that case, the
seanhalle@272 35 * masterVP was a virtual processor whose processor-state was the same
seanhalle@272 36 * as a slaveVP's processor sate, both implemented as a SlaveVP struct.
seanhalle@272 37 * Have removed that, and
seanhalle@272 38 * changed the masterVP implementation. Instead of being a special version
seanhalle@272 39 * of a proto-runtime virtual processor, using the slaveVP stuct, the
seanhalle@272 40 * Master "virtual processor" is now implemented as a pthread pinned to
seanhalle@272 41 * a physical core.
seanhalle@260 42 */
seanhalle@260 43
seanhalle@272 44 /*This is the behavior of the Master. The physical processor switches
seanhalle@272 45 * between animating the master, and animating a slave. When a slave
seanhalle@272 46 * suspends, the PR "suspend" primitive switches the physical core over
seanhalle@272 47 * to animating the masterVP, which is implemented as a pinned pthread.
seanhalle@272 48 * This function is the behavior of that masterVP.
seanhalle@272 49 *This function's job is to manage processing
seanhalle@272 50 * requests and to trigger assignment of new work to the physical core,
seanhalle@272 51 * and to manage sharing the core among processes.
seanhalle@272 52 */
seanhalle@261 53 inline
seanhalle@270 54 bool32
seanhalle@269 55 masterFunction( AnimSlot *slot )
seanhalle@261 56 { //Scan the animation slots
seanhalle@261 57 int32 magicNumber;
seanhalle@261 58 SlaveVP *slave;
seanhalle@268 59 PRLangEnv *langEnv;
seanhalle@261 60 PRReqst *req;
seanhalle@268 61 PRProcess *process;
seanhalle@270 62 bool32 foundWork;
seanhalle@260 63
seanhalle@268 64 //Check if newly-done slave in slot, which will need request handled
seanhalle@272 65 //NOTE: left over from when had a coreController & MasterVP managed
seanhalle@272 66 // several slots
seanhalle@268 67 if( slot->workIsDone )
seanhalle@268 68 { slot->workIsDone = FALSE;
seanhalle@268 69 slot->needsWorkAssigned = TRUE;
seanhalle@261 70
seanhalle@268 71 HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
seanhalle@268 72 MEAS__startReqHdlr;
seanhalle@261 73
seanhalle@268 74
seanhalle@268 75 //process the request made by the slave (held inside slave struc)
seanhalle@268 76 slave = slot->slaveAssignedToSlot;
seanhalle@268 77 req = slave->request;
seanhalle@268 78
seanhalle@268 79 //If the requesting slave is a slot slave, and request is not
seanhalle@268 80 // task-end, then turn it into a free task slave.
seanhalle@268 81 if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd )
seanhalle@268 82 PR_int__replace_with_new_slot_slv( slave );
seanhalle@268 83
seanhalle@268 84 //Handle task create and end first -- they're special cases..
seanhalle@268 85 switch( req->reqType )
seanhalle@268 86 { case TaskEnd:
seanhalle@268 87 { //do PR handler, which calls lang's hdlr and does recycle of
seanhalle@268 88 // free task slave if needed -- PR handler checks for free task Slv
seanhalle@272 89 PRHandle__EndTask( req, slave ); break;
seanhalle@267 90 }
seanhalle@268 91 case TaskCreate:
seanhalle@268 92 { //Do PR's create-task handler, which calls the lang's hdlr
seanhalle@268 93 // PR handler checks for free task Slv
seanhalle@272 94 PRHandle__CreateTask( req, slave ); break;
seanhalle@268 95 }
seanhalle@272 96 case SlvCreate: PRHandle__CreateSlave( req, slave ); break;
seanhalle@272 97 case SlvDissipate: PRHandle__EndSlave( req, slave ); break;
seanhalle@272 98 case Service: PRHandle__ServiceReq( slave ); break; //resumes into Service lang env
seanhalle@268 99 case Hardware: //for future expansion
seanhalle@268 100 case IO: //for future expansion
seanhalle@268 101 case OSCall: //for future expansion
seanhalle@268 102 PR_int__throw_exception("Not implemented", slave, NULL); break;
seanhalle@268 103 case Language: //normal lang request
seanhalle@268 104 { magicNumber = req->langMagicNumber;
seanhalle@268 105 langEnv = PR_PI__give_lang_env_for( slave, magicNumber );
seanhalle@268 106 (*req->handler)( req->langReq, slave, langEnv );
seanhalle@268 107 }
seanhalle@268 108 }
seanhalle@261 109
seanhalle@268 110 MEAS__endReqHdlr;
seanhalle@267 111 HOLISTIC__Record_AppResponder_end;
seanhalle@268 112 } //if have request to be handled
seanhalle@268 113
seanhalle@272 114 //NOTE: IF statement is leftover from when master managed many slots
seanhalle@272 115 foundWork = FALSE;
seanhalle@272 116 if( slot->needsWorkAssigned ) //can probably remove IF, not that only one slot
seanhalle@268 117 {
seanhalle@268 118 HOLISTIC__Record_Assigner_start;
seanhalle@272 119
seanhalle@268 120 //Pick a process to get this slot
seanhalle@268 121 process = pickAProcess( slot );
seanhalle@268 122
seanhalle@268 123 //Scan lang environs, looking for langEnv with ready work.
seanhalle@268 124 // call the Assigner for that lang Env, to get a slave for the slot
seanhalle@270 125 foundWork =
seanhalle@268 126 assignWork( process, slot );
seanhalle@268 127
seanhalle@268 128 HOLISTIC__Record_Assigner_end;
seanhalle@272 129
seanhalle@272 130 // fixme; //make this a while loop that tries a different process if this one fails
seanhalle@268 131 }//if slot needs slave assigned
seanhalle@270 132
seanhalle@270 133 return foundWork;
seanhalle@261 134 }
seanhalle@260 135
seanhalle@268 136 /*When several processes exist, use some pattern for picking one to give
seanhalle@268 137 * the animation slot to.
seanhalle@268 138 *First, it has to be a process that has work available.
seanhalle@268 139 *For now, just do a round-robin
seanhalle@261 140 */
seanhalle@268 141 inline
seanhalle@268 142 PRProcess *
seanhalle@268 143 pickAProcess( AnimSlot *slot )
seanhalle@268 144 { int32 idx;
seanhalle@268 145 PRProcess *process;
seanhalle@268 146
seanhalle@268 147 for( idx = _PRTopEnv->currProcessIdx; idx < _PRTopEnv->numProcesses; idx++)
seanhalle@268 148 {
seanhalle@268 149 process = _PRTopEnv->processes[ idx ];
seanhalle@268 150 if( process->numEnvsWithWork != 0 )
seanhalle@268 151 { _PRTopEnv->currProcessIdx = idx;
seanhalle@268 152 return process;
seanhalle@268 153 }
seanhalle@261 154 }
seanhalle@268 155 for( idx = 0; idx < _PRTopEnv->currProcessIdx; idx++)
seanhalle@268 156 {
seanhalle@268 157 process = _PRTopEnv->processes[ idx ];
seanhalle@268 158 if( process->numEnvsWithWork != 0 )
seanhalle@268 159 { _PRTopEnv->currProcessIdx = idx;
seanhalle@268 160 return process;
seanhalle@268 161 }
seanhalle@268 162 }
seanhalle@268 163 //none found
seanhalle@268 164 return NULL;
seanhalle@260 165 }
seanhalle@260 166
seanhalle@261 167 /*This does:
seanhalle@268 168 * 1) searches the language environments for one with work ready
seanhalle@261 169 * if finds one, asks its assigner to return work
seanhalle@261 170 * 2) checks what kind of work: new task, resuming task, resuming slave
seanhalle@261 171 * if new task, gets the slot slave and assigns task to it and returns slave
seanhalle@261 172 * else, gets the slave attached to the metaTask and returns that.
seanhalle@261 173 * 3) if no work found, then prune former task slaves waiting to be recycled.
seanhalle@261 174 * If no work and no slaves to prune, check for shutdown conditions.
seanhalle@261 175 *
seanhalle@268 176 * language env keeps its own work in its own structures, and has its own
seanhalle@261 177 * assigner. It chooses
seanhalle@261 178 * However, include a switch that switches-in an override assigner, which
seanhalle@268 179 * sees all the work in all the language env's. This is most likely
seanhalle@261 180 * generated by static tools and included in the executable. That means it
seanhalle@261 181 * has to be called via a registered pointer from here. The idea is that
seanhalle@261 182 * the static tools know which languages are grouped together.. and the
seanhalle@261 183 * override enables them to generate a custom assigner that uses info from
seanhalle@261 184 * all the languages in a unified way.. Don't really expect this to happen,
seanhalle@261 185 * but am making it possible.
seanhalle@260 186 */
seanhalle@268 187 inline
seanhalle@270 188 bool32
seanhalle@261 189 assignWork( PRProcess *process, AnimSlot *slot )
seanhalle@272 190 { int32 coreNum;
seanhalle@260 191
seanhalle@261 192 coreNum = slot->coreSlotIsOn;
seanhalle@260 193
seanhalle@267 194 if( process->overrideAssigner != NULL )
seanhalle@268 195 { if( process->numEnvsWithWork != 0 )
seanhalle@268 196 { (*process->overrideAssigner)( process, slot ); //calls PR fn that inserts work into slot
seanhalle@268 197 goto ReturnAfterAssigningWork; //quit for-loop, cause found work
seanhalle@261 198 }
seanhalle@268 199 else
seanhalle@261 200 goto NoWork;
seanhalle@261 201 }
seanhalle@261 202
seanhalle@268 203 //If here, then no override assigner, so search language envs for work
seanhalle@268 204 int32 envIdx, numEnvs; PRLangEnv **langEnvsList, *langEnv;
seanhalle@268 205 langEnvsList = process->langEnvsList;
seanhalle@268 206 numEnvs = process->numLangEnvs;
seanhalle@268 207 for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array
seanhalle@268 208 { langEnv = langEnvsList[envIdx];
seanhalle@272 209 if( langEnv->numReadyWork > 0 )
seanhalle@272 210 { bool32
seanhalle@272 211 didAssignWork =
seanhalle@272 212 (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot
seanhalle@272 213
seanhalle@272 214 if(didAssignWork)
seanhalle@272 215 { langEnv->numReadyWork -= 1;
seanhalle@272 216 if( langEnv->numReadyWork == 0 )
seanhalle@272 217 { process->numEnvsWithWork -= 1;
seanhalle@272 218 }
seanhalle@272 219 goto ReturnAfterAssigningWork; //quit for-loop, 'cause found work
seanhalle@272 220 }
seanhalle@272 221 else
seanhalle@272 222 goto NoWork; //quit for-loop, cause found work
seanhalle@272 223
seanhalle@268 224 //NOTE: bad search alg -- should start where left off, then wrap around
seanhalle@260 225 }
seanhalle@260 226 }
seanhalle@268 227 //If reach here, then have searched all langEnv's & none have work..
seanhalle@260 228
seanhalle@268 229 NoWork: //No work, if end up here..
seanhalle@260 230 {
seanhalle@260 231 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
seanhalle@272 232 returnSlv = process->idleSlv[coreNum][0]; //only one slot now, so [0]
seanhalle@260 233
seanhalle@260 234 //things that would normally happen in resume(), but idle VPs
seanhalle@260 235 // never go there
seanhalle@261 236 returnSlv->numTimesAssignedToASlot++; //gives each idle unit a unique ID
seanhalle@260 237 Unit newU;
seanhalle@268 238 newU.vp = returnSlv->slaveNum;
seanhalle@261 239 newU.task = returnSlv->numTimesAssignedToASlot;
seanhalle@261 240 addToListOfArrays(Unit,newU,process->unitList);
seanhalle@260 241
seanhalle@261 242 if (returnSlv->numTimesAssignedToASlot > 1) //make a dependency from prev idle unit
seanhalle@260 243 { Dependency newD; // to this one
seanhalle@268 244 newD.from_vp = returnSlv->slaveNum;
seanhalle@261 245 newD.from_task = returnSlv->numTimesAssignedToASlot - 1;
seanhalle@268 246 newD.to_vp = returnSlv->slaveNum;
seanhalle@261 247 newD.to_task = returnSlv->numTimesAssignedToASlot;
seanhalle@261 248 addToListOfArrays(Dependency, newD ,process->ctlDependenciesList);
seanhalle@260 249 }
seanhalle@268 250 #endif
seanhalle@268 251 HOLISTIC__Record_Assigner_end;
seanhalle@269 252 return FALSE;
seanhalle@260 253 }
seanhalle@268 254
seanhalle@268 255 ReturnAfterAssigningWork: //All paths goto here.. to provide single point for holistic..
seanhalle@268 256 {
seanhalle@268 257 HOLISTIC__Record_Assigner_end;
seanhalle@269 258 return TRUE;
seanhalle@260 259 }
seanhalle@260 260 }
seanhalle@260 261
seanhalle@260 262
seanhalle@268 263
seanhalle@268 264 /*This is first thing called when creating a slave.. it hands off to the
seanhalle@268 265 * langlet's creator, then adds updates of its own..
seanhalle@268 266 *
seanhalle@268 267 *There's a question of things like lang data, meta tasks, and such..
seanhalle@268 268 *In creator, only PR related things happen, and things for the langlet whose
seanhalle@261 269 * creator construct was used.
seanhalle@268 270 *
seanhalle@268 271 *Other langlets still get a chance to create langData -- but by registering a
seanhalle@268 272 * "createLangData" handler in the langEnv. When a construct of the langlet
seanhalle@268 273 * calls "PR__give_lang_data()", if there is no langData for that langlet,
seanhalle@268 274 * the PR will call the creator in the langlet's langEnv, place whatever it
seanhalle@268 275 * makes as the langData in that slave for that langlet, and return that langData
seanhalle@261 276 *
seanhalle@261 277 *So, as far as counting things, a langlet is only allowed to count creation
seanhalle@261 278 * of slaves it creates itself.. may have to change this later.. add a way for
seanhalle@261 279 * langlet to register a trigger Fn called each time a slave gets created..
seanhalle@261 280 * need more experience with what langlets will do at create time.. think Cilk
seanhalle@261 281 * has interesting create behavior.. not sure how that will differ in light
seanhalle@261 282 * of true tasks and langlet approach. Look at it after all done and start
seanhalle@261 283 * modifying the langs to be langlets..
seanhalle@261 284 *
seanhalle@261 285 *PR itself needs to create the slave, then update numLiveSlaves in process,
seanhalle@261 286 * copy processID from requestor to newly created
seanhalle@261 287 */
seanhalle@268 288 inline
seanhalle@268 289 void
seanhalle@272 290 PRHandle__CreateSlave( PRReqst *req, SlaveVP *slave )
seanhalle@268 291 { SlaveVP *newSlv;
seanhalle@261 292 PRProcess *process;
seanhalle@268 293 PRLangEnv *protoLangEnv;
seanhalle@261 294
seanhalle@268 295 process = slave->processSlaveIsIn;
seanhalle@268 296 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber );
seanhalle@272 297
seanhalle@272 298 //create handler, or a future request handler will call PR_PI__make_slave_ready
seanhalle@272 299 // which will in turn handle updating which langlets and which processes have
seanhalle@272 300 // work available.
seanhalle@272 301 //NOTE: create slv has diff prototype than standard reqst hdlr
seanhalle@268 302 newSlv =
seanhalle@268 303 (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv));
seanhalle@268 304
seanhalle@261 305 newSlv->typeOfVP = GenericSlv;
seanhalle@261 306 newSlv->processSlaveIsIn = process;
seanhalle@268 307 newSlv->ID = req->ID;
seanhalle@272 308 process->numLiveGenericSlvs += 1; //not same as work ready!
seanhalle@260 309 }
seanhalle@260 310
seanhalle@268 311 /*The dissipate handler has to, update the number of slaves of the type, within
seanhalle@261 312 * the process, and call the langlet handler linked into the request,
seanhalle@261 313 * and after that returns, then call the PR function that frees the slave state
seanhalle@261 314 * (or recycles the slave).
seanhalle@261 315 *
seanhalle@261 316 *The PR function that frees the slave state has to also free all of the
seanhalle@268 317 * langData in the slave.. or else reset all of the langDatas.. by, say, marking
seanhalle@268 318 * them, then in PR__give_langData( magicNum ) call the langlet registered
seanhalle@268 319 * "resetLangData" Fn.
seanhalle@261 320 */
seanhalle@268 321 inline
seanhalle@268 322 void
seanhalle@272 323 PRHandle__EndSlave( PRReqst *req, SlaveVP *slave )
seanhalle@261 324 { PRProcess *process;
seanhalle@268 325 PRLangEnv *protoLangEnv;
seanhalle@261 326
seanhalle@261 327 process = slave->processSlaveIsIn;
seanhalle@261 328
seanhalle@261 329 //do the language's dissipate handler
seanhalle@268 330 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, slave->request->langMagicNumber );
seanhalle@268 331
seanhalle@268 332 if(req->handler != NULL)
seanhalle@268 333 (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) );
seanhalle@261 334
seanhalle@272 335 process->numLiveGenericSlvs -= 1;
seanhalle@272 336 PR_int__recycle_slave( slave );
seanhalle@272 337 //NOTE: dissipate is unrelated to work available (just in case wondering)
seanhalle@272 338
seanhalle@261 339 //check End Of Process Condition
seanhalle@261 340 if( process->numLiveTasks == 0 &&
seanhalle@266 341 process->numLiveGenericSlvs == 0 )
seanhalle@272 342 PR_SS__shutdown_process( process );
seanhalle@261 343 }
seanhalle@261 344
seanhalle@261 345 /*Create task is a special form, that has PR behavior in addition to plugin
seanhalle@268 346 * behavior. Master calls this first, and it then calls the plugin's
seanhalle@261 347 * create task handler.
seanhalle@267 348 *
seanhalle@267 349 *Note: the requesting slave must be either generic slave or free task slave
seanhalle@261 350 */
seanhalle@268 351 inline
seanhalle@268 352 void
seanhalle@272 353 PRHandle__CreateTask( PRReqst *req, SlaveVP *slave )
seanhalle@267 354 { PRMetaTask *metaTask;
seanhalle@267 355 PRProcess *process;
seanhalle@268 356 PRLangEnv *protoLangEnv;
seanhalle@268 357 void *task;
seanhalle@267 358
seanhalle@268 359 process = slave->processSlaveIsIn;
seanhalle@268 360
seanhalle@268 361 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave,
seanhalle@268 362 req->langMagicNumber );
seanhalle@268 363
seanhalle@268 364 //Do the langlet's create-task handler, which keeps the task
seanhalle@268 365 // inside the langlet's lang env, but returns the langMetaTask
seanhalle@268 366 // so PR can put stuff into the prolog
seanhalle@268 367 task =
seanhalle@268 368 (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv) );
seanhalle@268 369 metaTask = PR_int__give_prolog_of_task( task );
seanhalle@268 370 metaTask->ID = req->ID; //may be NULL
seanhalle@267 371 metaTask->topLevelFn = req->topLevelFn;
seanhalle@267 372 metaTask->initData = req->initData;
seanhalle@261 373
seanhalle@261 374 process->numLiveTasks += 1;
seanhalle@267 375
seanhalle@261 376 return;
seanhalle@261 377 }
seanhalle@261 378
seanhalle@272 379 /*When a task ends, have two scenarios: 1) task ran to completion, or 2) task
seanhalle@272 380 * has been suspended at some point in its code.
seanhalle@261 381 *For 1, just decr count of live tasks (and check for end condition) -- the
seanhalle@261 382 * master loop will decide what goes into the slot freed up by this task end,
seanhalle@261 383 * so, here, don't worry about assigning a new task to the slot slave.
seanhalle@261 384 *For 2, the task's slot slave has been converted to a free task slave, which
seanhalle@261 385 * now has nothing more to do, so send it to the recycle Q (which includes
seanhalle@268 386 * freeing all the langData and meta task structs alloc'd for it). Then
seanhalle@261 387 * decrement the live task count and check end condition.
seanhalle@261 388 *
seanhalle@261 389 *PR has to update count of live tasks, and check end of process condition.
seanhalle@267 390 * The "main" can invoke constructs that wait for a process to end, so when
seanhalle@267 391 * end detected, have to resume what's waiting..
seanhalle@267 392 *Thing is, that wait involves the main OS thread. That means
seanhalle@261 393 * PR internals have to do OS thread signaling. Want to do that in the
seanhalle@267 394 * core controller, which has the original stack of an OS thread. So the
seanhalle@267 395 * end process handling happens in the core controller.
seanhalle@261 396 *
seanhalle@261 397 *So here, when detect process end, signal to the core controller, which will
seanhalle@267 398 * then do the condition variable notify to the OS thread that's waiting.
seanhalle@267 399 *
seanhalle@267 400 *Note: slave may be either a slot slave or a free task slave.
seanhalle@261 401 */
seanhalle@268 402 inline
seanhalle@268 403 void
seanhalle@272 404 PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv )
seanhalle@268 405 { void *langEnv;
seanhalle@261 406 PRProcess *process;
seanhalle@268 407 void *langMetaTask;
seanhalle@267 408
seanhalle@272 409 langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req
seanhalle@272 410 langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber);
seanhalle@261 411
seanhalle@267 412 //Do the langlet's request handler
seanhalle@268 413 //Want to keep PR structs hidden from plugin, so extract langReq..
seanhalle@268 414 (*req->handler)( req->langReq, requestingSlv, langEnv );
seanhalle@267 415
seanhalle@267 416 //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv
seanhalle@267 417 if( requestingSlv->typeOfVP == FreeTaskSlv )
seanhalle@272 418 PR_int__recycle_slave( requestingSlv ); //Doesn't decr num live slaves
seanhalle@261 419
seanhalle@261 420 process->numLiveTasks -= 1;
seanhalle@272 421 //NOTE: end-task is unrelated to work available (just in case wondering)
seanhalle@261 422
seanhalle@261 423 //check End Of Process Condition
seanhalle@261 424 if( process->numLiveTasks == 0 &&
seanhalle@266 425 process->numLiveGenericSlvs == 0 )
seanhalle@268 426 { //Tell the core controller to do wakeup of any waiting OS thread
seanhalle@272 427 PR_SS__shutdown_process( process );
seanhalle@268 428 }
seanhalle@261 429 }
seanhalle@261 430
seanhalle@272 431
seanhalle@272 432 /*This is for OS requests and PR infrastructure requests, which are not
seanhalle@272 433 * part of the PRServ language -- this is for things that have to be in the
seanhalle@272 434 * infrastructure of PR itself, such as I/O requests, which have to go through
seanhalle@272 435 * pthreads inside the core controller..
seanhalle@272 436 *
seanhalle@272 437 *As of Jan 2013, doesn't do much of anything..
seanhalle@272 438 */
seanhalle@272 439 void inline
seanhalle@272 440 PRHandle__ServiceReq( SlaveVP *requestingSlv )
seanhalle@272 441 { PRReqst *req;
seanhalle@272 442 PRServReq *langReq;
seanhalle@272 443 void *langEnv;
seanhalle@272 444 int32 magicNumber;
seanhalle@272 445
seanhalle@272 446
seanhalle@272 447 req = requestingSlv->request;
seanhalle@272 448
seanhalle@272 449 magicNumber = req->langMagicNumber;
seanhalle@272 450 langEnv = PR_PI__give_lang_env_for( slave, magicNumber );
seanhalle@272 451
seanhalle@272 452 langReq = PR_PI__take_lang_reqst_from(req);
seanhalle@272 453 if( langReq == NULL ) return;
seanhalle@272 454 switch( langReq->reqType ) //lang handlers are all in other file
seanhalle@272 455 {
seanhalle@272 456 case make_probe: handleMakeProbe( langReq, langEnv );
seanhalle@272 457 break;
seanhalle@272 458 case throw_excp: handleThrowException( langReq, langEnv );
seanhalle@272 459 break;
seanhalle@272 460 }
seanhalle@272 461 }