Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view MasterLoop.c @ 53:42dd44df1bb0
Init changed to only use VMS__malloc & uses VMS__malloc versions of utilities
| author | Me |
|---|---|
| date | Mon, 01 Nov 2010 21:21:32 -0700 |
| parents | 8f7141a9272e |
| children | 3bac84e4e56e |
line source
1 /*
2 * Copyright 2010 OpenSourceStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <stdio.h>
10 #include <stddef.h>
12 #include "VMS.h"
16 /*This code is animated by the virtual Master processor.
17 *
18 *Polls each sched slot exactly once, hands any requests made by a newly
19 * done slave to the "request handler" plug-in function
20 *
21 *Any slots that need a virt procr assigned are given to the "schedule"
22 * plug-in function, which tries to assign a virt procr (slave) to it.
23 *
24 *When all slots needing a processor have been given to the schedule plug-in,
25 * a fraction of the procrs successfully scheduled are put into the
26 * work queue, then a continuation of this function is put in, then the rest
27 * of the virt procrs that were successfully scheduled.
28 *
29 *The first thing the continuation does is busy-wait until the previous
30 * animation completes. This is because an (unlikely) continuation may
31 * sneak through queue before previous continuation is done putting second
32 * part of scheduled slaves in, which is the only race condition.
33 *
34 */
36 /*May 29, 2010 -- birth a Master during init so that first core loop to
37 * start running gets it and does all the stuff for a newly born --
38 * from then on, will be doing continuation, but do suspension self
39 * directly at end of master loop
40 *So VMS__init just births the master virtual processor same way it births
41 * all the others -- then does any extra setup needed and puts it into the
42 * work queue.
43 *However means have to make masterEnv a global static volatile the same way
44 * did with readyToAnimateQ in core loop. -- for performance, put the
45 * jump to the core loop directly in here, and have it directly jump back.
46 *
47 *
48 *Aug 18, 2010 -- Going to a separate MasterVP for each core, to see if this
49 * avoids the suspected bug in the system stack that causes bizarre faults
50 * at random places in the system code.
51 *
52 *So, this function is coupled to each of the MasterVPs, -- meaning this
53 * function can't rely on a particular stack and frame -- each MasterVP that
54 * animates this function has a different one.
55 *
56 *At this point, the masterLoop does not write itself into the queue anymore,
57 * instead, the coreLoop acquires the masterLock when it has nothing to
58 * animate, and then animates its own masterLoop. However, still try to put
59 * several AppVPs into the queue to amortize the startup cost of switching
60 * to the MasterVP. Note, don't have to worry about latency of requests much
61 * because most requests generate work for same core -- only latency issue
62 * is case when other cores starved and one core's requests generate work
63 * for them -- so keep max in queue to 3 or 4..
64 */
65 void masterLoop( void *initData, VirtProcr *animatingPr )
66 {
67 int slotIdx;
68 VirtProcr *schedVirtPr;
69 SchedSlot *currSlot, **schedSlots;
70 MasterEnv *masterEnv;
71 VMSQueueStruc *readyToAnimateQ;
73 SlaveScheduler slaveScheduler;
74 RequestHandler requestHandler;
75 void *semanticEnv;
77 int thisCoresIdx;
78 VirtProcr *masterPr;
79 volatile VirtProcr *volatileMasterPr;
81 volatileMasterPr = animatingPr;
82 masterPr = volatileMasterPr; //used to force re-define after jmp
84 //First animation of each MasterVP will in turn animate this part
85 // of setup code.. (VP creator sets up the stack as if this function
86 // was called normally, but actually get here by jmp)
87 //So, setup values about stack ptr, jmp pt and all that
88 masterPr->nextInstrPt = &&masterLoopStartPt;
91 //Note, got rid of writing the stack and frame ptr up here, because
92 // only one
93 // core can ever animate a given MasterVP, so don't need to communicate
94 // new frame and stack ptr to the MasterVP storage before a second
95 // version of that MasterVP can get animated on a different core.
96 //Also got rid of the busy-wait.
99 masterLoopStartPt:
100 //============================= MEASUREMENT STUFF ========================
101 #ifdef MEAS__TIME_MASTER
102 //Total Master time includes one coreloop time -- just assume the core
103 // loop time is same for Master as for AppVPs, even though it will be
104 // smaller due to high predictability of the fixed jmp.
105 saveLowTimeStampCountInto( masterPr->startMasterTSCLow );
106 #endif
107 //========================================================================
109 masterEnv = _VMSMasterEnv;
111 //TODO: check that compiles so that always re-define from frame-storage
112 masterPr = volatileMasterPr; //just to make sure after jmp
113 thisCoresIdx = masterPr->coreAnimatedBy;
114 readyToAnimateQ = masterEnv->readyToAnimateQs[thisCoresIdx];
115 schedSlots = masterEnv->allSchedSlots[thisCoresIdx];
117 requestHandler = masterEnv->requestHandler;
118 slaveScheduler = masterEnv->slaveScheduler;
119 semanticEnv = masterEnv->semanticEnv;
122 //Poll each slot's Done flag
123 for( slotIdx = 0; slotIdx < NUM_SCHED_SLOTS; slotIdx++)
124 {
125 currSlot = schedSlots[ slotIdx ];
127 if( currSlot->workIsDone )
128 {
129 currSlot->workIsDone = FALSE;
130 currSlot->needsProcrAssigned = TRUE;
132 //process requests from slave to master
133 (*requestHandler)( currSlot->procrAssignedToSlot, semanticEnv );
134 }
135 if( currSlot->needsProcrAssigned )
136 { //give slot a new virt procr
137 schedVirtPr =
138 (*slaveScheduler)( semanticEnv, thisCoresIdx );
140 if( schedVirtPr != NULL )
141 { currSlot->procrAssignedToSlot = schedVirtPr;
142 schedVirtPr->schedSlot = currSlot;
143 currSlot->needsProcrAssigned = FALSE;
145 writeSRSWQ( schedVirtPr, readyToAnimateQ );
146 }
147 }
148 }
151 //Save stack ptr and frame, restore CoreLoop's stack and frame,
152 // and clear the MasterLock
153 //TODO: cafefully verify don't need to force saving anything to stack
154 // before jumping back to core loop.
155 void *stackPtrAddr, *framePtrAddr, *masterLockAddr;
156 void *jmpPt, *coreLoopFramePtr, *coreLoopStackPtr;
158 stackPtrAddr = &(masterPr->stackPtr);
159 framePtrAddr = &(masterPr->framePtr);
160 masterLockAddr = &(_VMSMasterEnv->masterLock);
162 jmpPt = _VMSMasterEnv->coreLoopStartPt;
163 coreLoopFramePtr = masterPr->coreLoopFramePtr;//need this only
164 coreLoopStackPtr = masterPr->coreLoopStackPtr;//shouldn't need -- safety
166 #ifdef MEAS__TIME_MASTER
167 saveLowTimeStampCountInto( masterPr->endMasterTSCLow );
168 #endif
170 asm volatile("movl %0, %%eax; \
171 movl %%esp, (%%eax); \
172 movl %1, %%eax; \
173 movl %%ebp, (%%eax); \
174 movl %2, %%ebx; \
175 movl %3, %%eax; \
176 movl %4, %%esp; \
177 movl %5, %%ebp; \
178 movl $0x0, (%%ebx); \
179 jmp %%eax;" \
180 /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr), \
181 "=g"(masterLockAddr) \
182 /* inputs */ : "g" (jmpPt), "g"(coreLoopStackPtr), "g"(coreLoopFramePtr)\
183 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
184 );//can probably make clobber list empty -- but safe for now
185 }
