diff MasterLoop.c @ 21:a0af8d4fca35

Full VMS test -- works
author Me
date Wed, 30 Jun 2010 13:10:34 -0700
parents e2de204909bf
children 668278fa7a63
line diff
     1.1 --- a/MasterLoop.c	Wed Jun 30 13:10:26 2010 -0700
     1.2 +++ b/MasterLoop.c	Wed Jun 30 13:10:34 2010 -0700
     1.3 @@ -47,12 +47,14 @@
     1.4   * jump to the core loop directly in here, and have it directly jump back.
     1.5   */
     1.6  void masterLoop( void *initData, VirtProcr *masterPr )
     1.7 - { bool8 retCode;
     1.8 -   int slotIdx, numScheduled, numInFirstChunk, filledSlotIdx;
     1.9 + { 
    1.10 +   int slotIdx, numFilled, numInFirstChunk, filledSlotIdx;
    1.11 +   VirtProcr      *schedVirtPr;
    1.12     SchedSlot      *currSlot, **schedSlots, **filledSlots;
    1.13     MasterEnv      *masterEnv;
    1.14     CASQueueStruc  *workQ;
    1.15 -   void           *jmpPt;
    1.16 +   void           *jmpPt, *stackPtrAddr, *framePtrAddr, *stillRunningAddr;
    1.17 +   void           *coreLoopFramePtr, *coreLoopStackPtr, *semanticEnv;
    1.18     
    1.19     SlaveScheduler  slaveScheduler;
    1.20     RequestHandler  requestHandler;
    1.21 @@ -68,12 +70,12 @@
    1.22  
    1.23        //if another reference to same Master VirtProcr still going, busy-wait
    1.24        //Could put this lower, but don't want to think about shared stack..
    1.25 -   masterEnv = _VMSMasterEnv;
    1.26 -   while( masterEnv->stillRunning ) /*busy wait*/ ;
    1.27 +   while( _VMSMasterEnv->stillRunning ) /*busy wait*/ ;
    1.28        //TODO: want to do busy-wait as assembly, to be sure stack not touched?
    1.29     
    1.30        //this is the only master running now, set flag again
    1.31 -   masterEnv->stillRunning = TRUE;
    1.32 +   _VMSMasterEnv->stillRunning = TRUE;
    1.33 +   masterEnv = _VMSMasterEnv;
    1.34  
    1.35        //TODO: gdb -- check that a volatile _VMSMasterEnv and _VMSWorkQ means
    1.36        // all these will be re-filled every time jump here..
    1.37 @@ -83,12 +85,12 @@
    1.38     schedSlots       = masterEnv->schedSlots;
    1.39     filledSlots      = masterEnv->filledSlots;
    1.40     masterPr         = masterEnv->masterVirtPr;  //post-jmp clobbered, re-load
    1.41 -   
    1.42 +   semanticEnv      = masterEnv->semanticEnv;
    1.43  
    1.44        //prepare for scheduling
    1.45     masterEnv->numFilled = 0;
    1.46  
    1.47 -      //Poll each slot's Done flag -- slot 0 reseved for master, start at 1
    1.48 +      //Poll each slot's Done flag -- slot 0 reserved for master, start at 1
    1.49     for( slotIdx = 1; slotIdx < NUM_SCHED_SLOTS; slotIdx++)
    1.50      {
    1.51        currSlot = schedSlots[ slotIdx ];
    1.52 @@ -99,42 +101,52 @@
    1.53           currSlot->needsProcrAssigned = TRUE;
    1.54  
    1.55              //process requests from slave to master
    1.56 -         (*requestHandler)( currSlot->procrAssignedToSlot->requests );
    1.57 +         (*requestHandler)( currSlot->procrAssignedToSlot, semanticEnv );
    1.58         }
    1.59        if( currSlot->needsProcrAssigned )
    1.60         {    //give slot a new virt procr
    1.61 -         retCode =
    1.62 -         (*slaveScheduler)( currSlot, masterEnv->semanticEnv );
    1.63 +         schedVirtPr =
    1.64 +          (*slaveScheduler)( semanticEnv );
    1.65           
    1.66 -         if( retCode == 1 )
    1.67 -          { int numFilled = masterEnv->numFilled;
    1.68 +         if( schedVirtPr != NULL )
    1.69 +          { currSlot->procrAssignedToSlot = schedVirtPr;
    1.70 +            schedVirtPr->schedSlot = currSlot;
    1.71  
    1.72 -            filledSlots[numFilled] = currSlot;
    1.73 +            filledSlots[ masterEnv->numFilled ] = currSlot;
    1.74              masterEnv->numFilled += 1;
    1.75  
    1.76              currSlot->needsProcrAssigned = FALSE;
    1.77            }
    1.78 -         else if( retCode == -1 ) //scheduler plug-in says to shut down VMS
    1.79 -          {
    1.80 -            //shutdown -- make "end Thd" virt-procs whose nextInstrPt is the
    1.81 -            // coreloop's EndCoreLoopPt -- causing a jump to the EndThread
    1.82 -            // and any other shut-down.
    1.83 -          }
    1.84         }
    1.85      }
    1.86  
    1.87 -      //put some scheduled slaves in, then continuation, then rest
    1.88 -   numInFirstChunk = masterEnv->numFilled / 2;  //tweak this from experiments
    1.89 -   for( filledSlotIdx = 0; filledSlotIdx < numInFirstChunk; filledSlotIdx++)
    1.90 +      //put some scheduled slaves in, then Master continuation, then rest
    1.91 +      //Adjust position of master such that it maintains close to a fixed
    1.92 +      // ratio --> make NUM_CORES - 1  slots or fewer come after the master
    1.93 +   numFilled    = masterEnv->numFilled;
    1.94 +   
    1.95 +   int numPrecede = numFilled;
    1.96 +   int numFollow  = NUM_CORES - 1;
    1.97 +   
    1.98 +   if( numFilled < numFollow )
    1.99 +    { numFollow  = numFilled;
   1.100 +      numPrecede = 0;
   1.101 +    }
   1.102 +   else
   1.103 +    { numPrecede -= numFollow;
   1.104 +    }
   1.105 +
   1.106 +   for( filledSlotIdx = 0; filledSlotIdx < numPrecede; filledSlotIdx++)
   1.107      {
   1.108        writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
   1.109      }
   1.110  
   1.111        //enqueue continuation of this loop
   1.112        // note that After this enqueue, continuation might sneak through
   1.113 -   writeCASQ( schedSlots[0]->procrAssignedToSlot, workQ );//master always slot 0
   1.114 -   for( filledSlotIdx = numInFirstChunk;
   1.115 -        filledSlotIdx < numScheduled;
   1.116 +   writeCASQ( masterEnv->masterVirtPr, workQ );
   1.117 +
   1.118 +   for( filledSlotIdx = numPrecede;
   1.119 +        filledSlotIdx < numFilled;
   1.120          filledSlotIdx++)
   1.121      {
   1.122        writeCASQ( filledSlots[ filledSlotIdx ]->procrAssignedToSlot, workQ );
   1.123 @@ -142,27 +154,42 @@
   1.124  
   1.125     masterEnv->numFilled = 0;
   1.126     
   1.127 -      //Don't want code above to try to look at requests in masterVirtPr,
   1.128 -      // so leave workDone at FALSE, but do want it to schedule into
   1.129 -      // the slot, so set needs procr assigned to TRUE.
   1.130 -   masterPr->schedSlot->needsProcrAssigned = TRUE;
   1.131  
   1.132        //Save stack ptr and frame -- don't need to, take out later, but safe
   1.133        // Also, wait to set stillRunning to FALSE until just before jump, to
   1.134 -      // protect stack might need to jmp directly to asm busy-wait to be
   1.135 -      // sure stack not touched
   1.136 -      //TODO: gdb check that busy-wait doesn't touch stack, so this is safe
   1.137 -      //don't need any regs to be valid when come back, so clobber list empty
   1.138 -      //TODO: gdb the jmp -- make sure it jumps through register or mem
   1.139 -   asm volatile("movl %%esp, %0; \
   1.140 -                 movl %%ebp, %1; \
   1.141 -                 movl  $0x0, %2; \
   1.142 -                 jmp     %3      "
   1.143 -   /* outputs */ : "=m" (masterPr->stackPtr), "=m" (masterPr->framePtr),
   1.144 -                   "=m" (masterEnv->stillRunning)
   1.145 -   /* inputs  */ : "r"  (masterPr->coreLoopStartPt)
   1.146 -   /* clobber */ 
   1.147 -                );
   1.148 +      // be safe -- although the two simulatneously animated MasterLoops
   1.149 +      // are on different cores, so have different stacks, so no worries
   1.150 +      // there.
   1.151 +      //Restore CoreLoop's stack frame (and stack pointer, to be safe)
   1.152 +      //TODO: cafefully verify don't need to force saving anything to stack
   1.153 +      // before jumping back to core loop.
   1.154 +   stackPtrAddr      = &(masterPr->stackPtr);
   1.155 +   framePtrAddr      = &(masterPr->framePtr);
   1.156 +   stillRunningAddr  = &(_VMSMasterEnv->stillRunning); //when race condition
   1.157 +      //arises, stillRunning is shared between the two cores both animating
   1.158 +      // MasterLoop -- but those two cores have different esp & ebp, so safe
   1.159 +      // to change stack and frame pointer here, without one messing up other
   1.160 +      // one
   1.161 +
   1.162 +   jmpPt             = masterPr->coreLoopStartPt;
   1.163 +   coreLoopFramePtr  = masterPr->coreLoopFramePtr;//need this only
   1.164 +   coreLoopStackPtr  = masterPr->coreLoopStackPtr;//shouldn't need -- safety
   1.165 +   
   1.166 +   asm volatile("movl %0,     %%eax;  \
   1.167 +                 movl %%esp, (%%eax); \
   1.168 +                 movl %1,     %%eax;  \
   1.169 +                 movl %%ebp, (%%eax); \
   1.170 +                 movl %2, %%ebx;      \
   1.171 +                 movl %3, %%eax;      \
   1.172 +                 movl %4, %%esp;      \
   1.173 +                 movl %5, %%ebp;      \
   1.174 +                 movl $0x0, (%%ebx);  \
   1.175 +                 jmp  %%eax "         \
   1.176 +   /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr),                \
   1.177 +                   "=g"(stillRunningAddr)                                   \
   1.178 +   /* inputs  */ : "g" (jmpPt), "g"(coreLoopStackPtr), "g"(coreLoopFramePtr)\
   1.179 +   /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
   1.180 +                );//can probably make clobber list empty -- but safe for now
   1.181   }
   1.182  
   1.183