Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view MasterLoop.c @ 9:a87d02855dee
Compiles -- with win thds -- still debugging assembly
| author | Me |
|---|---|
| date | Tue, 01 Jun 2010 05:33:40 -0700 |
| parents | ca61f77ed417 |
| children | e2de204909bf |
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <windows.h>
10 #include <stdio.h>
11 #include <malloc.h>
12 #include <stddef.h>
14 #include "VMS.h"
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 *
23 *Polls each virtual slave exactly once, hands any requests made by the slave
24 * to the "request handler" plug-in function
25 *
26 *Any slaves that have no work-unit assigned are given to the "schedule"
27 * plug-in function, which tries to assign a work-unit to it.
28 *
29 *When all slaves that need work-units have been given to the schedule plug-in,
30 * half of the ones that were successfully scheduled are put into the work
31 * queue, then a continuation of this function is put in, then the rest of the
32 * slaves that were successfully scheduled.
33 *
34 *The first thing this function does is busy-wait until the previous work-unit
35 * running this function is done. This ensures it doesn't overlap with
36 * tail-end of previous -- IE, continuation may sneak through queue before
37 * previous done putting second half of scheduled slaves in. This is the only
38 * race condition.
39 *
40 */
42 /*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
44 * from then on, will be doing continuation -- but do suspension self
45 * directly at end of master loop
46 *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
48 * work queue.
49 *However means have to make masterEnv a global static volatile the same way
50 * did with workQ in core loop. -- for performance, put the
51 * jump to core loop directly in here, and have it directly jump back.
52 */
53 void masterLoop( void *initData, VirtProcr *masterPr )
54 { bool8 success;
55 int slotIdx, numScheduled, numInFirstChunk, filledSlotIdx;
56 SchedSlot *currSlot, **schedSlots, **filledSlots;
57 MasterEnv *masterEnv;
58 QueueStruc *workQ;
59 // VirtProcr *masterPr;
60 void *jmpPt;
62 SlaveScheduler slaveScheduler;
63 RequestHandler requestHandler;
65 //this will run as the first virt processor in workQ, and will be a
66 // new born -- so will do all the GCC-generated allocating space on
67 // the stack owned by master virt procr -- and will run this last bit
68 // of setup code..
69 masterPr->nextInstrPt = &&masterLoopStartPt;
72 masterLoopStartPt:
74 //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..
76 while( masterEnv->stillRunning ) /*busy wait*/ ;
77 //TODO: want to do busy-wait as assembly, to be sure stack not touched?
79 //this is the only master running now, set flag again
80 masterEnv->stillRunning = TRUE;
82 //TODO: gdb -- check that a volatile _VMSMasterEnv and _VMSWorkQ means
83 // all these will be re-filled every time jump here..
84 workQ = _VMSWorkQ;
85 masterEnv = _VMSMasterEnv;
86 requestHandler = masterEnv->requestHandler;
87 slaveScheduler = masterEnv->slaveScheduler;
88 schedSlots = masterEnv->schedSlots;
89 filledSlots = masterEnv->filledSlots;
90 masterPr = masterEnv->masterVirtPr;
93 //prepare for scheduling
94 masterEnv->numFilled = 0;
96 //Poll each slot's Done flag -- slot 0 reseved for master, start at 1
97 for( slotIdx = 1; slotIdx < NUM_SCHED_SLOTS; slotIdx++)
98 {
99 currSlot = schedSlots[ slotIdx ];
101 if( currSlot->workIsDone )
102 {
103 currSlot->workIsDone = FALSE;
104 currSlot->needsProcrAssigned = TRUE;
106 //process requests from slave to master
107 (*requestHandler)( currSlot->procrAssignedToSlot->requests );
108 }
109 if( currSlot->needsProcrAssigned )
110 { //give slot a new virt procr
111 success =
112 (*slaveScheduler)( currSlot, masterEnv->semanticEnv );
114 if( success )
115 { int numFilled = masterEnv->numFilled;
117 filledSlots[numFilled] = currSlot;
118 masterEnv->numFilled += 1;
120 currSlot->needsProcrAssigned = FALSE;
121 }
122 }
123 }
125 //put some scheduled slaves in, then continuation, then rest
126 numInFirstChunk = masterEnv->numFilled / 2; //tweak this from experiments
127 for( filledSlotIdx = 0; filledSlotIdx < numInFirstChunk; filledSlotIdx++)
128 {
129 writeQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
130 }
132 //enqueue continuation of this loop
133 // note that After this enqueue, continuation might sneak through
134 writeQ( schedSlots[0]->procrAssignedToSlot, workQ );//master always slot 0
135 for( filledSlotIdx = numInFirstChunk;
136 filledSlotIdx < numScheduled;
137 filledSlotIdx++)
138 {
139 writeQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
140 }
142 masterEnv->numFilled = 0;
144 //Don't want code above to try to look at requests in masterVirtPr,
145 // so leave workDone at FALSE, but do want it to schedule into
146 // the slot, so set needs procr assigned to TRUE.
147 masterPr->schedSlot->needsProcrAssigned = TRUE;
149 //Save stack ptr and frame -- don't need to, take out later, but safe
150 // Also, wait to set stillRunning to FALSE until just before jump, to
151 // protect stack might need to jmp directly to asm busy-wait to be
152 // sure stack not touched
153 //TODO: gdb check that busy-wait doesn't touch stack, so this is safe
154 //don't need any regs to be valid when come back, so clobber list empty
155 //TODO: gdb the jmp -- make sure it jumps through register or mem
156 asm volatile("movl %%esp, %0; \
157 movl %%ebp, %1; \
158 movl $0x0, %2; \
159 jmp %3 "
160 /* outputs */ : "=m" (masterPr->stackPtr), "=m" (masterPr->framePtr),
161 "=m" (masterEnv->stillRunning)
162 /* inputs */ : "r" (masterPr->coreLoopStartPt)
163 /* clobber */
164 );
165 }
