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