Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison MasterLoop.c @ 26:668278fa7a63
Sequential -- just starting to add sequential version
| author | Me |
|---|---|
| date | Mon, 26 Jul 2010 15:25:53 -0700 |
| parents | a0af8d4fca35 |
| children | 5a2068cbc28b |
comparison
equal
deleted
inserted
replaced
| 4:a6f548e8b898 | 5:7378ed18a43c |
|---|---|
| 4 * Licensed under BSD | 4 * Licensed under BSD |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 #include <windows.h> | |
| 10 #include <stdio.h> | 9 #include <stdio.h> |
| 11 #include <malloc.h> | 10 #include <malloc.h> |
| 12 #include <stddef.h> | 11 #include <stddef.h> |
| 13 | 12 |
| 14 #include "VMS.h" | 13 #include "VMS.h" |
| 46 * did with workQ in core loop. -- for performance, put the | 45 * did with workQ in core loop. -- for performance, put the |
| 47 * jump to the core loop directly in here, and have it directly jump back. | 46 * jump to the core loop directly in here, and have it directly jump back. |
| 48 */ | 47 */ |
| 49 void masterLoop( void *initData, VirtProcr *masterPr ) | 48 void masterLoop( void *initData, VirtProcr *masterPr ) |
| 50 { | 49 { |
| 51 int slotIdx, numFilled, numInFirstChunk, filledSlotIdx; | 50 int slotIdx, numFilled, filledSlotIdx, masterHasBeenQueued; |
| 52 VirtProcr *schedVirtPr; | 51 VirtProcr *schedVirtPr; |
| 53 SchedSlot *currSlot, **schedSlots, **filledSlots; | 52 SchedSlot *currSlot, **schedSlots, **filledSlots; |
| 54 MasterEnv *masterEnv; | 53 MasterEnv *masterEnv; |
| 55 CASQueueStruc *workQ; | 54 VMSQueueStruc *workQ; |
| 56 void *jmpPt, *stackPtrAddr, *framePtrAddr, *stillRunningAddr; | 55 void *jmpPt, *stackPtrAddr, *framePtrAddr, *stillRunningAddr; |
| 57 void *coreLoopFramePtr, *coreLoopStackPtr, *semanticEnv; | 56 void *coreLoopFramePtr, *coreLoopStackPtr, *semanticEnv; |
| 58 | 57 |
| 59 SlaveScheduler slaveScheduler; | 58 SlaveScheduler slaveScheduler; |
| 60 RequestHandler requestHandler; | 59 RequestHandler requestHandler; |
| 63 // new born -- so will do all the GCC-generated allocating space on | 62 // new born -- so will do all the GCC-generated allocating space on |
| 64 // the stack owned by master virt procr -- and will run this last bit | 63 // the stack owned by master virt procr -- and will run this last bit |
| 65 // of setup code.. | 64 // of setup code.. |
| 66 masterPr->nextInstrPt = &&masterLoopStartPt; | 65 masterPr->nextInstrPt = &&masterLoopStartPt; |
| 67 | 66 |
| 68 | 67 //The second time MasterVP comes out of queue, the first animation of |
| 68 // it hasn't written the stackPtr and framePtr yet -- but the second | |
| 69 // animation has already had its stackPtr and framePtr set to the old | |
| 70 // value by the coreLoop. Fix this by writing the correct stack and | |
| 71 // frame pointers here, at which point they're correct in the first | |
| 72 // animation of MasterVP. | |
| 73 //TODO: remove writing stackPtr and framePtr at the bottom, for eff | |
| 74 stackPtrAddr = &(masterPr->stackPtr); | |
| 75 framePtrAddr = &(masterPr->framePtr); | |
| 76 | |
| 77 asm volatile("movl %0, %%eax; \ | |
| 78 movl %%esp, (%%eax); \ | |
| 79 movl %1, %%eax; \ | |
| 80 movl %%ebp, (%%eax); " | |
| 81 /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr) \ | |
| 82 /* inputs */ : \ | |
| 83 /* clobber */ : "memory", "%eax", "%ebx" \ | |
| 84 ); | |
| 85 | |
| 86 | |
| 69 masterLoopStartPt: | 87 masterLoopStartPt: |
| 70 | 88 |
| 71 //if another reference to same Master VirtProcr still going, busy-wait | 89 //if another reference to same Master VirtProcr still going, busy-wait |
| 72 //Could put this lower, but don't want to think about shared stack.. | 90 //Could put this lower, but don't want to think about shared stack.. |
| 73 while( _VMSMasterEnv->stillRunning ) /*busy wait*/ ; | 91 while( _VMSMasterEnv->stillRunning ) /*busy wait*/ ; |
| 86 filledSlots = masterEnv->filledSlots; | 104 filledSlots = masterEnv->filledSlots; |
| 87 masterPr = masterEnv->masterVirtPr; //post-jmp clobbered, re-load | 105 masterPr = masterEnv->masterVirtPr; //post-jmp clobbered, re-load |
| 88 semanticEnv = masterEnv->semanticEnv; | 106 semanticEnv = masterEnv->semanticEnv; |
| 89 | 107 |
| 90 //prepare for scheduling | 108 //prepare for scheduling |
| 91 masterEnv->numFilled = 0; | 109 numFilled = 0; |
| 110 masterHasBeenQueued = FALSE; | |
| 92 | 111 |
| 93 //Poll each slot's Done flag -- slot 0 reserved for master, start at 1 | 112 //Poll each slot's Done flag -- slot 0 reserved for master, start at 1 |
| 94 for( slotIdx = 1; slotIdx < NUM_SCHED_SLOTS; slotIdx++) | 113 for( slotIdx = 0; slotIdx < NUM_SCHED_SLOTS; slotIdx++) |
| 95 { | 114 { |
| 96 currSlot = schedSlots[ slotIdx ]; | 115 currSlot = schedSlots[ slotIdx ]; |
| 97 | 116 |
| 98 if( currSlot->workIsDone ) | 117 if( currSlot->workIsDone ) |
| 99 { | 118 { |
| 108 schedVirtPr = | 127 schedVirtPr = |
| 109 (*slaveScheduler)( semanticEnv ); | 128 (*slaveScheduler)( semanticEnv ); |
| 110 | 129 |
| 111 if( schedVirtPr != NULL ) | 130 if( schedVirtPr != NULL ) |
| 112 { currSlot->procrAssignedToSlot = schedVirtPr; | 131 { currSlot->procrAssignedToSlot = schedVirtPr; |
| 113 schedVirtPr->schedSlot = currSlot; | 132 schedVirtPr->schedSlot = currSlot; |
| 114 | 133 currSlot->needsProcrAssigned = FALSE; |
| 115 filledSlots[ masterEnv->numFilled ] = currSlot; | 134 |
| 116 masterEnv->numFilled += 1; | 135 filledSlots[ numFilled ] = currSlot; |
| 117 | 136 numFilled += 1; |
| 118 currSlot->needsProcrAssigned = FALSE; | 137 |
| 138 writeVMSQ( schedVirtPr, workQ ); | |
| 139 if( numFilled == masterEnv->numToPrecede ) | |
| 140 { | |
| 141 writeVMSQ( masterEnv->masterVirtPr, workQ ); | |
| 142 masterHasBeenQueued = TRUE; | |
| 143 } | |
| 144 | |
| 119 } | 145 } |
| 120 } | 146 } |
| 121 } | 147 } |
| 122 | 148 |
| 149 if( !masterHasBeenQueued ) | |
| 150 { | |
| 151 writeVMSQ( masterEnv->masterVirtPr, workQ ); | |
| 152 } | |
| 153 | |
| 154 //Adjust the number to precede, for next round -- assume rate of | |
| 155 // finishing work is stable -- which is a bad assumption! But, just | |
| 156 // want something working for the moment, look at dynamic behavior | |
| 157 // later | |
| 158 //TODO: look at dynamic behavior -- time-average numToPrecede or something | |
| 159 if( numFilled < NUM_CORES - 1 ) | |
| 160 { | |
| 161 masterEnv->numToPrecede = 0; | |
| 162 } | |
| 163 else | |
| 164 { masterEnv->numToPrecede = numFilled - NUM_CORES + 1; | |
| 165 } | |
| 166 /* | |
| 123 //put some scheduled slaves in, then Master continuation, then rest | 167 //put some scheduled slaves in, then Master continuation, then rest |
| 124 //Adjust position of master such that it maintains close to a fixed | 168 //Adjust position of master such that it maintains close to a fixed |
| 125 // ratio --> make NUM_CORES - 1 slots or fewer come after the master | 169 // ratio --> make NUM_CORES - 1 slots or fewer come after the master |
| 126 numFilled = masterEnv->numFilled; | 170 |
| 127 | |
| 128 int numPrecede = numFilled; | |
| 129 int numFollow = NUM_CORES - 1; | |
| 130 | |
| 131 if( numFilled < numFollow ) | |
| 132 { numFollow = numFilled; | |
| 133 numPrecede = 0; | |
| 134 } | |
| 135 else | |
| 136 { numPrecede -= numFollow; | |
| 137 } | |
| 138 | |
| 139 for( filledSlotIdx = 0; filledSlotIdx < numPrecede; filledSlotIdx++) | 171 for( filledSlotIdx = 0; filledSlotIdx < numPrecede; filledSlotIdx++) |
| 140 { | 172 { |
| 141 writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); | 173 writeVMSQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); |
| 142 } | 174 } |
| 143 | 175 |
| 144 //enqueue continuation of this loop | 176 //enqueue continuation of this loop |
| 145 // note that After this enqueue, continuation might sneak through | 177 // note that After this enqueue, continuation might sneak through |
| 146 writeCASQ( masterEnv->masterVirtPr, workQ ); | 178 writeVMSQ( masterEnv->masterVirtPr, workQ ); |
| 147 | 179 |
| 148 for( filledSlotIdx = numPrecede; | 180 for( filledSlotIdx = numPrecede; |
| 149 filledSlotIdx < numFilled; | 181 filledSlotIdx < numFilled; |
| 150 filledSlotIdx++) | 182 filledSlotIdx++) |
| 151 { | 183 { |
| 152 writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); | 184 writeVMSQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ ); |
| 153 } | 185 } |
| 154 | 186 |
| 155 masterEnv->numFilled = 0; | 187 masterEnv->numFilled = 0; |
| 156 | 188 */ |
| 157 | 189 |
| 158 //Save stack ptr and frame -- don't need to, take out later, but safe | 190 //Save stack ptr and frame -- don't need to, take out later, but safe |
| 159 // Also, wait to set stillRunning to FALSE until just before jump, to | 191 // Also, wait to set stillRunning to FALSE until just before jump, to |
| 160 // be safe -- although the two simulatneously animated MasterLoops | 192 // be safe -- although the two simulatneously animated MasterLoops |
| 161 // are on different cores, so have different stacks, so no worries | 193 // are on different cores, so have different stacks, so no worries |
