comparison MasterLoop.c @ 18:734c665500e4

Kinda have test working -- assembly looks right for saving core loop frame and stack and restoring them But have a bug that looks timing-related, so thinking maybe some threads are going to completion? The whole test isn't quite right yet -- it throws exception because the suspended virtual processors never have a continuation put back into the workQ (is this right? Is that why it throws exception?) Want to move to full code to finish debugging
author Me
date Tue, 22 Jun 2010 12:37:43 -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,