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