Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view MasterLoop.c @ 5:6c518bda83fe
About to chg to win thds -- good except for that
| author | Me |
|---|---|
| date | Mon, 31 May 2010 19:15:14 -0700 |
| parents | a5fe730dfc2e |
| children | a87d02855dee |
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <stdio.h>
10 #include <malloc.h>
12 #include "VMS.h"
16 /*This code is animated by the virtual Master processor.
17 *Note, it is animated on a different level in virtual processor hierarchy
18 * than the CoreLoop -- this is the code pointed to in a work-unit that the
19 * coreLoop jumps to
20 *
21 *Polls each virtual slave exactly once, hands any requests made by the slave
22 * to the "request handler" plug-in function
23 *
24 *Any slaves that have no work-unit assigned are given to the "schedule"
25 * plug-in function, which tries to assign a work-unit to it.
26 *
27 *When all slaves that need work-units have been given to the schedule plug-in,
28 * half of the ones that were successfully scheduled are put into the work
29 * queue, then a continuation of this function is put in, then the rest of the
30 * slaves that were successfully scheduled.
31 *
32 *The first thing this function does is busy-wait until the previous work-unit
33 * running this function is done. This ensures it doesn't overlap with
34 * tail-end of previous -- IE, continuation may sneak through queue before
35 * previous done putting second half of scheduled slaves in. This is the only
36 * race condition.
37 *
38 */
40 /*May 29, 2010 -- birth a Master during init so that first core loop to
41 * start running gets it and does all the stuff for a newly born
42 * from then on, will be doing continuation -- but do suspension self
43 * directly at end of master loop
44 *So VMS__init just births the master virtual processor same way it births
45 * all the others -- then does any extra setup needed and puts it into the
46 * work queue.
47 *However means have to make masterEnv a global static volatile the same way
48 * did with workQ in core loop. -- for performance, put the
49 * jump to core loop directly in here, and have it directly jump back.
50 */
51 void masterLoop( void *initData, VirtProcr *masterPr )
52 { bool8 success;
53 int slotIdx, numScheduled, numInFirstChunk, filledSlotIdx;
54 SchedSlot *currSlot, **schedSlots, **filledSlots;
55 MasterEnv *masterEnv;
56 QueueStruc *workQ;
57 // VirtProcr *masterPr;
58 void *jmpPt;
60 SlaveScheduler slaveScheduler;
61 RequestHandler requestHandler;
63 //this will run as the first virt processor in workQ, and will be a
64 // new born -- so will do all the GCC-generated allocating space on
65 // the stack owned by master virt procr -- and will run this last bit
66 // of setup code..
67 masterPr->nextInstrPt = &&masterLoopStartPt;
70 masterLoopStartPt:
72 //if another reference to same Master VirtProcr still going, busy-wait
73 //Could put this lower, but don't want to think about shared stack..
74 while( masterEnv->stillRunning ) /*busy wait*/ ;
75 //TODO: want to do busy-wait as assembly, to be sure stack not touched?
77 //this is the only master running now, set flag again
78 masterEnv->stillRunning = TRUE;
80 //TODO: gdb -- check that a volatile _VMSMasterEnv and _VMSWorkQ means
81 // all these will be re-filled every time jump here..
82 workQ = _VMSWorkQ;
83 masterEnv = _VMSMasterEnv;
84 requestHandler = masterEnv->requestHandler;
85 slaveScheduler = masterEnv->slaveScheduler;
86 schedSlots = masterEnv->schedSlots;
87 filledSlots = masterEnv->filledSlots;
88 masterPr = masterEnv->masterVirtPr;
91 //prepare for scheduling
92 masterEnv->numFilled = 0;
94 //Poll each slot's Done flag -- slot 0 reseved for master, start at 1
95 for( slotIdx = 1; slotIdx < NUM_SCHED_SLOTS; slotIdx++)
96 {
97 currSlot = schedSlots[ slotIdx ];
99 if( currSlot->workIsDone )
100 {
101 currSlot->workIsDone = FALSE;
102 currSlot->needsProcrAssigned = TRUE;
104 //process requests from slave to master
105 (*requestHandler)( currSlot->procrAssignedToSlot->requests );
106 }
107 if( currSlot->needsProcrAssigned )
108 { //give slot a new virt procr
109 success =
110 (*slaveScheduler)( currSlot, masterEnv->semanticEnv );
112 if( success )
113 { int numFilled = masterEnv->numFilled;
115 filledSlots[numFilled] = currSlot;
116 masterEnv->numFilled += 1;
118 currSlot->needsProcrAssigned = FALSE;
119 }
120 }
121 }
123 //put some scheduled slaves in, then continuation, then rest
124 numInFirstChunk = masterEnv->numFilled / 2; //tweak this from experiments
125 for( filledSlotIdx = 0; filledSlotIdx < numInFirstChunk; filledSlotIdx++)
126 {
127 writeQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
128 }
130 //enqueue continuation of this loop
131 // note that After this enqueue, continuation might sneak through
132 writeQ( schedSlots[0]->procrAssignedToSlot, workQ );//master always slot 0
133 for( filledSlotIdx = numInFirstChunk;
134 filledSlotIdx < numScheduled;
135 filledSlotIdx++)
136 {
137 writeQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
138 }
140 masterEnv->numFilled = 0;
142 //Don't want code above to try to look at requests in masterVirtPr,
143 // so leave workDone at FALSE, but do want it to schedule into
144 // the slot, so set needs procr assigned to TRUE.
145 masterPr->schedSlot->needsProcrAssigned = TRUE;
147 //Save stack ptr and frame -- don't need to, take out later, but safe
148 // Also, wait to set stillRunning to FALSE until just before jump, to
149 // protect stack might need to jmp directly to asm busy-wait to be
150 // sure stack not touched
151 //TODO: gdb check that busy-wait doesn't touch stack, so this is safe
152 //don't need any regs to be valid when come back, so clobber list empty
153 //TODO: gdb the jmp -- make sure it jumps through register or mem
154 asm volatile("movl %%esp, %0; \
155 movl %%ebp, %1; \
156 movl $0x0, %2; \
157 jmp %3 "
158 /* outputs */ : "=m" (masterPr->stackPtr), "=m" (masterPr->framePtr),
159 "=m" (masterEnv->stillRunning)
160 /* inputs */ : "r" (masterPr->coreLoopStartPt)
161 /* clobber */
162 );
163 }
