Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison MasterLoop.c @ 14:65c8fb2821ee
Forgot to commit after had working test -- changed stack & frame ptrs in thd params
to be instead in virt procr struc -- stopped working! Saving now, then going back to
way had it..
| author | Me |
|---|---|
| date | Tue, 22 Jun 2010 11:52:41 -0700 |
| parents | a87d02855dee |
| children | a0af8d4fca35 |
comparison
equal
deleted
inserted
replaced
| 2:65d0e1918736 | 3:1f57dfe9eb12 |
|---|---|
| 14 #include "VMS.h" | 14 #include "VMS.h" |
| 15 | 15 |
| 16 | 16 |
| 17 | 17 |
| 18 /*This code is animated by the virtual Master processor. | 18 /*This code is animated by the virtual Master processor. |
| 19 *Note, it is animated on a different level in virtual processor hierarchy | |
| 20 * than the CoreLoop -- this is the code pointed to in a work-unit that the | |
| 21 * coreLoop jumps to | |
| 22 * | 19 * |
| 23 *Polls each virtual slave exactly once, hands any requests made by the slave | 20 *Polls each sched slot exactly once, hands any requests made by a newly |
| 24 * to the "request handler" plug-in function | 21 * done slave to the "request handler" plug-in function |
| 25 * | 22 * |
| 26 *Any slaves that have no work-unit assigned are given to the "schedule" | 23 *Any slots that need a virt procr assigned are given to the "schedule" |
| 27 * plug-in function, which tries to assign a work-unit to it. | 24 * plug-in function, which tries to assign a virt procr (slave) to it. |
| 28 * | 25 * |
| 29 *When all slaves that need work-units have been given to the schedule plug-in, | 26 *When all slots needing a processor have been given to the schedule plug-in, |
| 30 * half of the ones that were successfully scheduled are put into the work | 27 * a fraction of the procrs successfully scheduled are put into the |
| 31 * queue, then a continuation of this function is put in, then the rest of the | 28 * work queue, then a continuation of this function is put in, then the rest |
| 32 * slaves that were successfully scheduled. | 29 * of the virt procrs that were successfully scheduled. |
| 33 * | 30 * |
| 34 *The first thing this function does is busy-wait until the previous work-unit | 31 *The first thing the continuation does is busy-wait until the previous |
| 35 * running this function is done. This ensures it doesn't overlap with | 32 * animation completes. This is because an (unlikely) continuation may |
| 36 * tail-end of previous -- IE, continuation may sneak through queue before | 33 * sneak through queue before previous continuation is done putting second |
| 37 * previous done putting second half of scheduled slaves in. This is the only | 34 * part of scheduled slaves in, which is the only race condition. |
| 38 * race condition. | |
| 39 * | 35 * |
| 40 */ | 36 */ |
| 41 | 37 |
| 42 /*May 29, 2010 -- birth a Master during init so that first core loop to | 38 /*May 29, 2010 -- birth a Master during init so that first core loop to |
| 43 * start running gets it and does all the stuff for a newly born | 39 * start running gets it and does all the stuff for a newly born -- |
| 44 * from then on, will be doing continuation -- but do suspension self | 40 * from then on, will be doing continuation, but do suspension self |
| 45 * directly at end of master loop | 41 * directly at end of master loop |
| 46 *So VMS__init just births the master virtual processor same way it births | 42 *So VMS__init just births the master virtual processor same way it births |
| 47 * all the others -- then does any extra setup needed and puts it into the | 43 * all the others -- then does any extra setup needed and puts it into the |
| 48 * work queue. | 44 * work queue. |
| 49 *However means have to make masterEnv a global static volatile the same way | 45 *However means have to make masterEnv a global static volatile the same way |
| 50 * did with workQ in core loop. -- for performance, put the | 46 * did with workQ in core loop. -- for performance, put the |
| 51 * jump to core loop directly in here, and have it directly jump back. | 47 * jump to the core loop directly in here, and have it directly jump back. |
| 52 */ | 48 */ |
| 53 void masterLoop( void *initData, VirtProcr *masterPr ) | 49 void masterLoop( void *initData, VirtProcr *masterPr ) |
| 54 { bool8 success; | 50 { bool8 retCode; |
| 55 int slotIdx, numScheduled, numInFirstChunk, filledSlotIdx; | 51 int slotIdx, numScheduled, numInFirstChunk, filledSlotIdx; |
| 56 SchedSlot *currSlot, **schedSlots, **filledSlots; | 52 SchedSlot *currSlot, **schedSlots, **filledSlots; |
| 57 MasterEnv *masterEnv; | 53 MasterEnv *masterEnv; |
| 58 QueueStruc *workQ; | 54 CASQueueStruc *workQ; |
| 59 // VirtProcr *masterPr; | |
| 60 void *jmpPt; | 55 void *jmpPt; |
| 61 | 56 |
| 62 SlaveScheduler slaveScheduler; | 57 SlaveScheduler slaveScheduler; |
| 63 RequestHandler requestHandler; | 58 RequestHandler requestHandler; |
| 64 | 59 |
| 71 | 66 |
| 72 masterLoopStartPt: | 67 masterLoopStartPt: |
| 73 | 68 |
| 74 //if another reference to same Master VirtProcr still going, busy-wait | 69 //if another reference to same Master VirtProcr still going, busy-wait |
| 75 //Could put this lower, but don't want to think about shared stack.. | 70 //Could put this lower, but don't want to think about shared stack.. |
| 71 masterEnv = _VMSMasterEnv; | |
| 76 while( masterEnv->stillRunning ) /*busy wait*/ ; | 72 while( masterEnv->stillRunning ) /*busy wait*/ ; |
| 77 //TODO: want to do busy-wait as assembly, to be sure stack not touched? | 73 //TODO: want to do busy-wait as assembly, to be sure stack not touched? |
| 78 | 74 |
| 79 //this is the only master running now, set flag again | 75 //this is the only master running now, set flag again |
| 80 masterEnv->stillRunning = TRUE; | 76 masterEnv->stillRunning = TRUE; |
| 81 | 77 |
| 82 //TODO: gdb -- check that a volatile _VMSMasterEnv and _VMSWorkQ means | 78 //TODO: gdb -- check that a volatile _VMSMasterEnv and _VMSWorkQ means |
| 83 // all these will be re-filled every time jump here.. | 79 // all these will be re-filled every time jump here.. |
| 84 workQ = _VMSWorkQ; | 80 workQ = _VMSWorkQ; |
| 85 masterEnv = _VMSMasterEnv; | |
| 86 requestHandler = masterEnv->requestHandler; | 81 requestHandler = masterEnv->requestHandler; |
| 87 slaveScheduler = masterEnv->slaveScheduler; | 82 slaveScheduler = masterEnv->slaveScheduler; |
| 88 schedSlots = masterEnv->schedSlots; | 83 schedSlots = masterEnv->schedSlots; |
| 89 filledSlots = masterEnv->filledSlots; | 84 filledSlots = masterEnv->filledSlots; |
| 90 masterPr = masterEnv->masterVirtPr; | 85 masterPr = masterEnv->masterVirtPr; //post-jmp clobbered, re-load |
| 91 | 86 |
| 92 | 87 |
| 93 //prepare for scheduling | 88 //prepare for scheduling |
| 94 masterEnv->numFilled = 0; | 89 masterEnv->numFilled = 0; |
| 95 | 90 |
| 106 //process requests from slave to master | 101 //process requests from slave to master |
| 107 (*requestHandler)( currSlot->procrAssignedToSlot->requests ); | 102 (*requestHandler)( currSlot->procrAssignedToSlot->requests ); |
| 108 } | 103 } |
| 109 if( currSlot->needsProcrAssigned ) | 104 if( currSlot->needsProcrAssigned ) |
| 110 { //give slot a new virt procr | 105 { //give slot a new virt procr |
| 111 success = | 106 retCode = |
| 112 (*slaveScheduler)( currSlot, masterEnv->semanticEnv ); | 107 (*slaveScheduler)( currSlot, masterEnv->semanticEnv ); |
| 113 | 108 |
| 114 if( success ) | 109 if( retCode == 1 ) |
| 115 { int numFilled = masterEnv->numFilled; | 110 { int numFilled = masterEnv->numFilled; |
| 116 | 111 |
| 117 filledSlots[numFilled] = currSlot; | 112 filledSlots[numFilled] = currSlot; |
| 118 masterEnv->numFilled += 1; | 113 masterEnv->numFilled += 1; |
| 119 | 114 |
| 120 currSlot->needsProcrAssigned = FALSE; | 115 currSlot->needsProcrAssigned = FALSE; |
| 116 } | |
| 117 else if( retCode == -1 ) //scheduler plug-in says to shut down VMS | |
| 118 { | |
| 119 //shutdown -- make "end Thd" virt-procs whose nextInstrPt is the | |
| 120 // coreloop's EndCoreLoopPt -- causing a jump to the EndThread | |
| 121 // and any other shut-down. | |
| 121 } | 122 } |
| 122 } | 123 } |
| 123 } | 124 } |
| 124 | 125 |
| 125 //put some scheduled slaves in, then continuation, then rest | 126 //put some scheduled slaves in, then continuation, then rest |
| 126 numInFirstChunk = masterEnv->numFilled / 2; //tweak this from experiments | 127 numInFirstChunk = masterEnv->numFilled / 2; //tweak this from experiments |
| 127 for( filledSlotIdx = 0; filledSlotIdx < numInFirstChunk; filledSlotIdx++) | 128 for( filledSlotIdx = 0; filledSlotIdx < numInFirstChunk; filledSlotIdx++) |
| 128 { | 129 { |
| 129 writeQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); | 130 writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); |
| 130 } | 131 } |
| 131 | 132 |
| 132 //enqueue continuation of this loop | 133 //enqueue continuation of this loop |
| 133 // note that After this enqueue, continuation might sneak through | 134 // note that After this enqueue, continuation might sneak through |
| 134 writeQ( schedSlots[0]->procrAssignedToSlot, workQ );//master always slot 0 | 135 writeCASQ( schedSlots[0]->procrAssignedToSlot, workQ );//master always slot 0 |
| 135 for( filledSlotIdx = numInFirstChunk; | 136 for( filledSlotIdx = numInFirstChunk; |
| 136 filledSlotIdx < numScheduled; | 137 filledSlotIdx < numScheduled; |
| 137 filledSlotIdx++) | 138 filledSlotIdx++) |
| 138 { | 139 { |
| 139 writeQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); | 140 writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); |
| 140 } | 141 } |
| 141 | 142 |
| 142 masterEnv->numFilled = 0; | 143 masterEnv->numFilled = 0; |
| 143 | 144 |
| 144 //Don't want code above to try to look at requests in masterVirtPr, | 145 //Don't want code above to try to look at requests in masterVirtPr, |
