diff AnimationMaster.c @ 272:bc5030385120

Progress -- back to compile process, fixing compile issues
author Sean Halle <seanhalle@yahoo.com>
date Tue, 05 Feb 2013 20:23:27 -0800
parents 292393c6bef1
children 40e7625e57bd
line diff
     1.1 --- a/AnimationMaster.c	Wed Jan 16 01:50:26 2013 -0800
     1.2 +++ b/AnimationMaster.c	Tue Feb 05 20:23:27 2013 -0800
     1.3 @@ -19,79 +19,37 @@
     1.4  void        PRHandle_Dissipate_SL(SlaveVP *slave);
     1.5  void        PR_int__handle_PRServiceReq_SL(SlaveVP *slave);
     1.6  */
     1.7 -inline void PRHandle_CreateTask( PRReqst *req, SlaveVP *slave );
     1.8 -inline void PRHandle_EndTask(    PRReqst *req, SlaveVP *slave );
     1.9 -inline void PRHandle_CreateSlave(PRReqst *req, SlaveVP *slave );
    1.10 -void        PRHandle_EndSlave(  PRReqst *req, SlaveVP *slave );
    1.11 +inline void PRHandle__CreateTask( PRReqst *req, SlaveVP *slave );
    1.12 +inline void PRHandle__EndTask(    PRReqst *req, SlaveVP *slave );
    1.13 +inline void PRHandle__CreateSlave(PRReqst *req, SlaveVP *slave );
    1.14 +void        PRHandle__EndSlave(  PRReqst *req, SlaveVP *slave );
    1.15  
    1.16  
    1.17  //inline void  masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot );
    1.18  inline PRProcess * pickAProcess( AnimSlot *slot );
    1.19  inline bool32 assignWork( PRProcess *process, AnimSlot *slot );
    1.20  
    1.21 -/*The animationMaster embodies most of the animator of the language.  The
    1.22 - * animator is what emodies the behavior of language constructs. 
    1.23 - * As such, it is the animationMaster, in combination with the plugin
    1.24 - * functions, that make the language constructs do their behavior.   
    1.25 - * 
    1.26 - *Within the code, this is the top-level-function of the masterVPs, and
    1.27 - * runs when the coreController has no more slave VPs.  It's job is to
    1.28 - * refill the animation slots with slaves that have work.
    1.29 - *
    1.30 - *There are multiple versions of the master, each tuned to a specific 
    1.31 - * combination of modes.  This keeps the master simple, with reduced overhead,
    1.32 - * when the application is not using the extra complexity.
    1.33 - * 
    1.34 - *As of Sept 2012, the versions available will be:
    1.35 - * 1) Single langauge, which only exposes slaves (such as SSR or Vthread)
    1.36 - * 2) Single language, which only exposes tasks  (such as pure dataflow)
    1.37 - * 3) Single language, which exposes both (like Cilk, StarSs, and OpenMP)
    1.38 - * 4) Multi-language, which always assumes both tasks and slaves
    1.39 - * 5) Multi-language and multi-process, which also assumes both tasks and slaves
    1.40 - *
    1.41 - * 
    1.42 - *
    1.43 +
    1.44 +/*Note: there used to be a coreController that was another animation 
    1.45 + * layer below both the masterVP and the slaveVPs.. in that case, the
    1.46 + * masterVP was a virtual processor whose processor-state was the same
    1.47 + * as a slaveVP's processor sate, both implemented as a SlaveVP struct.
    1.48 + * Have removed that, and
    1.49 + * changed the masterVP implementation.  Instead of being a special  version 
    1.50 + * of a proto-runtime virtual processor, using the slaveVP stuct, the 
    1.51 + * Master "virtual processor" is now implemented as a pthread pinned to
    1.52 + * a physical core.
    1.53   */
    1.54  
    1.55 -//This version of the master selects one of three loops, depending upon
    1.56 -// whether stand-alone single language (just slaves), or standalone with
    1.57 -// tasks, or multi-lang (implies multi-process)
    1.58 -void animationMaster( void *_environment, SlaveVP *masterVP )
    1.59 - { 
    1.60 -   TopEnv         *masterEnv = (TopEnv *)_environment;
    1.61 -   int32           slotIdx;
    1.62 -   AnimSlot       *currSlot;
    1.63 -      //Used while scanning and filling animation slots
    1.64 -   AnimSlot      **animSlots;
    1.65 -   
    1.66 -      //Local copies, for performance
    1.67 -   int32           thisCoresIdx;
    1.68 -   
    1.69 -   //======================== Initializations ========================
    1.70 -   thisCoresIdx     = masterVP->coreAnimatedBy;
    1.71 -   animSlots        = masterEnv->allAnimSlots[thisCoresIdx];
    1.72 -      
    1.73 -      HOLISTIC__Insert_Master_Global_Vars;
    1.74 -   
    1.75 -   //======================== animationMaster ========================
    1.76 -   //Have three different modes, and the master behavior is different for
    1.77 -   // each, so jump to the loop that corresponds to the mode.
    1.78 -   //
    1.79 -   while(1)
    1.80 -    {       MEAS__Capture_Pre_Master_Point
    1.81 -      for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
    1.82 -       {
    1.83 -         currSlot = animSlots[ slotIdx ];
    1.84 -
    1.85 -         masterFunction( currSlot );
    1.86 -       }
    1.87 -            MEAS__Capture_Post_Master_Point;
    1.88 -      masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
    1.89 -      flushRegisters();
    1.90 -    }
    1.91 - }
    1.92 -
    1.93 -
    1.94 +/*This is the behavior of the Master.  The physical processor switches
    1.95 + * between animating the master, and animating a slave.  When a slave
    1.96 + * suspends, the PR "suspend" primitive switches the physical core over
    1.97 + * to animating the masterVP, which is implemented as a pinned pthread.
    1.98 + * This function is the behavior of that masterVP.
    1.99 + *This function's job is to manage processing
   1.100 + * requests and to trigger assignment of new work to the physical core,
   1.101 + * and to manage sharing the core among processes.
   1.102 + */
   1.103  inline
   1.104  bool32
   1.105  masterFunction( AnimSlot  *slot )
   1.106 @@ -104,6 +62,8 @@
   1.107     bool32          foundWork;
   1.108  
   1.109        //Check if newly-done slave in slot, which will need request handled
   1.110 +      //NOTE: left over from when had a coreController & MasterVP managed
   1.111 +      // several slots
   1.112     if( slot->workIsDone )
   1.113      { slot->workIsDone = FALSE;
   1.114        slot->needsWorkAssigned = TRUE;
   1.115 @@ -126,16 +86,16 @@
   1.116         { case TaskEnd: 
   1.117            { //do PR handler, which calls lang's hdlr and does recycle of
   1.118              // free task slave if needed -- PR handler checks for free task Slv
   1.119 -            PRHandle_EndTask( req, slave );                          break;
   1.120 +            PRHandle__EndTask( req, slave );                          break;
   1.121            }
   1.122           case TaskCreate:
   1.123            { //Do PR's create-task handler, which calls the lang's hdlr
   1.124              // PR handler checks for free task Slv
   1.125 -            PRHandle_CreateTask( req, slave );                       break;
   1.126 +            PRHandle__CreateTask( req, slave );                       break;
   1.127            }
   1.128 -         case SlvCreate:    PRHandle_CreateSlave( req, slave );      break;
   1.129 -         case SlvDissipate: PRHandle_EndSlave( req, slave );         break;
   1.130 -         case Service:      PR_int__handle_PRServiceReq( slave );    break; //resumes into Service lang env
   1.131 +         case SlvCreate:    PRHandle__CreateSlave( req, slave );      break;
   1.132 +         case SlvDissipate: PRHandle__EndSlave( req, slave );         break;
   1.133 +         case Service:      PRHandle__ServiceReq( slave );    break; //resumes into Service lang env
   1.134           case Hardware: //for future expansion
   1.135           case IO:       //for future expansion
   1.136           case OSCall:   //for future expansion
   1.137 @@ -151,10 +111,12 @@
   1.138             HOLISTIC__Record_AppResponder_end;
   1.139      } //if have request to be handled
   1.140  
   1.141 -   if( slot->needsWorkAssigned )
   1.142 +      //NOTE: IF statement is leftover from when master managed many slots
   1.143 +   foundWork = FALSE;
   1.144 +   if( slot->needsWorkAssigned ) //can probably remove IF, not that only one slot
   1.145      {
   1.146              HOLISTIC__Record_Assigner_start;
   1.147 -
   1.148 +      
   1.149           //Pick a process to get this slot
   1.150        process = pickAProcess( slot );
   1.151  
   1.152 @@ -164,6 +126,8 @@
   1.153        assignWork( process, slot );
   1.154  
   1.155              HOLISTIC__Record_Assigner_end;
   1.156 +
   1.157 +//      fixme; //make this a while loop that tries a different process if this one fails
   1.158      }//if slot needs slave assigned
   1.159     
   1.160     return foundWork;
   1.161 @@ -223,9 +187,7 @@
   1.162  inline 
   1.163  bool32
   1.164  assignWork( PRProcess *process, AnimSlot *slot )
   1.165 - { SlaveVP        *returnSlv;
   1.166 -   int32           coreNum, slotNum;
   1.167 -   PRMetaTask     *assignedMetaTask;
   1.168 + { int32           coreNum;
   1.169  
   1.170     coreNum = slot->coreSlotIsOn;
   1.171     
   1.172 @@ -244,9 +206,21 @@
   1.173     numEnvs = process->numLangEnvs;
   1.174     for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array
   1.175      { langEnv = langEnvsList[envIdx];
   1.176 -      if( langEnv->hasWork )
   1.177 -       { (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot
   1.178 -         goto ReturnAfterAssigningWork; //quit for-loop, cause found work
   1.179 +      if( langEnv->numReadyWork > 0 )
   1.180 +       { bool32 
   1.181 +         didAssignWork =
   1.182 +          (*langEnv->workAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot
   1.183 +
   1.184 +         if(didAssignWork)
   1.185 +          { langEnv->numReadyWork -= 1;
   1.186 +            if( langEnv->numReadyWork == 0 )
   1.187 +             { process->numEnvsWithWork -= 1;
   1.188 +             }
   1.189 +            goto ReturnAfterAssigningWork; //quit for-loop, 'cause found work
   1.190 +          }
   1.191 +         else
   1.192 +            goto NoWork; //quit for-loop, cause found work
   1.193 +       
   1.194           //NOTE: bad search alg -- should start where left off, then wrap around
   1.195         }
   1.196      }
   1.197 @@ -255,7 +229,7 @@
   1.198   NoWork:     //No work, if end up here..
   1.199      { 
   1.200     #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   1.201 -      returnSlv = process->idleSlv[coreNum][slotNum]; 
   1.202 +      returnSlv = process->idleSlv[coreNum][0];  //only one slot now, so [0]
   1.203      
   1.204           //things that would normally happen in resume(), but idle VPs
   1.205           // never go there
   1.206 @@ -313,24 +287,25 @@
   1.207   */
   1.208  inline
   1.209  void
   1.210 -PRHandle_CreateSlave( PRReqst *req, SlaveVP *slave )
   1.211 +PRHandle__CreateSlave( PRReqst *req, SlaveVP *slave )
   1.212   { SlaveVP   *newSlv;
   1.213     PRProcess *process;
   1.214     PRLangEnv *protoLangEnv;
   1.215   
   1.216     process = slave->processSlaveIsIn;
   1.217     protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber );
   1.218 -   
   1.219 -//   newSlv  = PR_int__create_slave( req->topLevelFn, req->initData );
   1.220 -   
   1.221 -   //create slv has diff prototype than standard reqst hdlr
   1.222 +      
   1.223 +   //create handler, or a future request handler will call PR_PI__make_slave_ready
   1.224 +   // which will in turn handle updating which langlets and which processes have
   1.225 +   // work available.
   1.226 +   //NOTE: create slv has diff prototype than standard reqst hdlr
   1.227     newSlv = 
   1.228        (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv)); 
   1.229     
   1.230     newSlv->typeOfVP = GenericSlv;
   1.231     newSlv->processSlaveIsIn = process;
   1.232     newSlv->ID = req->ID;
   1.233 -   process->numLiveGenericSlvs += 1;
   1.234 +   process->numLiveGenericSlvs += 1; //not same as work ready!
   1.235   }
   1.236  
   1.237  /*The dissipate handler has to, update the number of slaves of the type, within
   1.238 @@ -345,7 +320,7 @@
   1.239   */
   1.240  inline
   1.241  void
   1.242 -PRHandle_EndSlave( PRReqst *req, SlaveVP *slave )
   1.243 +PRHandle__EndSlave( PRReqst *req, SlaveVP *slave )
   1.244   { PRProcess *process;
   1.245     PRLangEnv *protoLangEnv;
   1.246     
   1.247 @@ -357,13 +332,14 @@
   1.248     if(req->handler != NULL)
   1.249        (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) );
   1.250     
   1.251 -   process->numLiveGenericSlvs -= 1;
   1.252 -   PR_int__recycle_slave__ML( slave );
   1.253 -  
   1.254 +   process->numLiveGenericSlvs -= 1; 
   1.255 +   PR_int__recycle_slave( slave );
   1.256 +   //NOTE: dissipate is unrelated to work available (just in case wondering)
   1.257 +
   1.258        //check End Of Process Condition
   1.259     if( process->numLiveTasks == 0 &&
   1.260         process->numLiveGenericSlvs == 0 )
   1.261 -      PR_SS__shutdown_process__ML( process );
   1.262 +      PR_SS__shutdown_process( process );
   1.263   }
   1.264  
   1.265  /*Create task is a special form, that has PR behavior in addition to plugin
   1.266 @@ -374,7 +350,7 @@
   1.267   */
   1.268  inline
   1.269  void
   1.270 -PRHandle_CreateTask( PRReqst *req, SlaveVP *slave )
   1.271 +PRHandle__CreateTask( PRReqst *req, SlaveVP *slave )
   1.272   { PRMetaTask     *metaTask;
   1.273     PRProcess      *process;
   1.274     PRLangEnv      *protoLangEnv;
   1.275 @@ -400,8 +376,8 @@
   1.276     return;
   1.277   }
   1.278  
   1.279 -/*When a task ends, are two scenarios: 1) task ran to completion, or 2) task
   1.280 - * suspended at some point in its code.
   1.281 +/*When a task ends, have two scenarios: 1) task ran to completion, or 2) task
   1.282 + * has been suspended at some point in its code.
   1.283   *For 1, just decr count of live tasks (and check for end condition) -- the
   1.284   * master loop will decide what goes into the slot freed up by this task end,
   1.285   * so, here, don't worry about assigning a new task to the slot slave.
   1.286 @@ -425,13 +401,13 @@
   1.287   */
   1.288  inline 
   1.289  void
   1.290 -PRHandle_EndTask( PRReqst *req, SlaveVP *requestingSlv )
   1.291 +PRHandle__EndTask( PRReqst *req, SlaveVP *requestingSlv )
   1.292   { void       *langEnv;
   1.293     PRProcess  *process;
   1.294     void       *langMetaTask;
   1.295     
   1.296 -   langEnv = PR_int__give_lang_env_of_req__ML( req, requestingSlv ); //magic num in req
   1.297 -   langMetaTask = PR_int__give_lang_meta_task_from_slave__ML( requestingSlv, req->langMagicNumber);
   1.298 +   langEnv = PR_int__give_lang_env_of_req( req, requestingSlv ); //magic num in req
   1.299 +   langMetaTask = PR_int__give_lang_meta_task_from_slave( requestingSlv, req->langMagicNumber);
   1.300     
   1.301     //Do the langlet's request handler
   1.302     //Want to keep PR structs hidden from plugin, so extract langReq..
   1.303 @@ -439,15 +415,47 @@
   1.304     
   1.305     //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv
   1.306     if( requestingSlv->typeOfVP == FreeTaskSlv )
   1.307 -      PR_int__recycle_slave__ML( requestingSlv );
   1.308 +      PR_int__recycle_slave( requestingSlv ); //Doesn't decr num live slaves
   1.309     
   1.310     process->numLiveTasks -= 1;
   1.311 +   //NOTE: end-task is unrelated to work available (just in case wondering)
   1.312    
   1.313        //check End Of Process Condition
   1.314     if( process->numLiveTasks == 0 &&
   1.315         process->numLiveGenericSlvs == 0 )
   1.316      { //Tell the core controller to do wakeup of any waiting OS thread
   1.317 -      PR_SS__shutdown_process__ML( process );
   1.318 +      PR_SS__shutdown_process( process );
   1.319      }
   1.320   }
   1.321  
   1.322 +
   1.323 +/*This is for OS requests and PR infrastructure requests, which are not
   1.324 + * part of the PRServ language -- this is for things that have to be in the
   1.325 + * infrastructure of PR itself, such as I/O requests, which have to go through
   1.326 + * pthreads inside the core controller..
   1.327 + * 
   1.328 + *As of Jan 2013, doesn't do much of anything..
   1.329 + */
   1.330 +void inline
   1.331 +PRHandle__ServiceReq( SlaveVP *requestingSlv )
   1.332 + { PRReqst   *req;
   1.333 +   PRServReq *langReq;
   1.334 +   void      *langEnv;
   1.335 +   int32      magicNumber;
   1.336 +   
   1.337 + 
   1.338 +   req = requestingSlv->request;
   1.339 + 
   1.340 +   magicNumber = req->langMagicNumber;
   1.341 +   langEnv = PR_PI__give_lang_env_for( slave, magicNumber );
   1.342 +
   1.343 +   langReq = PR_PI__take_lang_reqst_from(req);
   1.344 +   if( langReq == NULL ) return;
   1.345 +   switch( langReq->reqType )  //lang handlers are all in other file
   1.346 +    {
   1.347 +      case make_probe:      handleMakeProbe(   langReq, langEnv );
   1.348 +         break;
   1.349 +      case throw_excp:  handleThrowException(  langReq, langEnv );
   1.350 +         break;
   1.351 +    }
   1.352 + }