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,