Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view 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 |
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 *
20 *Polls each sched slot exactly once, hands any requests made by a newly
21 * done slave to the "request handler" plug-in function
22 *
23 *Any slots that need a virt procr assigned are given to the "schedule"
24 * plug-in function, which tries to assign a virt procr (slave) to it.
25 *
26 *When all slots needing a processor have been given to the schedule plug-in,
27 * a fraction of the procrs successfully scheduled are put into the
28 * work queue, then a continuation of this function is put in, then the rest
29 * of the virt procrs that were successfully scheduled.
30 *
31 *The first thing the continuation does is busy-wait until the previous
32 * animation completes. This is because an (unlikely) continuation may
33 * sneak through queue before previous continuation is done putting second
34 * part of scheduled slaves in, which is the only race condition.
35 *
36 */
38 /*May 29, 2010 -- birth a Master during init so that first core loop to
39 * start running gets it and does all the stuff for a newly born --
40 * from then on, will be doing continuation, but do suspension self
41 * directly at end of master loop
42 *So VMS__init just births the master virtual processor same way it births
43 * all the others -- then does any extra setup needed and puts it into the
44 * work queue.
45 *However means have to make masterEnv a global static volatile the same way
46 * 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.
48 */
49 void masterLoop( void *initData, VirtProcr *masterPr )
50 { bool8 retCode;
51 int slotIdx, numScheduled, numInFirstChunk, filledSlotIdx;
52 SchedSlot *currSlot, **schedSlots, **filledSlots;
53 MasterEnv *masterEnv;
54 CASQueueStruc *workQ;
55 void *jmpPt;
57 SlaveScheduler slaveScheduler;
58 RequestHandler requestHandler;
60 //this will run as the first virt processor in workQ, and will be a
61 // new born -- so will do all the GCC-generated allocating space on
62 // the stack owned by master virt procr -- and will run this last bit
63 // of setup code..
64 masterPr->nextInstrPt = &&masterLoopStartPt;
67 masterLoopStartPt:
69 //if another reference to same Master VirtProcr still going, busy-wait
70 //Could put this lower, but don't want to think about shared stack..
71 masterEnv = _VMSMasterEnv;
72 while( masterEnv->stillRunning ) /*busy wait*/ ;
73 //TODO: want to do busy-wait as assembly, to be sure stack not touched?
75 //this is the only master running now, set flag again
76 masterEnv->stillRunning = TRUE;
78 //TODO: gdb -- check that a volatile _VMSMasterEnv and _VMSWorkQ means
79 // all these will be re-filled every time jump here..
80 workQ = _VMSWorkQ;
81 requestHandler = masterEnv->requestHandler;
82 slaveScheduler = masterEnv->slaveScheduler;
83 schedSlots = masterEnv->schedSlots;
84 filledSlots = masterEnv->filledSlots;
85 masterPr = masterEnv->masterVirtPr; //post-jmp clobbered, re-load
88 //prepare for scheduling
89 masterEnv->numFilled = 0;
91 //Poll each slot's Done flag -- slot 0 reseved for master, start at 1
92 for( slotIdx = 1; slotIdx < NUM_SCHED_SLOTS; slotIdx++)
93 {
94 currSlot = schedSlots[ slotIdx ];
96 if( currSlot->workIsDone )
97 {
98 currSlot->workIsDone = FALSE;
99 currSlot->needsProcrAssigned = TRUE;
101 //process requests from slave to master
102 (*requestHandler)( currSlot->procrAssignedToSlot->requests );
103 }
104 if( currSlot->needsProcrAssigned )
105 { //give slot a new virt procr
106 retCode =
107 (*slaveScheduler)( currSlot, masterEnv->semanticEnv );
109 if( retCode == 1 )
110 { int numFilled = masterEnv->numFilled;
112 filledSlots[numFilled] = currSlot;
113 masterEnv->numFilled += 1;
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.
122 }
123 }
124 }
126 //put some scheduled slaves in, then continuation, then rest
127 numInFirstChunk = masterEnv->numFilled / 2; //tweak this from experiments
128 for( filledSlotIdx = 0; filledSlotIdx < numInFirstChunk; filledSlotIdx++)
129 {
130 writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
131 }
133 //enqueue continuation of this loop
134 // note that After this enqueue, continuation might sneak through
135 writeCASQ( schedSlots[0]->procrAssignedToSlot, workQ );//master always slot 0
136 for( filledSlotIdx = numInFirstChunk;
137 filledSlotIdx < numScheduled;
138 filledSlotIdx++)
139 {
140 writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
141 }
143 masterEnv->numFilled = 0;
145 //Don't want code above to try to look at requests in masterVirtPr,
146 // so leave workDone at FALSE, but do want it to schedule into
147 // the slot, so set needs procr assigned to TRUE.
148 masterPr->schedSlot->needsProcrAssigned = TRUE;
150 //Save stack ptr and frame -- don't need to, take out later, but safe
151 // Also, wait to set stillRunning to FALSE until just before jump, to
152 // protect stack might need to jmp directly to asm busy-wait to be
153 // sure stack not touched
154 //TODO: gdb check that busy-wait doesn't touch stack, so this is safe
155 //don't need any regs to be valid when come back, so clobber list empty
156 //TODO: gdb the jmp -- make sure it jumps through register or mem
157 asm volatile("movl %%esp, %0; \
158 movl %%ebp, %1; \
159 movl $0x0, %2; \
160 jmp %3 "
161 /* outputs */ : "=m" (masterPr->stackPtr), "=m" (masterPr->framePtr),
162 "=m" (masterEnv->stillRunning)
163 /* inputs */ : "r" (masterPr->coreLoopStartPt)
164 /* clobber */
165 );
166 }
