comparison 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
comparison
equal deleted inserted replaced
15:77a8dc0f570c 17:1f4f559c0919
17 17
18 void PRHandle_CreateSlave_SL(SlaveVP *slave); 18 void PRHandle_CreateSlave_SL(SlaveVP *slave);
19 void PRHandle_Dissipate_SL(SlaveVP *slave); 19 void PRHandle_Dissipate_SL(SlaveVP *slave);
20 void PR_int__handle_PRServiceReq_SL(SlaveVP *slave); 20 void PR_int__handle_PRServiceReq_SL(SlaveVP *slave);
21 */ 21 */
22 inline void PRHandle_CreateTask( PRReqst *req, SlaveVP *slave ); 22 inline void PRHandle__CreateTask( PRReqst *req, SlaveVP *slave );
23 inline void PRHandle_EndTask( PRReqst *req, SlaveVP *slave ); 23 inline void PRHandle__EndTask( PRReqst *req, SlaveVP *slave );
24 inline void PRHandle_CreateSlave(PRReqst *req, SlaveVP *slave ); 24 inline void PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave );
25 void PRHandle_EndSlave( PRReqst *req, SlaveVP *slave ); 25 void PRHandle__EndSlave( PRReqst *req, SlaveVP *slave );
26 26
27 27
28 //inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot ); 28 //inline void masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot );
29 inline PRProcess * pickAProcess( AnimSlot *slot ); 29 inline PRProcess * pickAProcess( AnimSlot *slot );
30 inline bool32 assignWork( PRProcess *process, AnimSlot *slot ); 30 inline bool32 assignWork( PRProcess *process, AnimSlot *slot );
31 31
32 /*The animationMaster embodies most of the animator of the language. The 32
33 * animator is what emodies the behavior of language constructs. 33 /*Note: there used to be a coreController that was another animation
34 * As such, it is the animationMaster, in combination with the plugin 34 * layer below both the masterVP and the slaveVPs.. in that case, the
35 * functions, that make the language constructs do their behavior. 35 * masterVP was a virtual processor whose processor-state was the same
36 * 36 * as a slaveVP's processor sate, both implemented as a SlaveVP struct.
37 *Within the code, this is the top-level-function of the masterVPs, and 37 * Have removed that, and
38 * runs when the coreController has no more slave VPs. It's job is to 38 * changed the masterVP implementation. Instead of being a special version
39 * refill the animation slots with slaves that have work. 39 * of a proto-runtime virtual processor, using the slaveVP stuct, the
40 * 40 * Master "virtual processor" is now implemented as a pthread pinned to
41 *There are multiple versions of the master, each tuned to a specific 41 * a physical core.
42 * combination of modes. This keeps the master simple, with reduced overhead, 42 */
43 * when the application is not using the extra complexity. 43
44 * 44 /*This is the behavior of the Master. The physical processor switches
45 *As of Sept 2012, the versions available will be: 45 * between animating the master, and animating a slave. When a slave
46 * 1) Single langauge, which only exposes slaves (such as SSR or Vthread) 46 * suspends, the PR "suspend" primitive switches the physical core over
47 * 2) Single language, which only exposes tasks (such as pure dataflow) 47 * to animating the masterVP, which is implemented as a pinned pthread.
48 * 3) Single language, which exposes both (like Cilk, StarSs, and OpenMP) 48 * This function is the behavior of that masterVP.
49 * 4) Multi-language, which always assumes both tasks and slaves 49 *This function's job is to manage processing
50 * 5) Multi-language and multi-process, which also assumes both tasks and slaves 50 * requests and to trigger assignment of new work to the physical core,
51 * 51 * and to manage sharing the core among processes.
52 * 52 */
53 *
54 */
55
56 //This version of the master selects one of three loops, depending upon
57 // whether stand-alone single language (just slaves), or standalone with
58 // tasks, or multi-lang (implies multi-process)
59 void animationMaster( void *_environment, SlaveVP *masterVP )
60 {
61 TopEnv *masterEnv = (TopEnv *)_environment;
62 int32 slotIdx;
63 AnimSlot *currSlot;
64 //Used while scanning and filling animation slots
65 AnimSlot **animSlots;
66
67 //Local copies, for performance
68 int32 thisCoresIdx;
69
70 //======================== Initializations ========================
71 thisCoresIdx = masterVP->coreAnimatedBy;
72 animSlots = masterEnv->allAnimSlots[thisCoresIdx];
73
74 HOLISTIC__Insert_Master_Global_Vars;
75
76 //======================== animationMaster ========================
77 //Have three different modes, and the master behavior is different for
78 // each, so jump to the loop that corresponds to the mode.
79 //
80 while(1)
81 { MEAS__Capture_Pre_Master_Point
82 for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
83 {
84 currSlot = animSlots[ slotIdx ];
85
86 masterFunction( currSlot );
87 }
88 MEAS__Capture_Post_Master_Point;
89 masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
90 flushRegisters();
91 }
92 }
93
94
95 inline 53 inline
96 bool32 54 bool32
97 masterFunction( AnimSlot *slot ) 55 masterFunction( AnimSlot *slot )
98 { //Scan the animation slots 56 { //Scan the animation slots
99 int32 magicNumber; 57 int32 magicNumber;
102 PRReqst *req; 60 PRReqst *req;
103 PRProcess *process; 61 PRProcess *process;
104 bool32 foundWork; 62 bool32 foundWork;
105 63
106 //Check if newly-done slave in slot, which will need request handled 64 //Check if newly-done slave in slot, which will need request handled
65 //NOTE: left over from when had a coreController & MasterVP managed
66 // several slots
107 if( slot->workIsDone ) 67 if( slot->workIsDone )
108 { slot->workIsDone = FALSE; 68 { slot->workIsDone = FALSE;
109 slot->needsWorkAssigned = TRUE; 69 slot->needsWorkAssigned = TRUE;
110 70
111 HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot 71 HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
124 //Handle task create and end first -- they're special cases.. 84 //Handle task create and end first -- they're special cases..
125 switch( req->reqType ) 85 switch( req->reqType )
126 { case TaskEnd: 86 { case TaskEnd:
127 { //do PR handler, which calls lang's hdlr and does recycle of 87 { //do PR handler, which calls lang's hdlr and does recycle of
128 // free task slave if needed -- PR handler checks for free task Slv 88 // free task slave if needed -- PR handler checks for free task Slv
129 PRHandle_EndTask( req, slave ); break; 89 PRHandle__EndTask( req, slave ); break;
130 } 90 }
131 case TaskCreate: 91 case TaskCreate:
132 { //Do PR's create-task handler, which calls the lang's hdlr 92 { //Do PR's create-task handler, which calls the lang's hdlr
133 // PR handler checks for free task Slv 93 // PR handler checks for free task Slv
134 PRHandle_CreateTask( req, slave ); break; 94 PRHandle__CreateTask( req, slave ); break;
135 } 95 }
136 case SlvCreate: PRHandle_CreateSlave( req, slave ); break; 96 case SlvCreate: PRHandle__CreateSlave( req, slave ); break;
137 case SlvDissipate: PRHandle_EndSlave( req, slave ); break; 97 case SlvDissipate: PRHandle__EndSlave( req, slave ); break;
138 case Service: PR_int__handle_PRServiceReq( slave ); break; //resumes into Service lang env 98 case Service: PRHandle__ServiceReq( slave ); break; //resumes into Service lang env
139 case Hardware: //for future expansion 99 case Hardware: //for future expansion
140 case IO: //for future expansion 100 case IO: //for future expansion
141 case OSCall: //for future expansion 101 case OSCall: //for future expansion
142 PR_int__throw_exception("Not implemented", slave, NULL); break; 102 PR_int__throw_exception("Not implemented", slave, NULL); break;
143 case Language: //normal lang request 103 case Language: //normal lang request
149 109
150 MEAS__endReqHdlr; 110 MEAS__endReqHdlr;
151 HOLISTIC__Record_AppResponder_end; 111 HOLISTIC__Record_AppResponder_end;
152 } //if have request to be handled 112 } //if have request to be handled
153 113
154 if( slot->needsWorkAssigned ) 114 //NOTE: IF statement is leftover from when master managed many slots
115 foundWork = FALSE;
116 if( slot->needsWorkAssigned ) //can probably remove IF, not that only one slot
155 { 117 {
156 HOLISTIC__Record_Assigner_start; 118 HOLISTIC__Record_Assigner_start;
157 119
158 //Pick a process to get this slot 120 //Pick a process to get this slot
159 process = pickAProcess( slot ); 121 process = pickAProcess( slot );
160 122
161 //Scan lang environs, looking for langEnv with ready work. 123 //Scan lang environs, looking for langEnv with ready work.
162 // call the Assigner for that lang Env, to get a slave for the slot 124 // call the Assigner for that lang Env, to get a slave for the slot
163 foundWork = 125 foundWork =
164 assignWork( process, slot ); 126 assignWork( process, slot );
165 127
166 HOLISTIC__Record_Assigner_end; 128 HOLISTIC__Record_Assigner_end;
129
130 // fixme; //make this a while loop that tries a different process if this one fails
167 }//if slot needs slave assigned 131 }//if slot needs slave assigned
168 132
169 return foundWork; 133 return foundWork;
170 } 134 }
171 135
221 * but am making it possible. 185 * but am making it possible.
222 */ 186 */
223 inline 187 inline
224 bool32 188 bool32
225 assignWork( PRProcess *process, AnimSlot *slot ) 189 assignWork( PRProcess *process, AnimSlot *slot )
226 { SlaveVP *returnSlv; 190 { int32 coreNum;
227 int32 coreNum, slotNum;
228 PRMetaTask *assignedMetaTask;
229 191
230 coreNum = slot->coreSlotIsOn; 192 coreNum = slot->coreSlotIsOn;
231 193
232 if( process->overrideAssigner != NULL ) 194 if( process->overrideAssigner != NULL )
233 { if( process->numEnvsWithWork != 0 ) 195 { if( process->numEnvsWithWork != 0 )
242 int32 envIdx, numEnvs; PRLangEnv **langEnvsList, *langEnv; 204 int32 envIdx, numEnvs; PRLangEnv **langEnvsList, *langEnv;
243 langEnvsList = process->langEnvsList; 205 langEnvsList = process->langEnvsList;
244 numEnvs = process->numLangEnvs; 206 numEnvs = process->numLangEnvs;
245 for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array 207 for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array
246 { langEnv = langEnvsList[envIdx]; 208 { langEnv = langEnvsList[envIdx];
247 if( langEnv->hasWork ) 209 if( langEnv->numReadyWork > 0 )
248 { (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot 210 { bool32
249 goto ReturnAfterAssigningWork; //quit for-loop, cause found work 211 didAssignWork =
212 (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot
213
214 if(didAssignWork)
215 { langEnv->numReadyWork -= 1;
216 if( langEnv->numReadyWork == 0 )
217 { process->numEnvsWithWork -= 1;
218 }
219 goto ReturnAfterAssigningWork; //quit for-loop, 'cause found work
220 }
221 else
222 goto NoWork; //quit for-loop, cause found work
223
250 //NOTE: bad search alg -- should start where left off, then wrap around 224 //NOTE: bad search alg -- should start where left off, then wrap around
251 } 225 }
252 } 226 }
253 //If reach here, then have searched all langEnv's & none have work.. 227 //If reach here, then have searched all langEnv's & none have work..
254 228
255 NoWork: //No work, if end up here.. 229 NoWork: //No work, if end up here..
256 { 230 {
257 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 231 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
258 returnSlv = process->idleSlv[coreNum][slotNum]; 232 returnSlv = process->idleSlv[coreNum][0]; //only one slot now, so [0]
259 233
260 //things that would normally happen in resume(), but idle VPs 234 //things that would normally happen in resume(), but idle VPs
261 // never go there 235 // never go there
262 returnSlv->numTimesAssignedToASlot++; //gives each idle unit a unique ID 236 returnSlv->numTimesAssignedToASlot++; //gives each idle unit a unique ID
263 Unit newU; 237 Unit newU;
311 *PR itself needs to create the slave, then update numLiveSlaves in process, 285 *PR itself needs to create the slave, then update numLiveSlaves in process,
312 * copy processID from requestor to newly created 286 * copy processID from requestor to newly created
313 */ 287 */
314 inline 288 inline
315 void 289 void
316 PRHandle_CreateSlave( PRReqst *req, SlaveVP *slave ) 290 PRHandle__CreateSlave( PRReqst *req, SlaveVP *slave )
317 { SlaveVP *newSlv; 291 { SlaveVP *newSlv;
318 PRProcess *process; 292 PRProcess *process;
319 PRLangEnv *protoLangEnv; 293 PRLangEnv *protoLangEnv;
320 294
321 process = slave->processSlaveIsIn; 295 process = slave->processSlaveIsIn;
322 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber ); 296 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber );
323 297
324 // newSlv = PR_int__create_slave( req->topLevelFn, req->initData ); 298 //create handler, or a future request handler will call PR_PI__make_slave_ready
325 299 // which will in turn handle updating which langlets and which processes have
326 //create slv has diff prototype than standard reqst hdlr 300 // work available.
301 //NOTE: create slv has diff prototype than standard reqst hdlr
327 newSlv = 302 newSlv =
328 (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv)); 303 (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv));
329 304
330 newSlv->typeOfVP = GenericSlv; 305 newSlv->typeOfVP = GenericSlv;
331 newSlv->processSlaveIsIn = process; 306 newSlv->processSlaveIsIn = process;
332 newSlv->ID = req->ID; 307 newSlv->ID = req->ID;
333 process->numLiveGenericSlvs += 1; 308 process->numLiveGenericSlvs += 1; //not same as work ready!
334 } 309 }
335 310
336 /*The dissipate handler has to, update the number of slaves of the type, within 311 /*The dissipate handler has to, update the number of slaves of the type, within
337 * the process, and call the langlet handler linked into the request, 312 * the process, and call the langlet handler linked into the request,
338 * and after that returns, then call the PR function that frees the slave state 313 * and after that returns, then call the PR function that frees the slave state
343 * them, then in PR__give_langData( magicNum ) call the langlet registered 318 * them, then in PR__give_langData( magicNum ) call the langlet registered
344 * "resetLangData" Fn. 319 * "resetLangData" Fn.
345 */ 320 */
346 inline 321 inline
347 void 322 void
348 PRHandle_EndSlave( PRReqst *req, SlaveVP *slave ) 323 PRHandle__EndSlave( PRReqst *req, SlaveVP *slave )
349 { PRProcess *process; 324 { PRProcess *process;
350 PRLangEnv *protoLangEnv; 325 PRLangEnv *protoLangEnv;
351 326
352 process = slave->processSlaveIsIn; 327 process = slave->processSlaveIsIn;
353 328
355 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, slave->request->langMagicNumber ); 330 protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, slave->request->langMagicNumber );
356 331
357 if(req->handler != NULL) 332 if(req->handler != NULL)
358 (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) ); 333 (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) );
359 334
360 process->numLiveGenericSlvs -= 1; 335 process->numLiveGenericSlvs -= 1;
361 PR_int__recycle_slave__ML( slave ); 336 PR_int__recycle_slave( slave );
362 337 //NOTE: dissipate is unrelated to work available (just in case wondering)
338
363 //check End Of Process Condition 339 //check End Of Process Condition
364 if( process->numLiveTasks == 0 && 340 if( process->numLiveTasks == 0 &&
365 process->numLiveGenericSlvs == 0 ) 341 process->numLiveGenericSlvs == 0 )
366 PR_SS__shutdown_process__ML( process ); 342 PR_SS__shutdown_process( process );
367 } 343 }
368 344
369 /*Create task is a special form, that has PR behavior in addition to plugin 345 /*Create task is a special form, that has PR behavior in addition to plugin
370 * behavior. Master calls this first, and it then calls the plugin's 346 * behavior. Master calls this first, and it then calls the plugin's
371 * create task handler. 347 * create task handler.
372 * 348 *
373 *Note: the requesting slave must be either generic slave or free task slave 349 *Note: the requesting slave must be either generic slave or free task slave
374 */ 350 */
375 inline 351 inline
376 void 352 void
377 PRHandle_CreateTask( PRReqst *req, SlaveVP *slave ) 353 PRHandle__CreateTask( PRReqst *req, SlaveVP *slave )
378 { PRMetaTask *metaTask; 354 { PRMetaTask *metaTask;
379 PRProcess *process; 355 PRProcess *process;
380 PRLangEnv *protoLangEnv; 356 PRLangEnv *protoLangEnv;
381 void *task; 357 void *task;
382 358
398 process->numLiveTasks += 1; 374 process->numLiveTasks += 1;
399 375
400 return; 376 return;
401 } 377 }
402 378
403 /*When a task ends, are two scenarios: 1) task ran to completion, or 2) task 379 /*When a task ends, have two scenarios: 1) task ran to completion, or 2) task
404 * suspended at some point in its code. 380 * has been suspended at some point in its code.
405 *For 1, just decr count of live tasks (and check for end condition) -- the 381 *For 1, just decr count of live tasks (and check for end condition) -- the
406 * master loop will decide what goes into the slot freed up by this task end, 382 * master loop will decide what goes into the slot freed up by this task end,
407 * so, here, don't worry about assigning a new task to the slot slave. 383 * so, here, don't worry about assigning a new task to the slot slave.
408 *For 2, the task's slot slave has been converted to a free task slave, which 384 *For 2, the task's slot slave has been converted to a free task slave, which
409 * now has nothing more to do, so send it to the recycle Q (which includes 385 * now has nothing more to do, so send it to the recycle Q (which includes
423 * 399 *
424 *Note: slave may be either a slot slave or a free task slave. 400 *Note: slave may be either a slot slave or a free task slave.
425 */ 401 */
426 inline 402 inline
427 void 403 void
428 PRHandle_EndTask( PRReqst *req, SlaveVP *requestingSlv ) 404 PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv )
429 { void *langEnv; 405 { void *langEnv;
430 PRProcess *process; 406 PRProcess *process;
431 void *langMetaTask; 407 void *langMetaTask;
432 408
433 langEnv = PR_int__give_lang_env_of_req__ML( req, requestingSlv ); //magic num in req 409 langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req
434 langMetaTask = PR_int__give_lang_meta_task_from_slave__ML( requestingSlv, req->langMagicNumber); 410 langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber);
435 411
436 //Do the langlet's request handler 412 //Do the langlet's request handler
437 //Want to keep PR structs hidden from plugin, so extract langReq.. 413 //Want to keep PR structs hidden from plugin, so extract langReq..
438 (*req->handler)( req->langReq, requestingSlv, langEnv ); 414 (*req->handler)( req->langReq, requestingSlv, langEnv );
439 415
440 //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv 416 //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv
441 if( requestingSlv->typeOfVP == FreeTaskSlv ) 417 if( requestingSlv->typeOfVP == FreeTaskSlv )
442 PR_int__recycle_slave__ML( requestingSlv ); 418 PR_int__recycle_slave( requestingSlv ); //Doesn't decr num live slaves
443 419
444 process->numLiveTasks -= 1; 420 process->numLiveTasks -= 1;
421 //NOTE: end-task is unrelated to work available (just in case wondering)
445 422
446 //check End Of Process Condition 423 //check End Of Process Condition
447 if( process->numLiveTasks == 0 && 424 if( process->numLiveTasks == 0 &&
448 process->numLiveGenericSlvs == 0 ) 425 process->numLiveGenericSlvs == 0 )
449 { //Tell the core controller to do wakeup of any waiting OS thread 426 { //Tell the core controller to do wakeup of any waiting OS thread
450 PR_SS__shutdown_process__ML( process ); 427 PR_SS__shutdown_process( process );
451 } 428 }
452 } 429 }
453 430
431
432 /*This is for OS requests and PR infrastructure requests, which are not
433 * part of the PRServ language -- this is for things that have to be in the
434 * infrastructure of PR itself, such as I/O requests, which have to go through
435 * pthreads inside the core controller..
436 *
437 *As of Jan 2013, doesn't do much of anything..
438 */
439 void inline
440 PRHandle__ServiceReq( SlaveVP *requestingSlv )
441 { PRReqst *req;
442 PRServReq *langReq;
443 void *langEnv;
444 int32 magicNumber;
445
446
447 req = requestingSlv->request;
448
449 magicNumber = req->langMagicNumber;
450 langEnv = PR_PI__give_lang_env_for( slave, magicNumber );
451
452 langReq = PR_PI__take_lang_reqst_from(req);
453 if( langReq == NULL ) return;
454 switch( langReq->reqType ) //lang handlers are all in other file
455 {
456 case make_probe: handleMakeProbe( langReq, langEnv );
457 break;
458 case throw_excp: handleThrowException( langReq, langEnv );
459 break;
460 }
461 }