Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison MasterLoop.c @ 120:d4c881c7f03a
Added fn to send inter-master requests, and cleaned up code
| author | Me@portablequad |
|---|---|
| date | Sat, 03 Sep 2011 20:41:51 -0700 |
| parents | ac11b50220bd |
| children | 24466227d8bb |
comparison
equal
deleted
inserted
replaced
| 32:5197c66f356b | 33:e829b6b0438c |
|---|---|
| 47 * from then on, will be doing continuation, but do suspension self | 47 * from then on, will be doing continuation, but do suspension self |
| 48 * directly at end of master loop | 48 * directly at end of master loop |
| 49 *So VMS__init just births the master virtual processor same way it births | 49 *So VMS__init just births the master virtual processor same way it births |
| 50 * all the others -- then does any extra setup needed and puts it into the | 50 * all the others -- then does any extra setup needed and puts it into the |
| 51 * work queue. | 51 * work queue. |
| 52 *However means have to make masterEnv a global static volatile the same way | 52 *However means have to make masterEnv a global static volatile. |
| 53 * did with readyToAnimateQ in core loop. -- for performance, put the | |
| 54 * jump to the core loop directly in here, and have it directly jump back. | |
| 55 * | 53 * |
| 56 * | 54 * |
| 57 *Aug 18, 2010 -- Going to a separate MasterVP for each core, to see if this | 55 *Aug 18, 2010 -- Going to a separate MasterVP for each core, to see if this |
| 58 * avoids the suspected bug in the system stack that causes bizarre faults | 56 * avoids the suspected bug in the system stack that causes bizarre faults |
| 59 * at random places in the system code. | 57 * at random places in the system code. |
| 60 * | 58 * |
| 61 *So, this function is coupled to each of the MasterVPs, -- meaning this | 59 *So, this function is coupled to each of the MasterVPs, -- meaning this |
| 62 * function can't rely on a particular stack and frame -- each MasterVP that | 60 * function can't rely on a particular stack and frame -- each MasterVP that |
| 63 * animates this function has a different one. | 61 * animates this function has a different stack. |
| 64 * | 62 * |
| 65 *At this point, the masterLoop does not write itself into the queue anymore, | 63 *At this point, the masterLoop does not write itself into the queue anymore, |
| 66 * instead, the coreLoop acquires the masterLock when it has nothing to | 64 * instead, the coreLoop acquires the masterLock when it has nothing to |
| 67 * animate, and then animates its own masterLoop. However, still try to put | 65 * animate, and then animates its own masterLoop. However, still try to put |
| 68 * several AppVPs into the queue to amortize the startup cost of switching | 66 * several AppVPs into the queue to amortize the startup cost of switching |
| 94 // of setup code.. (VP creator sets up the stack as if this function | 92 // of setup code.. (VP creator sets up the stack as if this function |
| 95 // was called normally, but actually get here by jmp) | 93 // was called normally, but actually get here by jmp) |
| 96 //So, setup values about stack ptr, jmp pt and all that | 94 //So, setup values about stack ptr, jmp pt and all that |
| 97 //masterPr->nextInstrPt = &&masterLoopStartPt; | 95 //masterPr->nextInstrPt = &&masterLoopStartPt; |
| 98 | 96 |
| 99 | 97 //Sept 2011 |
| 100 //Note, got rid of writing the stack and frame ptr up here, because | 98 //Old code jumped directly to this point, but doesn't work on x64 |
| 101 // only one | 99 // So, just make this an endless loop, and do assembly function at end |
| 102 // core can ever animate a given MasterVP, so don't need to communicate | 100 // that saves its own return addr, then jumps to core_loop. |
| 103 // new frame and stack ptr to the MasterVP storage before a second | 101 while(1) |
| 104 // version of that MasterVP can get animated on a different core. | 102 { |
| 105 //Also got rid of the busy-wait. | |
| 106 | |
| 107 | |
| 108 //masterLoopStartPt: | |
| 109 //The animating materVP suspends at end of this loop, then later resumes and | |
| 110 // comes back here | |
| 111 while(1){ | |
| 112 | 103 |
| 113 //============================= MEASUREMENT STUFF ======================== | 104 //============================= MEASUREMENT STUFF ======================== |
| 114 #ifdef MEAS__TIME_MASTER | 105 #ifdef MEAS__TIME_MASTER |
| 115 //Total Master time includes one coreloop time -- just assume the core | 106 //Total Master time includes one coreloop time -- just assume the core |
| 116 // loop time is same for Master as for AppVPs, even though it may be | 107 // loop time is same for Master as is for AppVPs, even though it may be |
| 117 // smaller due to higher predictability of the fixed jmp. | 108 // smaller due to higher predictability of the fixed jmp. |
| 118 saveLowTimeStampCountInto( masterPr->startMasterTSCLow ); | 109 saveLowTimeStampCountInto( masterPr->startMasterTSCLow ); |
| 119 #endif | 110 #endif |
| 120 //======================================================================== | 111 //======================================================================== |
| 121 | 112 |
| 122 masterEnv = (MasterEnv*)_VMSMasterEnv; | 113 masterEnv = (MasterEnv*)_VMSMasterEnv; |
| 123 | 114 |
| 124 //GCC may optimize so doesn't always re-define from frame-storage | 115 //GCC may optimize so doesn't always re-define from frame-storage |
| 125 masterPr = (VirtProcr*)volatileMasterPr; //on stack, to be sure after jmp | 116 masterPr = (VirtProcr*)volatileMasterPr; //on stack, reload after jmp |
| 126 thisCoresIdx = masterPr->coreAnimatedBy; | 117 thisCoresIdx = masterPr->coreAnimatedBy; |
| 127 readyToAnimateQ = masterEnv->readyToAnimateQs[thisCoresIdx]; | 118 readyToAnimateQ = masterEnv->readyToAnimateQs[thisCoresIdx]; |
| 128 schedSlots = masterEnv->allSchedSlots[thisCoresIdx]; | 119 schedSlots = masterEnv->allSchedSlots[thisCoresIdx]; |
| 129 | 120 |
| 130 requestHandler = masterEnv->requestHandler; | 121 requestHandler = masterEnv->requestHandler; |
| 131 slaveScheduler = masterEnv->slaveScheduler; | 122 slaveScheduler = masterEnv->slaveScheduler; |
| 132 semanticEnv = masterEnv->semanticEnv; | 123 semanticEnv = masterEnv->semanticEnv; |
| 133 | 124 |
| 134 //First, check for requests from other MasterVPs, and handle them | 125 //First, check for requests from other MasterVPs, and handle them |
| 135 if( masterEnv->requestsWaitingFor[thisCoresIdx] ) | 126 if( currReq = masterEnv->interMasterRequestsFor[thisCoresIdx] ) |
| 136 { masterReqQ = masterEnv->masterReqQs[thisCoresIdx]; | 127 { do |
| 137 while( currReq = readVMSQ(masterReqQ) ) | 128 { handleInterMasterReq( currReq, semanticEnv, masterPr ); |
| 138 { handleMasterReq( currReq, semanticEnv, masterPr ); | 129 } |
| 139 } | 130 while( currReq = currReq->nextReqst ); |
| 140 } | 131 } |
| 141 //Now, take care of the SlaveVPs | 132 //Now, take care of the SlaveVPs |
| 142 //Go through the slots -- if Slave there newly suspended, handle its request | 133 //Go through the slots -- if Slave there newly suspended, handle its request |
| 143 // then, either way, ask assigner to fill each slot | 134 // then, either way, ask assigner to fill each slot |
| 144 numSlotsFilled = 0; | 135 numSlotsFilled = 0; |
| 145 for( slotIdx = 0; slotIdx < NUM_SCHED_SLOTS; slotIdx++) | 136 for( slotIdx = 0; slotIdx < NUM_SCHED_SLOTS; slotIdx++) |
| 146 { | 137 { |
| 147 currSlot = schedSlots[ slotIdx ]; | 138 currSlot = schedSlots[ slotIdx ]; |
| 148 | 139 |
| 206 /*This is for inter-master communication. Either the master itself or | 197 /*This is for inter-master communication. Either the master itself or |
| 207 * the plugin sends one of these requests. Some are handled here, by the | 198 * the plugin sends one of these requests. Some are handled here, by the |
| 208 * master_loop, others are handed off to the plugin. | 199 * master_loop, others are handed off to the plugin. |
| 209 */ | 200 */ |
| 210 void inline | 201 void inline |
| 211 handleMasterReq( MasterReq *currReq, void *_semEnv, VirtProcr *masterPr ) | 202 handleInterMasterReq( InterMasterReqst *currReq, void *_semEnv, |
| 212 { | 203 VirtProcr *masterPr ) |
| 213 switch( currReq->reqType ) | 204 { switch( currReq->reqType ) |
| 214 { case interVMSReq: | 205 { case destVMSCore: |
| 215 handleInterVMSReq( (InterVMSCoreReq *)currReq, masterPr); | 206 handleInterVMSCoreReq( (InterVMSCoreReqst *)currReq, masterPr); |
| 216 break; | 207 break; |
| 217 case interPluginReq: | 208 case destPlugin: |
| 218 (*interPluginReqHdlr)( (InterPluginReq *)currReq, _semEnv ); | 209 (*interPluginReqHdlr)( ((InterPluginReqst *)currReq)->pluginReq, |
| 210 _semEnv ); | |
| 219 break; | 211 break; |
| 220 default: | 212 default: |
| 221 break; | 213 break; |
| 222 } | 214 } |
| 223 } | 215 } |
| 224 | 216 |
| 225 void inline | 217 void inline |
| 226 handleInterVMSReq( InterVMSCoreReq *currReq, VirtProcr *masterPr ) | 218 handleInterVMSReq( InterVMSCoreReqst *currReq, VirtProcr *masterPr ) |
| 227 { | 219 { |
| 228 switch( currReq->reqType ) | 220 switch( currReq->reqType ) |
| 229 { | 221 { |
| 230 case transfer_free: handleTransferFree( currReq, masterPr ); | 222 case transfer_free_ptr: handleTransferFree( currReq, masterPr ); |
| 231 break; | 223 break; |
| 232 } | 224 } |
| 233 } | 225 } |
| 226 | |
| 234 | 227 |
| 235 | 228 |
| 236 /*Work Stealing Alg -- racy one | 229 /*Work Stealing Alg -- racy one |
| 237 *This algorithm has a race condition -- the coreloops are accessing their | 230 *This algorithm has a race condition -- the coreloops are accessing their |
| 238 * own queues at the same time that this work-stealer on a different core | 231 * own queues at the same time that this work-stealer on a different core |
