changeset 268:e5bd470b562b Dev_ML

Checkpoint 2 -- split up header file, and about to delete single lang version of AnimationMaster
author Sean Halle <seanhalle@yahoo.com>
date Mon, 14 Jan 2013 15:31:23 -0800
parents 608833ae2c5d
children e6a68e7ea63f
files AnimationMaster.c CoreController.c Defines/MEAS__macros_to_be_moved_to_langs.h Defines/PR_defs.h Defines/PR_defs__HW_constants.h HW_Dependent_Primitives/PR__HW_measurement.h HW_Dependent_Primitives/PR__MetaInfo.c HW_Dependent_Primitives/PR__primitives.h HW_Dependent_Primitives/PR__primitives_asm.s PR.h PR__PI.c PR__PI.h PR__SS.c PR__WL.c PR__WL.h PR__int.c PR__int.h PR__structs.h PR_primitive_data_types.h Services_Offered_by_PR/Measurement_and_Stats/MEAS__macros.h Services_Offered_by_PR/Memory_Handling/vmalloc.c
diffstat 21 files changed, 2584 insertions(+), 1908 deletions(-) [+]
line diff
     1.1 --- a/AnimationMaster.c	Sun Nov 04 18:39:28 2012 -0800
     1.2 +++ b/AnimationMaster.c	Mon Jan 14 15:31:23 2013 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright 2010  OpenSourceStewardshipFoundation
     1.6 + * Copyright 2010  OpenSourceResearchInstitute
     1.7   * 
     1.8   * Licensed under BSD
     1.9   */
    1.10 @@ -12,9 +12,23 @@
    1.11  #include "PR.h"
    1.12  #include "VSs_impl/VSs.h"
    1.13  
    1.14 -inline void
    1.15 -replaceWithNewSlotSlv( SlaveVP *slave );
    1.16 +/*
    1.17 +void        PRHandle_CreateTask_SL(SlaveVP *slave);
    1.18  
    1.19 +void        PRHandle_CreateSlave_SL(SlaveVP *slave);
    1.20 +void        PRHandle_Dissipate_SL(SlaveVP *slave);
    1.21 +void        PR_int__handle_PRServiceReq_SL(SlaveVP *slave);
    1.22 +*/
    1.23 +inline void PRHandle_CreateTask( PRReqst *req, SlaveVP *slave );
    1.24 +inline void PRHandle_EndTask(    PRReqst *req, SlaveVP *slave );
    1.25 +inline void PRHandle_CreateSlave(PRReqst *req, SlaveVP *slave );
    1.26 +void        PRHandle_Dissipate(  PRReqst *req, SlaveVP *slave );
    1.27 +
    1.28 +
    1.29 +//inline void  masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot );
    1.30 +inline void masterFunction_MultiLang( AnimSlot  *slot );
    1.31 +inline PRProcess * pickAProcess( AnimSlot *slot );
    1.32 +inline SlaveVP * assignWork( PRProcess *process, AnimSlot *slot );
    1.33  
    1.34  /*The animationMaster embodies most of the animator of the language.  The
    1.35   * animator is what emodies the behavior of language constructs. 
    1.36 @@ -40,6 +54,81 @@
    1.37   *
    1.38   */
    1.39  
    1.40 +//This version of the master selects one of three loops, depending upon
    1.41 +// whether stand-alone single language (just slaves), or standalone with
    1.42 +// tasks, or multi-lang (implies multi-process)
    1.43 +void animationMaster( void *_environment, SlaveVP *masterVP )
    1.44 + { 
    1.45 +   TopEnv         *masterEnv = (TopEnv *)_environment;
    1.46 +   int32           slotIdx;
    1.47 +   AnimSlot       *currSlot;
    1.48 +      //Used while scanning and filling animation slots
    1.49 +   AnimSlot      **animSlots;
    1.50 +   
    1.51 +      //Local copies, for performance
    1.52 +   int32           thisCoresIdx;
    1.53 +   
    1.54 +   //======================== Initializations ========================
    1.55 +   thisCoresIdx     = masterVP->coreAnimatedBy;
    1.56 +   animSlots        = masterEnv->allAnimSlots[thisCoresIdx];
    1.57 +      
    1.58 +      HOLISTIC__Insert_Master_Global_Vars;
    1.59 +   
    1.60 +   //======================== animationMaster ========================
    1.61 +   //Have three different modes, and the master behavior is different for
    1.62 +   // each, so jump to the loop that corresponds to the mode.
    1.63 +   //
    1.64 +   switch(masterEnv->mode)
    1.65 +    {
    1.66 +/*
    1.67 +    { case SingleLang: 
    1.68 +         while(1)
    1.69 +          {       MEAS__Capture_Pre_Master_Point
    1.70 +            for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
    1.71 +             {
    1.72 +               currSlot = animSlots[ slotIdx ];
    1.73 +
    1.74 +               masterFunction_StandaloneSlavesOnly( masterEnv, currSlot );
    1.75 +             }
    1.76 +                  MEAS__Capture_Post_Master_Point;
    1.77 +            masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
    1.78 +            flushRegisters();
    1.79 +          } 
    1.80 +
    1.81 +      case SingleLang:     
    1.82 +       { PRLangEnv  *protoLangEnv =  _PRTopEnv->protoLangEnv;
    1.83 +         while(1)
    1.84 +          {       MEAS__Capture_Pre_Master_Point
    1.85 +            for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
    1.86 +             {
    1.87 +               currSlot = animSlots[ slotIdx ];
    1.88 +
    1.89 +               masterFunction_SingleLang( protoLangEnv, currSlot );
    1.90 +             }
    1.91 +                  MEAS__Capture_Post_Master_Point;
    1.92 +            masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
    1.93 +            flushRegisters();
    1.94 +          }
    1.95 +       }
    1.96 + */
    1.97 +      case MultiLang:
    1.98 +       { while(1)
    1.99 +          {       MEAS__Capture_Pre_Master_Point
   1.100 +            for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.101 +             {
   1.102 +               currSlot = animSlots[ slotIdx ];
   1.103 +
   1.104 +               masterFunction_MultiLang( currSlot );
   1.105 +             }
   1.106 +                  MEAS__Capture_Post_Master_Point;
   1.107 +            masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.108 +            flushRegisters();
   1.109 +          }
   1.110 +       }
   1.111 +    }
   1.112 + }
   1.113 +
   1.114 +
   1.115          
   1.116  //=====================  The versions of the Animation Master  =================
   1.117  //
   1.118 @@ -71,7 +160,7 @@
   1.119   * order that application code in the slaves executes.
   1.120   * 
   1.121   *To control order of animation of slaves, the request handler has a
   1.122 - * semantic environment that holds data structures used to hold slaves
   1.123 + * language environment that holds data structures used to hold slaves
   1.124   * and choose when they're ready to be animated.
   1.125   *
   1.126   *Once a slave is marked as ready to be animated by the request handler,
   1.127 @@ -93,23 +182,23 @@
   1.128   *==========================================================================
   1.129   *In summary, the animationMaster scans the slots, finds slaves
   1.130   * just-finished, which hold requests, pass those to the request handler,
   1.131 - * along with the semantic environment, and the request handler then manages
   1.132 - * the structures in the semantic env, which controls the order of
   1.133 + * along with the language environment, and the request handler then manages
   1.134 + * the structures in the language env, which controls the order of
   1.135   * animation of slaves, and so embodies the behavior of the language
   1.136   * constructs.
   1.137   *The animationMaster then rescans the slots, offering each empty one to
   1.138 - * the Assigner, along with the semantic environment.  The Assigner chooses
   1.139 - * among the ready slaves in the semantic Env, finding the one best suited
   1.140 + * the Assigner, along with the language environment.  The Assigner chooses
   1.141 + * among the ready slaves in the language env, finding the one best suited
   1.142   * to be animated by that slot's associated core.
   1.143   * 
   1.144   *==========================================================================
   1.145   *Implementation Details:
   1.146   * 
   1.147 - *There is a separate masterVP for each core, but a single semantic
   1.148 + *There is a separate masterVP for each core, but a single language
   1.149   * environment shared by all cores.  Each core also has its own scheduling
   1.150   * slots, which are used to communicate slaves between animationMaster and
   1.151   * coreController.  There is only one global variable, _PRTopEnv, which
   1.152 - * holds the semantic env and other things shared by the different
   1.153 + * holds the language env and other things shared by the different
   1.154   * masterVPs.  The request handler and Assigner are registered with
   1.155   * the animationMaster by the language's init function, and a pointer to
   1.156   * each is in the _PRTopEnv. (There are also some pthread related global
   1.157 @@ -128,7 +217,7 @@
   1.158   *The core controllers access _PRTopEnv to get the masterVP, and when
   1.159   * they start, the slots are all empty, so they run their associated core's
   1.160   * masterVP.  The first of those to get the master lock sees the seed slave
   1.161 - * in the shared semantic environment, so when it runs the Assigner, that
   1.162 + * in the shared language environment, so when it runs the Assigner, that
   1.163   * returns the seed slave, which the animationMaster puts into a scheduling
   1.164   * slot then switches to the core controller.  That then switches the core
   1.165   * over to the seed slave, which then proceeds to execute language
   1.166 @@ -148,246 +237,100 @@
   1.167   * executing the animationMaster code, which drives for more than one. In
   1.168   * practice, the best balance should be discovered by profiling.
   1.169   */
   1.170 -void animationMaster( void *initData, SlaveVP *masterVP )
   1.171 +/*
   1.172 +void masterFunction_StandaloneSlavesOnly( AnimSlot  *slot )
   1.173   { 
   1.174 -      //Used while scanning and filling animation slots
   1.175 -   int32           slotIdx, numSlotsFilled;
   1.176 -   AnimSlot      *currSlot, **animSlots;
   1.177 -   SlaveVP        *assignedSlaveVP;  //the slave chosen by the assigner
   1.178 -
   1.179 -      //Local copies, for performance
   1.180 -   MasterEnv      *masterEnv;
   1.181 -   SlaveAssigner   slaveAssigner;
   1.182 -   RequestHandler  requestHandler;
   1.183 -   void           *semanticEnv;
   1.184 -   int32           thisCoresIdx;
   1.185 -  
   1.186 -   //======================== Initializations ========================
   1.187 -   masterEnv        = (MasterEnv*)_PRTopEnv;
   1.188 -   
   1.189 -   thisCoresIdx     = masterVP->coreAnimatedBy;
   1.190 -   animSlots       = masterEnv->allAnimSlots[thisCoresIdx];
   1.191 -
   1.192 -   requestHandler   = masterEnv->requestHandler;
   1.193 -   slaveAssigner    = masterEnv->slaveAssigner;
   1.194 -   semanticEnv      = masterEnv->semanticEnv;
   1.195 -   
   1.196 -      HOLISTIC__Insert_Master_Global_Vars;
   1.197 +   SlaveVP        *slave;
   1.198 +   PRReqst        *req;
   1.199 +   PRLangEnv      *langEnv = _PRTopEnv->langEnv;
   1.200 +    
   1.201     
   1.202     //======================== animationMaster ========================
   1.203 -   while(1){
   1.204 -       
   1.205 -      MEAS__Capture_Pre_Master_Point
   1.206 +      
   1.207 +      //Check if newly-done slave in slot, which will need request handled
   1.208 +   if( slot->workIsDone )
   1.209 +    { slot->workIsDone = FALSE;
   1.210 +      slot->needsWorkAssigned = TRUE;
   1.211  
   1.212 -      //Scan the animation slots
   1.213 -   numSlotsFilled = 0;
   1.214 -   for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.215 -    {
   1.216 -      currSlot = animSlots[ slotIdx ];
   1.217  
   1.218 -         //Check if newly-done slave in slot, which will need request handled
   1.219 -      if( currSlot->workIsDone )
   1.220 -       {
   1.221 -         currSlot->workIsDone         = FALSE;
   1.222 -         currSlot->needsWorkAssigned = TRUE;
   1.223 -         
   1.224 -       HOLISTIC__Record_AppResponder_start;
   1.225 -               MEAS__startReqHdlr;
   1.226 -               
   1.227 -           currSlot->workIsDone         = FALSE;
   1.228 -            currSlot->needsWorkAssigned = TRUE;
   1.229 -            SlaveVP *currSlave = currSlot->slaveAssignedToSlot;
   1.230 -            
   1.231 -	justAddedReqHdlrChg();
   1.232 -			//handle the request, either by PR or by the language
   1.233 -            if( currSlave->requests->reqType != LangReq )
   1.234 -             {    //The request is a standard PR one, not one defined by the
   1.235 -                  // language, so PR handles it, then queues slave to be assigned
   1.236 -               handleReqInPR( currSlave );
   1.237 -               writePrivQ( currSlave, PRReadyQ ); //Q slave to be assigned below
   1.238 -             }
   1.239 -            else
   1.240 -             {       MEAS__startReqHdlr;
   1.241 +            HOLISTIC__Record_AppResponder_start;
   1.242 +            MEAS__startReqHdlr;
   1.243 +         //process the request made by the slave (held inside slave struc)
   1.244 +      slave = slot->slaveAssignedToSlot;
   1.245 +      req = slave->request;
   1.246  
   1.247 -                  //Language handles request, which is held inside slave struc
   1.248 -               (*requestHandler)( currSlave, semanticEnv );
   1.249 -
   1.250 -                     MEAS__endReqHdlr;
   1.251 -             }
   1.252 -          }
   1.253 -
   1.254 -		  //process the requests made by the slave (held inside slave struc)
   1.255 -         (*requestHandler)( currSlot->slaveAssignedToSlot, semanticEnv );
   1.256 -         
   1.257 -         HOLISTIC__Record_AppResponder_end;
   1.258 -               MEAS__endReqHdlr;
   1.259 -       }
   1.260 -         //If slot empty, hand to Assigner to fill with a slave
   1.261 -      if( currSlot->needsWorkAssigned )
   1.262 -       {    //Call plugin's Assigner to give slot a new slave
   1.263 -          HOLISTIC__Record_Assigner_start;
   1.264 -         assignedSlaveVP =
   1.265 -          (*slaveAssigner)( semanticEnv, currSlot );
   1.266 -         
   1.267 -            //put the chosen slave into slot, and adjust flags and state
   1.268 -         if( assignedSlaveVP != NULL )
   1.269 -          { currSlot->slaveAssignedToSlot = assignedSlaveVP;
   1.270 -            assignedSlaveVP->animSlotAssignedTo       = currSlot;
   1.271 -            currSlot->needsWorkAssigned  = FALSE;
   1.272 -            numSlotsFilled               += 1;
   1.273 -            
   1.274 -            HOLISTIC__Record_Assigner_end;
   1.275 +      //Handle task create and end first -- they're special cases..
   1.276 +      switch( req->reqType )
   1.277 +       { case SlvCreate:    PRHandle_CreateSlave( slave );           break;
   1.278 +         case SlvDissipate: PRHandle_Dissipate( slave );             break;
   1.279 +         case Service:      PR_int__handle_PRServiceReq( slave );    break; //resume into PR's own language env
   1.280 +         case Hardware: //for future expansion
   1.281 +         case IO:       //for future expansion
   1.282 +         case OSCall:   //for future expansion
   1.283 +            PR_int__throw_exception("Not implemented");             break;
   1.284 +         case Language: //normal lang request
   1.285 +          { 
   1.286 +            (*langEnv->requestHdlr)( req->langReq, slave, langEnv );
   1.287            }
   1.288         }
   1.289 +            HOLISTIC__Record_AppResponder_end;
   1.290 +            MEAS__endReqHdlr;
   1.291      }
   1.292 +      //If slot empty, hand to Assigner to fill with a slave
   1.293 +   if( slot->needsWorkAssigned )
   1.294 +    {    //Call plugin's Assigner to give slot a new slave
   1.295 +            HOLISTIC__Record_Assigner_start;
   1.296  
   1.297 -         MEAS__Capture_Post_Master_Point;
   1.298 +      if( langEnv->hasWork )
   1.299 +       {  (*langEnv->slaveAssigner)( langEnv, slot ); //calls PR fn that inserts work into slot
   1.300 +         goto ReturnAfterAssigningWork; //quit for-loop, cause found work
   1.301 +       }
   1.302 +      else
   1.303 +         goto NoWork;
   1.304 +    }
   1.305     
   1.306 -   masterSwitchToCoreCtlr( masterVP );
   1.307 -   flushRegisters();
   1.308 -         DEBUG__printf(FALSE,"came back after switch to core -- so lock released!");
   1.309 -   }//while(1) 
   1.310 + NoWork:
   1.311 +      //No work, if reach here..
   1.312 +    { 
   1.313 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   1.314 +      coreNum = slot->coreSlotIsOn;
   1.315 +      returnSlv = process->idleSlv[coreNum][slotNum]; 
   1.316 +    
   1.317 +         //things that would normally happen in resume(), but idle VPs
   1.318 +         // never go there
   1.319 +      returnSlv->numTimesAssignedToASlot++; //gives each idle unit a unique ID
   1.320 +      Unit newU;
   1.321 +      newU.vp = returnSlv->slaveNum;
   1.322 +      newU.task = returnSlv->numTimesAssignedToASlot;
   1.323 +      addToListOfArrays(Unit,newU,process->unitList);
   1.324 +
   1.325 +      if (returnSlv->numTimesAssignedToASlot > 1) //make a dependency from prev idle unit
   1.326 +       { Dependency newD;             // to this one
   1.327 +         newD.from_vp = returnSlv->slaveNum;
   1.328 +         newD.from_task = returnSlv->numTimesAssignedToASlot - 1;
   1.329 +         newD.to_vp = returnSlv->slaveNum;
   1.330 +         newD.to_task = returnSlv->numTimesAssignedToASlot;
   1.331 +         addToListOfArrays(Dependency, newD ,process->ctlDependenciesList);  
   1.332 +       }
   1.333 +   #endif
   1.334 +            HOLISTIC__Record_Assigner_end;
   1.335 +      return;
   1.336 +    }
   1.337 + 
   1.338 + ReturnAfterAssigningWork:  //All paths goto here.. to provide single point for holistic..
   1.339 +    {
   1.340 +            HOLISTIC__Record_Assigner_end;
   1.341 +      return;
   1.342 +    }
   1.343   }
   1.344 -
   1.345 -
   1.346 -/* 2)  This version is for a single language that has only tasks, which 
   1.347 - *     cannot be suspended.
   1.348 - */
   1.349 -void animationMaster( void *initData, SlaveVP *masterVP )
   1.350 - { 
   1.351 -      //Used while scanning and filling animation slots
   1.352 -   int32           slotIdx, numSlotsFilled;
   1.353 -   AnimSlot       *currSlot, **animSlots;
   1.354 -   SlaveVP        *assignedSlaveVP;  //the slave chosen by the assigner
   1.355 -   
   1.356 -      //Local copies, for performance
   1.357 -   MasterEnv      *masterEnv;
   1.358 -   SlaveAssigner   slaveAssigner;
   1.359 -   RequestHandler  requestHandler;
   1.360 -   PRSemEnv       *semanticEnv;
   1.361 -   int32           thisCoresIdx;
   1.362 -
   1.363 -   //#ifdef  MODE__MULTI_LANG
   1.364 -   SlaveVP        *slave;
   1.365 -   PRProcess      *process;
   1.366 -   int32           langMagicNumber;
   1.367 -   //#endif
   1.368 -   
   1.369 -   //======================== Initializations ========================
   1.370 -   masterEnv        = (MasterEnv*)_PRTopEnv;
   1.371 -   
   1.372 -   thisCoresIdx     = masterVP->coreAnimatedBy;
   1.373 -   animSlots        = masterEnv->allAnimSlots[thisCoresIdx];
   1.374 -
   1.375 -   requestHandler   = masterEnv->requestHandler;
   1.376 -   slaveAssigner    = masterEnv->slaveAssigner;
   1.377 -   semanticEnv      = masterEnv->semanticEnv;
   1.378 -   
   1.379 -      //initialize, for non-multi-lang, non multi-proc case
   1.380 -      // default handler gets put into master env by a registration call by lang
   1.381 -   endTaskHandler   = masterEnv->defaultTaskHandler;
   1.382 -   
   1.383 -      HOLISTIC__Insert_Master_Global_Vars;
   1.384 -   
   1.385 -   //======================== animationMaster ========================
   1.386 -   //Do loop gets requests handled and work assigned to slots..
   1.387 -   // work can either be a task or a resumed slave
   1.388 -   //Having two cases makes this logic complex.. can be finishing either, and 
   1.389 -   // then the next available work may be either.. so really have two distinct
   1.390 -   // loops that are inter-twined.. 
   1.391 -   while(1){
   1.392 -       
   1.393 -      MEAS__Capture_Pre_Master_Point
   1.394 -
   1.395 -      //Scan the animation slots
   1.396 -   numSlotsFilled = 0;
   1.397 -   for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.398 -    {
   1.399 -      currSlot = animSlots[ slotIdx ];
   1.400 -
   1.401 -         //Check if newly-done slave in slot, which will need request handled
   1.402 -      if( currSlot->workIsDone )
   1.403 -       { currSlot->workIsDone = FALSE;
   1.404 -       
   1.405 -               HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
   1.406 -               MEAS__startReqHdlr;
   1.407 -               
   1.408 -         
   1.409 -            //process the request made by the slave (held inside slave struc)
   1.410 -         slave = currSlot->slaveAssignedToSlot;
   1.411 -         
   1.412 -            //check if the completed work was a task..
   1.413 -         if( slave->metaTask->isATask )
   1.414 -          {
   1.415 -             if( slave->request->type == TaskEnd ) 
   1.416 -              {    //do task end handler, which is registered separately
   1.417 -                   //note, end hdlr may use semantic data from reqst..
   1.418 -                //#ifdef  MODE__MULTI_LANG
   1.419 -                   //get end-task handler
   1.420 -                //taskEndHandler = lookup( slave->reqst->langMagicNumber, processEnv );
   1.421 -                taskEndHandler = slave->metaTask->endTaskHandler;
   1.422 -                //#endif
   1.423 -                (*taskEndHandler)( slave, semanticEnv );
   1.424 -                
   1.425 -                goto AssignWork;
   1.426 -              }
   1.427 -             else  //is a task, and just suspended
   1.428 -              {    //turn slot slave into free task slave & make replacement
   1.429 -                if( slave->typeOfVP == SlotTaskSlv ) changeSlvType();
   1.430 -                
   1.431 -                //goto normal slave request handling
   1.432 -                goto SlaveReqHandling; 
   1.433 -              }
   1.434 -          }
   1.435 -         else //is a slave that suspended
   1.436 -          {
   1.437 -          SlaveReqHandling:
   1.438 -            (*requestHandler)( slave, semanticEnv ); //(note: indirect Fn call more efficient when use fewer params, instead re-fetch from slave)
   1.439 -         
   1.440 -               HOLISTIC__Record_AppResponder_end;
   1.441 -               MEAS__endReqHdlr;
   1.442 -               
   1.443 -            goto AssignWork;
   1.444 -          }
   1.445 -       } //if has suspended slave that needs handling
   1.446 -      
   1.447 -         //if slot empty, hand to Assigner to fill with a slave
   1.448 -      if( currSlot->needsWorkAssigned )
   1.449 -       {    //Call plugin's Assigner to give slot a new slave
   1.450 -               HOLISTIC__Record_Assigner_start;
   1.451 -               
   1.452 -       AssignWork:
   1.453 -     
   1.454 -         assignedSlaveVP = assignWork( semanticEnv, currSlot );
   1.455 -       
   1.456 -            //put the chosen slave into slot, and adjust flags and state
   1.457 -         if( assignedSlaveVP != NULL )
   1.458 -          { currSlot->slaveAssignedToSlot = assignedSlaveVP;
   1.459 -            assignedSlaveVP->animSlotAssignedTo = currSlot;
   1.460 -            currSlot->needsWorkAssigned  = FALSE;
   1.461 -            numSlotsFilled               += 1;
   1.462 -          }
   1.463 -         else
   1.464 -          {
   1.465 -            currSlot->needsWorkAssigned  = TRUE; //local write
   1.466 -          }
   1.467 -               HOLISTIC__Record_Assigner_end;
   1.468 -       }//if slot needs slave assigned
   1.469 -    }//for( slotIdx..
   1.470 -
   1.471 -         MEAS__Capture_Post_Master_Point;
   1.472 -   
   1.473 -   masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.474 -   flushRegisters();
   1.475 -   }//while(1) 
   1.476 - }
   1.477 +*/
   1.478  
   1.479  
   1.480  /*This is the master when just multi-lang, but not multi-process mode is on.
   1.481   * This version has to handle both tasks and slaves, and do extra work of 
   1.482 - * looking up the semantic env and handlers to use, for each completed bit of 
   1.483 + * looking up the language env and handlers to use, for each completed bit of 
   1.484   * work.
   1.485 - *It also has to search through the semantic envs to find one with work,
   1.486 + *It also has to search through the language envs to find one with work,
   1.487   * then ask that env's assigner to return a unit of that work.
   1.488   * 
   1.489   *The language is written to startup in the same way as if it were the only
   1.490 @@ -429,9 +372,9 @@
   1.491   * 
   1.492   *The multi-lang thing complicates matters..  
   1.493   *
   1.494 - *For request handling, it means have to first fetch the semantic environment
   1.495 + *For request handling, it means have to first fetch the language environment
   1.496   * of the language, and then do the request handler pointed to by that
   1.497 - * semantic env.
   1.498 + * language env.
   1.499   *For assigning, things get more complex because of competing goals..  One
   1.500   * goal is for language specific stuff to be used during assignment, so
   1.501   * assigner can make higher quality decisions..  but with multiple languages,
   1.502 @@ -452,9 +395,9 @@
   1.503   * queue at a time..  but this is quite hack-like.. or perhaps HWSim supplies
   1.504   * a task-end handler that kicks the next unit of work from HWSim internal
   1.505   * priority queue, over to PR readyQ)
   1.506 - *2) can have each language have its own semantic env, that holds its own
   1.507 + *2) can have each language have its own language env, that holds its own
   1.508   * work, which is assigned by its own assigner.. then the master searches
   1.509 - * through all the semantic envs to find one with work and asks it give work..
   1.510 + * through all the language envs to find one with work and asks it give work..
   1.511   * (this has downside of blinding assigners to each other.. but does work
   1.512   * for HWSim case)
   1.513   *3) could make PR have a different readyQ for each core, and ask the lang
   1.514 @@ -477,383 +420,217 @@
   1.515   * the languages in a unified way..  Don't really expect this to happen, 
   1.516   * but making it possible.
   1.517   */
   1.518 -#ifdef  MODE__MULTI_LANG
   1.519 -void animationMaster( void *initData, SlaveVP *masterVP )
   1.520 - { 
   1.521 -      //Used while scanning and filling animation slots
   1.522 -   int32           slotIdx, numSlotsFilled;
   1.523 -   AnimSlot       *currSlot, **animSlots;
   1.524 -   SlaveVP        *assignedSlaveVP;  //the slave chosen by the assigner
   1.525 +/*
   1.526 +inline
   1.527 +void 
   1.528 +masterFunction_SingleLang( PRLangEnv *protoLangEnv, AnimSlot *slot )
   1.529 + {    //Scan the animation slots
   1.530 +   SlaveVP        *slave;
   1.531 +   PRReqst        *req;
   1.532 +
   1.533 +      //Check if newly-done slave in slot, which will need request handled
   1.534 +   if( slot->workIsDone )
   1.535 +    { slot->workIsDone = FALSE;
   1.536 +      slot->needsWorkAssigned = TRUE;
   1.537 +
   1.538 +            HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
   1.539 +            MEAS__startReqHdlr;
   1.540 +
   1.541 +
   1.542 +         //process the request made by the slave (held inside slave struc)
   1.543 +      slave = slot->slaveAssignedToSlot;
   1.544 +      req = slave->request;
   1.545 +
   1.546 +         //If the requesting slave is a slot slave, and request is not
   1.547 +         // task-end, then turn it into a free task slave. 
   1.548 +      if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd )
   1.549 +         PR_int__replace_with_new_slot_slv( slave );
   1.550 +
   1.551 +      //Handle task create and end first -- they're special cases..
   1.552 +      switch( req->reqType )
   1.553 +       { case TaskEnd: 
   1.554 +          { //do PR handler, which calls lang's hdlr and does recycle of
   1.555 +            // free task slave if needed -- PR handler checks for free task Slv
   1.556 +            PRHandle_EndTask_SL( slave );                            break;
   1.557 +          }
   1.558 +         case TaskCreate:
   1.559 +          { //Do PR's create-task handler, which calls the lang's hdlr
   1.560 +            // PR handler checks for free task Slv
   1.561 +            PRHandle_CreateTask_SL( slave );                         break;
   1.562 +          }
   1.563 +         case SlvCreate:    PRHandle_CreateSlave_SL( slave );        break;
   1.564 +         case SlvDissipate: PRHandle_Dissipate_SL( slave );          break;
   1.565 +         case Service:      PR_int__handle_PRServiceReq_SL( slave ); break; //resume into PR's own language env
   1.566 +         case Hardware: //for future expansion
   1.567 +         case IO:       //for future expansion
   1.568 +         case OSCall:   //for future expansion
   1.569 +            PR_int__throw_exception("Not implemented", slave, NULL); break;
   1.570 +         case Language: //normal lang request
   1.571 +          { 
   1.572 +            (*protoLangEnv->requestHdlr)( req->langReq, slave, (void*)PR_int__give_lang_env(protoLangEnv ));
   1.573 +          }
   1.574 +       }
   1.575 +              
   1.576 +            MEAS__endReqHdlr;          
   1.577 +            HOLISTIC__Record_AppResponder_end;
   1.578 +    } //if have request to be handled
   1.579 +
   1.580 +      //If slot empty, hand to Assigner to fill with a slave
   1.581 +   if( slot->needsWorkAssigned )
   1.582 +    {    //Call plugin's Assigner to give slot a new slave
   1.583 +            HOLISTIC__Record_Assigner_start;
   1.584 +
   1.585 +      if( protoLangEnv->hasWork )
   1.586 +       {  (*protoLangEnv->slaveAssigner)( protoLangEnv, slot ); //calls PR fn that inserts work into slot
   1.587 +         goto ReturnAfterAssigningWork; //quit for-loop, cause found work
   1.588 +       }
   1.589 +      else
   1.590 +         goto NoWork;
   1.591 +    }
   1.592     
   1.593 -      //Local copies, for performance
   1.594 -   MasterEnv      *masterEnv;
   1.595 -   SlaveAssigner   slaveAssigner;
   1.596 -   RequestHandler  requestHandler;
   1.597 -   PRSemEnv       *semanticEnv;
   1.598 -   int32           thisCoresIdx;
   1.599 + NoWork:
   1.600 +      //No work, if reach here..
   1.601 +    { 
   1.602 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   1.603 +      coreNum = slot->coreSlotIsOn;
   1.604 +      returnSlv = process->idleSlv[coreNum][slotNum]; 
   1.605 +    
   1.606 +         //things that would normally happen in resume(), but idle VPs
   1.607 +         // never go there
   1.608 +      returnSlv->numTimesAssignedToASlot++; //gives each idle unit a unique ID
   1.609 +      Unit newU;
   1.610 +      newU.vp = returnSlv->slaveNum;
   1.611 +      newU.task = returnSlv->numTimesAssignedToASlot;
   1.612 +      addToListOfArrays(Unit,newU,process->unitList);
   1.613  
   1.614 -   //#ifdef  MODE__MULTI_LANG
   1.615 -   SlaveVP        *slave;
   1.616 -   PRProcess      *process;
   1.617 -   int32           langMagicNumber;
   1.618 -   //#endif
   1.619 -   
   1.620 -   //======================== Initializations ========================
   1.621 -   masterEnv        = (MasterEnv*)_PRTopEnv;
   1.622 -   
   1.623 -   thisCoresIdx     = masterVP->coreAnimatedBy;
   1.624 -   animSlots        = masterEnv->allAnimSlots[thisCoresIdx];
   1.625 -
   1.626 -   requestHandler   = masterEnv->requestHandler;
   1.627 -   slaveAssigner    = masterEnv->slaveAssigner;
   1.628 -   semanticEnv      = masterEnv->semanticEnv;
   1.629 -   
   1.630 -      //initialize, for non-multi-lang, non multi-proc case
   1.631 -      // default handler gets put into master env by a registration call by lang
   1.632 -   endTaskHandler   = masterEnv->defaultTaskHandler;
   1.633 -   
   1.634 -      HOLISTIC__Insert_Master_Global_Vars;
   1.635 -   
   1.636 -   //======================== animationMaster ========================
   1.637 -   //Do loop gets requests handled and work assigned to slots..
   1.638 -   // work can either be a task or a resumed slave
   1.639 -   //Having two cases makes this logic complex.. can be finishing either, and 
   1.640 -   // then the next available work may be either.. so really have two distinct
   1.641 -   // loops that are inter-twined.. 
   1.642 -   while(1){
   1.643 -       
   1.644 -      MEAS__Capture_Pre_Master_Point
   1.645 -
   1.646 -      //Scan the animation slots
   1.647 -   numSlotsFilled = 0;
   1.648 -   for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.649 +      if (returnSlv->numTimesAssignedToASlot > 1) //make a dependency from prev idle unit
   1.650 +       { Dependency newD;             // to this one
   1.651 +         newD.from_vp = returnSlv->slaveNum;
   1.652 +         newD.from_task = returnSlv->numTimesAssignedToASlot - 1;
   1.653 +         newD.to_vp = returnSlv->slaveNum;
   1.654 +         newD.to_task = returnSlv->numTimesAssignedToASlot;
   1.655 +         addToListOfArrays(Dependency, newD ,process->ctlDependenciesList);  
   1.656 +       }
   1.657 +   #endif
   1.658 +            HOLISTIC__Record_Assigner_end;
   1.659 +      return;
   1.660 +    }
   1.661 + 
   1.662 + ReturnAfterAssigningWork:  //All paths goto here.. to provide single point for holistic..
   1.663      {
   1.664 -      currSlot = animSlots[ slotIdx ];
   1.665 -
   1.666 -         //Check if newly-done slave in slot, which will need request handled
   1.667 -      if( currSlot->workIsDone )
   1.668 -       { currSlot->workIsDone = FALSE;
   1.669 -       
   1.670 -               HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
   1.671 -               MEAS__startReqHdlr;
   1.672 -               
   1.673 -         
   1.674 -            //process the request made by the slave (held inside slave struc)
   1.675 -         slave = currSlot->slaveAssignedToSlot;
   1.676 -         
   1.677 -            //check if the completed work was a task..
   1.678 -         if( slave->taskMetaInfo->isATask )
   1.679 -          {
   1.680 -             if( slave->reqst->type == TaskEnd ) 
   1.681 -              {    //do task end handler, which is registered separately
   1.682 -                   //note, end hdlr may use semantic data from reqst..
   1.683 -                //#ifdef  MODE__MULTI_LANG
   1.684 -                   //get end-task handler
   1.685 -                //taskEndHandler = lookup( slave->reqst->langMagicNumber, processEnv );
   1.686 -                taskEndHandler = slave->taskMetaInfo->endTaskHandler;
   1.687 -                //#endif
   1.688 -                (*taskEndHandler)( slave, semanticEnv );
   1.689 -                
   1.690 -                goto AssignWork;
   1.691 -              }
   1.692 -             else  //is a task, and just suspended
   1.693 -              {    //turn slot slave into free task slave & make replacement
   1.694 -                if( slave->typeOfVP == SlotTaskSlv ) changeSlvType();
   1.695 -                
   1.696 -                //goto normal slave request handling
   1.697 -                goto SlaveReqHandling; 
   1.698 -              }
   1.699 -          }
   1.700 -         else //is a slave that suspended
   1.701 -          {
   1.702 -          SlaveReqHandling:
   1.703 -            (*requestHandler)( slave, semanticEnv ); //(note: indirect Fn call more efficient when use fewer params, instead re-fetch from slave)
   1.704 -         
   1.705 -               HOLISTIC__Record_AppResponder_end;
   1.706 -               MEAS__endReqHdlr;
   1.707 -               
   1.708 -            goto AssignWork;
   1.709 -          }
   1.710 -       } //if has suspended slave that needs handling
   1.711 -      
   1.712 -         //if slot empty, hand to Assigner to fill with a slave
   1.713 -      if( currSlot->needsWorkAssigned )
   1.714 -       {    //Call plugin's Assigner to give slot a new slave
   1.715 -               HOLISTIC__Record_Assigner_start;
   1.716 -               
   1.717 -       AssignWork:
   1.718 -     
   1.719 -         assignedSlaveVP = assignWork( semanticEnv, currSlot );
   1.720 -       
   1.721 -            //put the chosen slave into slot, and adjust flags and state
   1.722 -         if( assignedSlaveVP != NULL )
   1.723 -          { currSlot->slaveAssignedToSlot = assignedSlaveVP;
   1.724 -            assignedSlaveVP->animSlotAssignedTo = currSlot;
   1.725 -            currSlot->needsWorkAssigned  = FALSE;
   1.726 -            numSlotsFilled               += 1;
   1.727 -          }
   1.728 -         else
   1.729 -          {
   1.730 -            currSlot->needsWorkAssigned  = TRUE; //local write
   1.731 -          }
   1.732 -               HOLISTIC__Record_Assigner_end;
   1.733 -       }//if slot needs slave assigned
   1.734 -    }//for( slotIdx..
   1.735 -
   1.736 -         MEAS__Capture_Post_Master_Point;
   1.737 -   
   1.738 -   masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.739 -   flushRegisters();
   1.740 -   }//while(1) 
   1.741 - }
   1.742 -#endif //MODE__MULTI_LANG
   1.743 -
   1.744 -
   1.745 -
   1.746 -//This is the master when both multi-lang and multi-process modes are turned on
   1.747 -//#ifdef MODE__MULTI_LANG
   1.748 -//#ifdef MODE__MULTI_PROCESS
   1.749 -void animationMaster( void *initData, SlaveVP *masterVP )
   1.750 - { 
   1.751 -   int32           slotIdx;
   1.752 -   AnimSlot       *currSlot;
   1.753 -      //Used while scanning and filling animation slots
   1.754 -   AnimSlot      **animSlots;
   1.755 -   
   1.756 -      //Local copies, for performance
   1.757 -   MasterEnv      *masterEnv;
   1.758 -   int32           thisCoresIdx;
   1.759 -   
   1.760 -   //======================== Initializations ========================
   1.761 -   masterEnv        = (MasterEnv*)_PRTopEnv;
   1.762 -   
   1.763 -   thisCoresIdx     = masterVP->coreAnimatedBy;
   1.764 -   animSlots        = masterEnv->allAnimSlots[thisCoresIdx];
   1.765 -      
   1.766 -      HOLISTIC__Insert_Master_Global_Vars;
   1.767 -   
   1.768 -   //======================== animationMaster ========================
   1.769 -   //Do loop gets requests handled and work assigned to slots..
   1.770 -   // work can either be a task or a resumed slave
   1.771 -   //Having two cases makes this logic complex.. can be finishing either, and 
   1.772 -   // then the next available work may be either.. so really have two distinct
   1.773 -   // loops that are inter-twined.. 
   1.774 -   while(1)
   1.775 -    {  
   1.776 -            MEAS__Capture_Pre_Master_Point
   1.777 -      
   1.778 -      for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.779 -       {
   1.780 -         currSlot = animSlots[ slotIdx ];
   1.781 -
   1.782 -         masterFunction_multiLang( currSlot );
   1.783 -       }
   1.784 -            
   1.785 -            MEAS__Capture_Post_Master_Point;
   1.786 -    
   1.787 -      masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.788 -      flushRegisters();
   1.789 -    } 
   1.790 - }
   1.791 -#endif  //MODE__MULTI_LANG
   1.792 -#endif  //MODE__MULTI_PROCESS
   1.793 -
   1.794 -
   1.795 -//This version of the master selects one of three loops, depending upon
   1.796 -// whether stand-alone single language (just slaves), or standalone with
   1.797 -// tasks, or multi-lang (implies multi-process)
   1.798 -void animationMaster( void *initData, SlaveVP *masterVP )
   1.799 - { 
   1.800 -   int32           slotIdx;
   1.801 -   AnimSlot       *currSlot;
   1.802 -      //Used while scanning and filling animation slots
   1.803 -   AnimSlot      **animSlots;
   1.804 -   
   1.805 -      //Local copies, for performance
   1.806 -   MasterEnv      *masterEnv;
   1.807 -   int32           thisCoresIdx;
   1.808 -   
   1.809 -   //======================== Initializations ========================
   1.810 -   masterEnv        = (MasterEnv*)_PRTopEnv;
   1.811 -   
   1.812 -   thisCoresIdx     = masterVP->coreAnimatedBy;
   1.813 -   animSlots        = masterEnv->allAnimSlots[thisCoresIdx];
   1.814 -      
   1.815 -      HOLISTIC__Insert_Master_Global_Vars;
   1.816 -   
   1.817 -   //======================== animationMaster ========================
   1.818 -   //Have three different modes, and the master behavior is different for
   1.819 -   // each, so jump to the loop that corresponds to the mode.
   1.820 -   //
   1.821 -   switch(mode)
   1.822 -    { case StandaloneSlavesOnly: 
   1.823 -         while(1)
   1.824 -          {       MEAS__Capture_Pre_Master_Point
   1.825 -            for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.826 -             {
   1.827 -               currSlot = animSlots[ slotIdx ];
   1.828 -
   1.829 -               masterFunction_StandaloneSlavesOnly( currSlot );
   1.830 -             }
   1.831 -                  MEAS__Capture_Post_Master_Point;
   1.832 -            masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.833 -            flushRegisters();
   1.834 -          } 
   1.835 -      case StandaloneWTasks:     
   1.836 -         while(1)
   1.837 -          {       MEAS__Capture_Pre_Master_Point
   1.838 -            for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.839 -             {
   1.840 -               currSlot = animSlots[ slotIdx ];
   1.841 -
   1.842 -               masterFunction_StandaloneWTasks( currSlot );
   1.843 -             }
   1.844 -                  MEAS__Capture_Post_Master_Point;
   1.845 -            masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.846 -            flushRegisters();
   1.847 -          }
   1.848 -      case MultiLang:
   1.849 -         while(1)
   1.850 -          {       MEAS__Capture_Pre_Master_Point
   1.851 -            for( slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++)
   1.852 -             {
   1.853 -               currSlot = animSlots[ slotIdx ];
   1.854 -
   1.855 -               masterFunction_multiLang( currSlot );
   1.856 -             }
   1.857 -                  MEAS__Capture_Post_Master_Point;
   1.858 -            masterSwitchToCoreCtlr( masterVP ); //returns when ctlr switches back to master
   1.859 -            flushRegisters();
   1.860 -          } 
   1.861 +            HOLISTIC__Record_Assigner_end;
   1.862 +      return;
   1.863      }
   1.864   }
   1.865 -
   1.866 +*/
   1.867  
   1.868  inline
   1.869  void
   1.870 -masterFunction_multiLang( AnimSlot  *currSlot )
   1.871 +masterFunction_MultiLang( AnimSlot  *slot )
   1.872   {    //Scan the animation slots
   1.873     int32           magicNumber;
   1.874     SlaveVP        *slave;
   1.875 -   SlaveVP        *assignedSlaveVP;
   1.876 -   PRSemEnv       *semanticEnv;
   1.877 +   PRLangEnv      *langEnv;
   1.878     PRReqst        *req;
   1.879     RequestHandler  requestHandler;
   1.880 +   PRProcess      *process;
   1.881  
   1.882 -         //Check if newly-done slave in slot, which will need request handled
   1.883 -      if( currSlot->workIsDone )
   1.884 -       { currSlot->workIsDone = FALSE;
   1.885 -         currSlot->needsWorkAssigned = TRUE;
   1.886 -       
   1.887 -               HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
   1.888 -               MEAS__startReqHdlr;
   1.889 -               
   1.890 -         
   1.891 -            //process the request made by the slave (held inside slave struc)
   1.892 -         slave = currSlot->slaveAssignedToSlot;
   1.893 -         req = slave->request;
   1.894 +      //Check if newly-done slave in slot, which will need request handled
   1.895 +   if( slot->workIsDone )
   1.896 +    { slot->workIsDone = FALSE;
   1.897 +      slot->needsWorkAssigned = TRUE;
   1.898  
   1.899 -            //If the requesting slave is a slot slave, and request is not
   1.900 -            // task-end, then turn it into a free task slave. 
   1.901 -         if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd )
   1.902 -            replaceWithNewSlotSlv( slave );
   1.903 +            HOLISTIC__Record_AppResponder_start; //TODO: update to check which process for each slot
   1.904 +            MEAS__startReqHdlr;
   1.905  
   1.906 -         //Handle task create and end first -- they're special cases..
   1.907 -         switch( req->reqType )
   1.908 -          { case TaskEnd: 
   1.909 -             { //do PR handler, which calls lang's hdlr and does recycle of
   1.910 -               // free task slave if needed -- PR handler checks for free task Slv
   1.911 -               PRHandle_EndTask( slave );                               break;
   1.912 -             }
   1.913 -            case TaskCreate:
   1.914 -             { //Do PR's create-task handler, which calls the lang's hdlr
   1.915 -               // PR handler checks for free task Slv
   1.916 -               PRHandle_CreateTask( slave );                            break;
   1.917 -             }
   1.918 -            case SlvCreate:    PRHandle_CreateSlave( slave );           break;
   1.919 -            case SlvDissipate: PRHandle_Dissipate( slave );             break;
   1.920 -            case Service:      PR_int__handle_PRServiceReq( slave );    break; //resume into PR's own semantic env
   1.921 -            case Hardware: //for future expansion
   1.922 -            case IO:       //for future expansion
   1.923 -            case OSCall:   //for future expansion
   1.924 -                PR_int__throw_exception("Not implemented");             break;
   1.925 -            case Language: //normal sem request
   1.926 -              magicNumber = req->langMagicNumber;
   1.927 -              semanticEnv = PR_PI__give_sem_env_for( slave, magicNumber );
   1.928 -              requestHandler = semanticEnv->requestHdlr;
   1.929 -              (*requestHandler)( req->semReq, slave, semanticEnv );
   1.930 +
   1.931 +         //process the request made by the slave (held inside slave struc)
   1.932 +      slave = slot->slaveAssignedToSlot;
   1.933 +      req = slave->request;
   1.934 +
   1.935 +         //If the requesting slave is a slot slave, and request is not
   1.936 +         // task-end, then turn it into a free task slave. 
   1.937 +      if( slave->typeOfVP == SlotTaskSlv && req->reqType != TaskEnd )
   1.938 +         PR_int__replace_with_new_slot_slv( slave );
   1.939 +
   1.940 +      //Handle task create and end first -- they're special cases..
   1.941 +      switch( req->reqType )
   1.942 +       { case TaskEnd: 
   1.943 +          { //do PR handler, which calls lang's hdlr and does recycle of
   1.944 +            // free task slave if needed -- PR handler checks for free task Slv
   1.945 +            PRHandle_EndTask( req, slave );                          break;
   1.946            }
   1.947 +         case TaskCreate:
   1.948 +          { //Do PR's create-task handler, which calls the lang's hdlr
   1.949 +            // PR handler checks for free task Slv
   1.950 +            PRHandle_CreateTask( req, slave );                       break;
   1.951 +          }
   1.952 +         case SlvCreate:    PRHandle_CreateSlave( req, slave );      break;
   1.953 +         case SlvDissipate: PRHandle_Dissipate( req, slave );        break;
   1.954 +         case Service:      PR_int__handle_PRServiceReq( slave );    break; //resume into PR's own language env
   1.955 +         case Hardware: //for future expansion
   1.956 +         case IO:       //for future expansion
   1.957 +         case OSCall:   //for future expansion
   1.958 +            PR_int__throw_exception("Not implemented", slave, NULL); break;
   1.959 +         case Language: //normal lang request
   1.960 +          { magicNumber = req->langMagicNumber;
   1.961 +            langEnv = PR_PI__give_lang_env_for( slave, magicNumber );
   1.962 +            (*req->handler)( req->langReq, slave, langEnv );
   1.963 +          }
   1.964 +       }
   1.965  
   1.966 +           MEAS__endReqHdlr;          
   1.967             HOLISTIC__Record_AppResponder_end;
   1.968 -           MEAS__endReqHdlr;          
   1.969 -       } //if have request to be handled
   1.970 -      
   1.971 -      if( currSlot->needsWorkAssigned )
   1.972 -       {
   1.973 -               HOLISTIC__Record_Assigner_start;
   1.974 -                  
   1.975 -            //Scan sem environs, looking for semEnv with ready work.
   1.976 -            // call the Assigner for that sem Env, to get a slave for the slot
   1.977 -         assignedSlaveVP = assignWork( semanticEnv, currSlot );
   1.978 -       
   1.979 -            //if work found, put into slot, and adjust flags and state
   1.980 -         if( assignedSlaveVP != NULL )
   1.981 -          { currSlot->slaveAssignedToSlot = assignedSlaveVP;
   1.982 -            assignedSlaveVP->animSlotAssignedTo = currSlot;
   1.983 -            currSlot->needsWorkAssigned  = FALSE;
   1.984 -          }
   1.985 -               HOLISTIC__Record_Assigner_end;
   1.986 -       }//if slot needs slave assigned
   1.987 +    } //if have request to be handled
   1.988 +
   1.989 +   if( slot->needsWorkAssigned )
   1.990 +    {
   1.991 +            HOLISTIC__Record_Assigner_start;
   1.992 +
   1.993 +         //Pick a process to get this slot
   1.994 +      process = pickAProcess( slot );
   1.995 +
   1.996 +         //Scan lang environs, looking for langEnv with ready work.
   1.997 +         // call the Assigner for that lang Env, to get a slave for the slot
   1.998 +      assignWork( process, slot );
   1.999 +
  1.1000 +            HOLISTIC__Record_Assigner_end;
  1.1001 +    }//if slot needs slave assigned
  1.1002   }
  1.1003  
  1.1004 -//==========================================================================
  1.1005 -/*When a task in a slot slave suspends, the slot slave has to be changed to
  1.1006 - * a free task slave, then the slot slave replaced.  The replacement can be
  1.1007 - * either a recycled free task slave that finished it's task and has been
  1.1008 - * idle in the recycle queue, or else create a new slave to be the slot slave.
  1.1009 - *The master only calls this with a slot slave that needs to be replaced.
  1.1010 +/*When several processes exist, use some pattern for picking one to give
  1.1011 + * the animation slot to.
  1.1012 + *First, it has to be a process that has work available.
  1.1013 + *For now, just do a round-robin
  1.1014   */
  1.1015 -inline void
  1.1016 -replaceWithNewSlotSlv( SlaveVP *requestingSlv, PRProcess *process )
  1.1017 - { SlaveVP *newSlotSlv;
  1.1018 -
  1.1019 - When slot slave converted to a free task slave, insert the process pointer -- slot slaves are not assigned to any process;
  1.1020 - when convert from slot slave to free task slave, check what should do about num (live slaves + live tasks) inside VSs's task stub, and properly update process's count of liveFreeTaskSlaves 
  1.1021 -
  1.1022 -      //get a new slave to be the slot slave
  1.1023 -   newSlotSlv     = readPrivQ( process->freeTaskSlvRecycleQ );
  1.1024 -   if( newSlotSlv == NULL )
  1.1025 -    { newSlotSlv  = PR_int__create_slaveVP( &idle_fn, NULL, process, 0);
  1.1026 -         //just made a new free task slave, so count it
  1.1027 -      process->numLiveFreeTaskSlvs += 1;
  1.1028 +inline
  1.1029 +PRProcess *
  1.1030 +pickAProcess( AnimSlot *slot )
  1.1031 + { int32 idx;
  1.1032 +   PRProcess *process;
  1.1033 + 
  1.1034 +   for( idx = _PRTopEnv->currProcessIdx; idx < _PRTopEnv->numProcesses; idx++)
  1.1035 +    {
  1.1036 +      process = _PRTopEnv->processes[ idx ];
  1.1037 +      if( process->numEnvsWithWork != 0 )
  1.1038 +       { _PRTopEnv->currProcessIdx = idx;
  1.1039 +         return process;
  1.1040 +       }
  1.1041      }
  1.1042 -   
  1.1043 -      //set slave values to make it the slot slave
  1.1044 -   newSlotSlv->metaTask              = NULL;
  1.1045 -   newSlotSlv->typeOfVP              = SlotTaskSlv;
  1.1046 -//   newSlotSlv->needsTaskAssigned     = TRUE;
  1.1047 -   
  1.1048 -      //a slot slave is pinned to a particular slot on a particular core
  1.1049 -      //Note, this happens before the request is seen by handler, so nothing
  1.1050 -      // has had a chance to change the coreAnimatedBy or anything else..
  1.1051 -   newSlotSlv->animSlotAssignedTo = requestingSlv->animSlotAssignedTo;
  1.1052 -   newSlotSlv->coreAnimatedBy     = requestingSlv->coreAnimatedBy;
  1.1053 -    
  1.1054 -      //put it into the slot slave matrix
  1.1055 -   int32 slotNum = requestingSlv->animSlotAssignedTo->slotIdx;
  1.1056 -   int32 coreNum = requestingSlv->coreAnimatedBy;
  1.1057 -   process->slotTaskSlvs[coreNum][slotNum] = newSlotSlv;
  1.1058 -
  1.1059 -      //Fix up requester, to be an extra slave now (but not an ended one)
  1.1060 -      // because it's active, doesn't go into freeTaskSlvRecycleQ
  1.1061 -   requestingSlv->typeOfVP = FreeTaskSlv;
  1.1062 -   requestingSlv->metaTask->taskType = FreeTask;
  1.1063 +   for( idx = 0; idx < _PRTopEnv->currProcessIdx; idx++)
  1.1064 +    {
  1.1065 +      process = _PRTopEnv->processes[ idx ];
  1.1066 +      if( process->numEnvsWithWork != 0 )
  1.1067 +       { _PRTopEnv->currProcessIdx = idx;
  1.1068 +         return process;
  1.1069 +       }
  1.1070 +    }
  1.1071 +      //none found
  1.1072 +   return NULL;
  1.1073   }
  1.1074  
  1.1075 -
  1.1076 -
  1.1077  /*This does:
  1.1078 - * 1) searches the semantic environments for one with work ready
  1.1079 + * 1) searches the language environments for one with work ready
  1.1080   *    if finds one, asks its assigner to return work
  1.1081   * 2) checks what kind of work: new task, resuming task, resuming slave
  1.1082   *    if new task, gets the slot slave and assigns task to it and returns slave
  1.1083 @@ -861,10 +638,10 @@
  1.1084   * 3) if no work found, then prune former task slaves waiting to be recycled.
  1.1085   *    If no work and no slaves to prune, check for shutdown conditions.
  1.1086   * 
  1.1087 - * Semantic env keeps its own work in its own structures, and has its own
  1.1088 + * language env keeps its own work in its own structures, and has its own
  1.1089   *  assigner.  It chooses 
  1.1090   * However, include a switch that switches-in an override assigner, which
  1.1091 - *  sees all the work in all the semantic env's.  This is most likely  
  1.1092 + *  sees all the work in all the language env's.  This is most likely  
  1.1093   *  generated by static tools and included in the executable.  That means it
  1.1094   *  has to be called via a registered pointer from here.  The idea is that
  1.1095   *  the static tools know which languages are grouped together.. and the
  1.1096 @@ -872,7 +649,8 @@
  1.1097   *  all the languages in a unified way..  Don't really expect this to happen,
  1.1098   *  but am making it possible.
  1.1099   */
  1.1100 -inline SlaveVP *
  1.1101 +inline 
  1.1102 +SlaveVP *
  1.1103  assignWork( PRProcess *process, AnimSlot *slot )
  1.1104   { SlaveVP        *returnSlv;
  1.1105     int32           coreNum, slotNum;
  1.1106 @@ -881,147 +659,75 @@
  1.1107     coreNum = slot->coreSlotIsOn;
  1.1108     
  1.1109     if( process->overrideAssigner != NULL )
  1.1110 -    { assignedMetaTask = (*process->overrideAssigner)( process, slot );
  1.1111 -      if( assignedMetaTask != NULL )
  1.1112 -       {
  1.1113 -            //have work, so reset Done flag (caused by work generated on other core)
  1.1114 -//         if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf
  1.1115 -//            process->coreIsDone[coreNum] = FALSE;   //don't just write always
  1.1116 -         
  1.1117 -//         switch( assignedMetaTask->taskType )
  1.1118 -//          { case GenericSlave:  goto AssignSlave;
  1.1119 -//            case FreeTask:      goto AssignSlave;
  1.1120 -//            case SlotTask:      goto AssignNewTask;
  1.1121 -//            default:      PR_int__throw_exception( "unknown task type ret by assigner" );
  1.1122 -//          }
  1.1123 -            //If meta task has a slave attached, then goto assign slave,
  1.1124 -            // else it's a new task, so goto where assign it to a slot slave
  1.1125 -         if( assignedMetaTask->slaveAssignedTo != NULL )
  1.1126 -            goto AssignSlave;
  1.1127 -         else
  1.1128 -            goto AssignNewTask;
  1.1129 +    { if( process->numEnvsWithWork != 0 )
  1.1130 +       {  (*process->overrideAssigner)( process, slot ); //calls PR fn that inserts work into slot
  1.1131 +         goto ReturnAfterAssigningWork; //quit for-loop, cause found work
  1.1132         }
  1.1133 -      else //metaTask is NULL, so no work..
  1.1134 +      else
  1.1135           goto NoWork;
  1.1136      }
  1.1137     
  1.1138 -      //If here, then no override assigner, so search semantic envs for work
  1.1139 -   int32 envIdx, numEnvs; PRSemEnv **semEnvs, *semEnv; SlaveAssigner assigner;
  1.1140 -   semEnvs = process->semEnvs;
  1.1141 -   numEnvs = process->numSemEnvs;
  1.1142 -   for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep semEnvs in hash & array
  1.1143 -    { semEnv = semEnvs[envIdx];
  1.1144 -      if( semEnv->hasWork )
  1.1145 -       { assigner = semEnv->slaveAssigner; 
  1.1146 -         assignedMetaTask = (*assigner)( semEnv, slot );
  1.1147 -         
  1.1148 -            //have work, so reset Done flag (caused by work generated on other core)
  1.1149 -//         if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf
  1.1150 -//            process->coreIsDone[coreNum] = FALSE;   //don't just write always
  1.1151 -         
  1.1152 -//         switch( assignedMetaTask->taskType )
  1.1153 -//          { case GenericSlave: goto AssignSlave;
  1.1154 -//            case FreeTask:     goto AssignSlave;
  1.1155 -//            case SlotTask:     goto AssignNewTask;
  1.1156 -//            default:      PR_int__throw_exception( "unknown task type ret by assigner" );
  1.1157 -//          }
  1.1158 -            //If meta task has a slave attached, then goto assign slave,
  1.1159 -            // else it's a new task, so goto where assign it to a slot slave
  1.1160 -         if( assignedMetaTask->slaveAssignedTo != NULL )
  1.1161 -            goto AssignSlave;
  1.1162 -         else
  1.1163 -            goto AssignNewTask;
  1.1164 +      //If here, then no override assigner, so search language envs for work
  1.1165 +   int32 envIdx, numEnvs; PRLangEnv **langEnvsList, *langEnv;
  1.1166 +   langEnvsList = process->langEnvsList;
  1.1167 +   numEnvs = process->numLangEnvs;
  1.1168 +   for( envIdx = 0; envIdx < numEnvs; envIdx++ ) //keep langEnvs in hash & array
  1.1169 +    { langEnv = langEnvsList[envIdx];
  1.1170 +      if( langEnv->hasWork )
  1.1171 +       { (*langEnv->slaveAssigner)( langEnv, slot ); //assigner calls PR to put slave/task into slot
  1.1172 +         goto ReturnAfterAssigningWork; //quit for-loop, cause found work
  1.1173 +         //NOTE: bad search alg -- should start where left off, then wrap around
  1.1174         }
  1.1175      }
  1.1176 -   //If reach here, then have searched all semEnv's & none have work..
  1.1177 +   //If reach here, then have searched all langEnv's & none have work..
  1.1178     
  1.1179 - NoWork:
  1.1180 -      //No work, if reach here..
  1.1181 -    { goto ReturnTheSlv;
  1.1182 -    }
  1.1183 - 
  1.1184 - AssignSlave: //Have a metaTask attached to a slave, so get the slave & ret it
  1.1185 -    { returnSlv = assignedMetaTask->slaveAssignedTo;
  1.1186 -      returnSlv->coreAnimatedBy   = coreNum;
  1.1187 -    
  1.1188 -      goto ReturnTheSlv;
  1.1189 -    }
  1.1190 - 
  1.1191 - AssignNewTask: //Have a new metaTask that has no slave yet.. assign to slot slv
  1.1192 + NoWork:     //No work, if end up here..
  1.1193      { 
  1.1194 -         //get the slot slave to assign the task to..
  1.1195 -      slotNum = slot->slotIdx;
  1.1196 -      returnSlv = process->slotTaskSlvs[coreNum][slotNum];
  1.1197 -
  1.1198 -         //point slave to task's function
  1.1199 -      PR_int__reset_slaveVP_to_TopLvlFn( returnSlv, 
  1.1200 -                       assignedMetaTask->topLevelFn, assignedMetaTask->initData );
  1.1201 -      returnSlv->metaTask = assignedMetaTask;
  1.1202 -      assignedMetaTask->slaveAssignedTo = returnSlv;
  1.1203 -//      returnSlv->needsTaskAssigned = FALSE;  //slot slave is a "Task" slave type
  1.1204 -      
  1.1205 -         //have work, so reset Done flag, if was set
  1.1206 -//      if( process->coreIsDone[coreNum] == TRUE ) //reads are higher perf
  1.1207 -//         process->coreIsDone[coreNum] = FALSE;   //don't just write always
  1.1208 -      
  1.1209 -      goto ReturnTheSlv;
  1.1210 -    }
  1.1211 - 
  1.1212 -
  1.1213 - ReturnTheSlv:  //All paths goto here.. to provide single point for holistic..
  1.1214 -
  1.1215     #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
  1.1216 -   if( returnSlv == NULL )
  1.1217 -    { returnSlv = process->idleSlv[coreNum][slotNum]; 
  1.1218 +      returnSlv = process->idleSlv[coreNum][slotNum]; 
  1.1219      
  1.1220           //things that would normally happen in resume(), but idle VPs
  1.1221           // never go there
  1.1222        returnSlv->numTimesAssignedToASlot++; //gives each idle unit a unique ID
  1.1223        Unit newU;
  1.1224 -      newU.vp = returnSlv->slaveID;
  1.1225 +      newU.vp = returnSlv->slaveNum;
  1.1226        newU.task = returnSlv->numTimesAssignedToASlot;
  1.1227        addToListOfArrays(Unit,newU,process->unitList);
  1.1228  
  1.1229        if (returnSlv->numTimesAssignedToASlot > 1) //make a dependency from prev idle unit
  1.1230         { Dependency newD;             // to this one
  1.1231 -         newD.from_vp = returnSlv->slaveID;
  1.1232 +         newD.from_vp = returnSlv->slaveNum;
  1.1233           newD.from_task = returnSlv->numTimesAssignedToASlot - 1;
  1.1234 -         newD.to_vp = returnSlv->slaveID;
  1.1235 +         newD.to_vp = returnSlv->slaveNum;
  1.1236           newD.to_task = returnSlv->numTimesAssignedToASlot;
  1.1237           addToListOfArrays(Dependency, newD ,process->ctlDependenciesList);  
  1.1238         }
  1.1239 +   #endif
  1.1240 +            HOLISTIC__Record_Assigner_end;
  1.1241 +      return;
  1.1242      }
  1.1243 -   else //have a slave will be assigned to the slot
  1.1244 -    { //assignSlv->numTimesAssigned++;
  1.1245 -         //get previous occupant of the slot
  1.1246 -      Unit prev_in_slot = 
  1.1247 -         process->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum];
  1.1248 -      if(prev_in_slot.vp != 0) //if not first slave in slot, make dependency
  1.1249 -       { Dependency newD;      // is a hardware dependency
  1.1250 -         newD.from_vp = prev_in_slot.vp;
  1.1251 -         newD.from_task = prev_in_slot.task;
  1.1252 -         newD.to_vp = returnSlv->slaveID;
  1.1253 -         newD.to_task = returnSlv->numTimesAssignedToASlot;
  1.1254 -         addToListOfArrays(Dependency,newD,process->hwArcs);   
  1.1255 -       }
  1.1256 -      prev_in_slot.vp = returnSlv->slaveID; //make new slave the new previous
  1.1257 -      prev_in_slot.task = returnSlv->numTimesAssignedToASlot;
  1.1258 -      process->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] =
  1.1259 -         prev_in_slot;        
  1.1260 + 
  1.1261 + ReturnAfterAssigningWork:  //All paths goto here.. to provide single point for holistic..
  1.1262 +    {
  1.1263 +            HOLISTIC__Record_Assigner_end;
  1.1264 +      return;
  1.1265      }
  1.1266 -   #endif
  1.1267 -
  1.1268 -   return( returnSlv );
  1.1269   }
  1.1270  
  1.1271  
  1.1272 -/*In creator, only PR related things happen, and things in the langlet whose
  1.1273 +
  1.1274 +/*This is first thing called when creating a slave..  it hands off to the 
  1.1275 + * langlet's creator, then adds updates of its own..
  1.1276 + * 
  1.1277 + *There's a question of things like lang data, meta tasks, and such..
  1.1278 + *In creator, only PR related things happen, and things for the langlet whose
  1.1279   * creator construct was used.
  1.1280 - *Other langlet still gets a chance to create semData -- but by registering a
  1.1281 - * "createSemData" handler in the semEnv.  When a construct  of the langlet
  1.1282 - * calls "PR__give_sem_data()", if there is no semData for that langlet,
  1.1283 - * the PR will call the creator in the langlet's semEnv, place whatever it
  1.1284 - * makes as the semData in that slave for that langlet, and return that semData
  1.1285 + * 
  1.1286 + *Other langlets still get a chance to create langData -- but by registering a
  1.1287 + * "createLangData" handler in the langEnv.  When a construct  of the langlet
  1.1288 + * calls "PR__give_lang_data()", if there is no langData for that langlet,
  1.1289 + * the PR will call the creator in the langlet's langEnv, place whatever it
  1.1290 + * makes as the langData in that slave for that langlet, and return that langData
  1.1291   *
  1.1292   *So, as far as counting things, a langlet is only allowed to count creation
  1.1293   * of slaves it creates itself..  may have to change this later.. add a way for
  1.1294 @@ -1034,87 +740,92 @@
  1.1295   *PR itself needs to create the slave, then update numLiveSlaves in process,
  1.1296   * copy processID from requestor to newly created
  1.1297   */
  1.1298 -PRHandle_CreateSlave( PRReqst *req, SlaveVP *requestingSlv )
  1.1299 - { SlaveVP *newSlv;
  1.1300 -   PRMetaTask metaTask;
  1.1301 +inline
  1.1302 +void
  1.1303 +PRHandle_CreateSlave( PRReqst *req, SlaveVP *slave )
  1.1304 + { SlaveVP   *newSlv;
  1.1305     PRProcess *process;
  1.1306 +   PRLangEnv *protoLangEnv;
  1.1307   
  1.1308 -   process = requestingSlv->processSlaveIsIn;
  1.1309 -   newSlv = PR_int__create_slaveVP();
  1.1310 +   process = slave->processSlaveIsIn;
  1.1311 +   protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, req->langMagicNumber );
  1.1312 +   
  1.1313 +//   newSlv  = PR_int__create_slave( req->topLevelFn, req->initData );
  1.1314 +   
  1.1315 +   //create slv has diff prototype than standard reqst hdlr
  1.1316 +   newSlv = 
  1.1317 +      (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv)); 
  1.1318 +   
  1.1319     newSlv->typeOfVP = GenericSlv;
  1.1320     newSlv->processSlaveIsIn = process;
  1.1321 +   newSlv->ID = req->ID;
  1.1322     process->numLiveGenericSlvs += 1;
  1.1323 -   metaTask = PR_int__create_slave_meta_task();
  1.1324 -   metaTask->taskID = req->ID;
  1.1325 -//   metaTask->taskType = GenericSlave;
  1.1326 -   
  1.1327 -   (*req->handler)( req->semReq, newSlv, requestingSlv, semEnv );
  1.1328   }
  1.1329  
  1.1330 -/*The dissipate handler has to, sdate the number of slaves of the type, within
  1.1331 +/*The dissipate handler has to, update the number of slaves of the type, within
  1.1332   * the process, and call the langlet handler linked into the request,
  1.1333   * and after that returns, then call the PR function that frees the slave state
  1.1334   * (or recycles the slave).
  1.1335   * 
  1.1336   *The PR function that frees the slave state has to also free all of the
  1.1337 - * semData in the slave..  or else reset all of the semDatas.. by, say, marking
  1.1338 - * them, then in PR__give_semData( magicNum ) call the langlet registered
  1.1339 - * "resetSemData" Fn.
  1.1340 + * langData in the slave..  or else reset all of the langDatas.. by, say, marking
  1.1341 + * them, then in PR__give_langData( magicNum ) call the langlet registered
  1.1342 + * "resetLangData" Fn.
  1.1343   */
  1.1344 -PRHandle_Dissipate( SlaveVP *slave )
  1.1345 +inline
  1.1346 +void
  1.1347 +PRHandle_Dissipate( PRReqst *req, SlaveVP *slave )
  1.1348   { PRProcess *process;
  1.1349 -   void      *semEnv;
  1.1350 +   PRLangEnv *protoLangEnv;
  1.1351     
  1.1352     process = slave->processSlaveIsIn;
  1.1353     
  1.1354        //do the language's dissipate handler
  1.1355 -   semEnv = PR_int__give_sem_env_for_slave( slave, slave->request->langMagicNumber );
  1.1356 -   (*slave->request->handler)( slave->request->semReq, slave, semEnv );
  1.1357 +   protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, slave->request->langMagicNumber );
  1.1358 +   
  1.1359 +   if(req->handler != NULL)
  1.1360 +      (*req->handler)( req->langReq, slave, PR_int__give_lang_env(protoLangEnv) );
  1.1361     
  1.1362     process->numLiveGenericSlvs -= 1;
  1.1363 -   PR_int__recycle_slave_multilang( requestingSlv );
  1.1364 +   PR_int__recycle_slave__ML( slave );
  1.1365    
  1.1366        //check End Of Process Condition
  1.1367     if( process->numLiveTasks == 0 &&
  1.1368         process->numLiveGenericSlvs == 0 )
  1.1369 -      PR_SS__shutdown_process( process );
  1.1370 +      PR_SS__shutdown_process__ML( process );
  1.1371   }
  1.1372  
  1.1373  /*Create task is a special form, that has PR behavior in addition to plugin
  1.1374 - * behavior.  Master calls this first, and then calls the plugin's
  1.1375 + * behavior.  Master calls this first, and it then calls the plugin's
  1.1376   * create task handler.
  1.1377   * 
  1.1378   *Note: the requesting slave must be either generic slave or free task slave
  1.1379   */
  1.1380 -inline PRMetaTask *
  1.1381 -PRHandle_CreateTask( PRReqst *req, SlaveVP *requestingSlv )
  1.1382 +inline
  1.1383 +void
  1.1384 +PRHandle_CreateTask( PRReqst *req, SlaveVP *slave )
  1.1385   { PRMetaTask     *metaTask;
  1.1386     PRProcess      *process;
  1.1387 -   PRLangMetaTask *langMetaTask;
  1.1388 -   PRSemEnv       *semanticEnv;
  1.1389 +   PRLangEnv      *protoLangEnv;
  1.1390 +   void           *task;
  1.1391                  
  1.1392 -   process = requestingSlv->processSlaveIsIn;
  1.1393 -
  1.1394 -   metaTask             = PR_int__create_meta_task( req );
  1.1395 -   metaTask->taskID     = req->ID; //may be NULL
  1.1396 +   process = slave->processSlaveIsIn;
  1.1397 +   
  1.1398 +   protoLangEnv = PR_int__give_proto_lang_env_for_slave__ML( slave, 
  1.1399 +                                                        req->langMagicNumber );
  1.1400 +   
  1.1401 +   //Do the langlet's create-task handler, which keeps the task
  1.1402 +   // inside the langlet's lang env, but returns the langMetaTask
  1.1403 +   // so PR can put stuff into the prolog
  1.1404 +   task = 
  1.1405 +      (*req->createHdlr)(req->langReq, slave, PR_int__give_lang_env(protoLangEnv) );
  1.1406 +   metaTask = PR_int__give_prolog_of_task( task );
  1.1407 +   metaTask->ID         = req->ID; //may be NULL
  1.1408     metaTask->topLevelFn = req->topLevelFn;
  1.1409     metaTask->initData   = req->initData;
  1.1410             
  1.1411     process->numLiveTasks += 1;
  1.1412  
  1.1413 -   semanticEnv = PR_int__give_sem_env_for_slave( slave, 
  1.1414 -                                          req->langMagicNumber );
  1.1415 -   
  1.1416 -   //Do the langlet's create-task handler, which keeps the task
  1.1417 -   // inside the langlet's sem env, but returns the langMetaTask
  1.1418 -   // so PR can hook it to the PRMetaTask.
  1.1419 -   //(Could also do PRMetaTask as a prolog -- make a Fn that takes the size
  1.1420 -   // of the lang's metaTask, and alloc's that plus the prolog and returns
  1.1421 -   // ptr to position just above the prolog)
  1.1422 -   langMetaTask = (*req->handler)(req->semReq, slave, semanticEnv);
  1.1423 -   metaTask->langMetaTask      = langMetaTask;
  1.1424 -   langMetaTask->protoMetaTask = metaTask;
  1.1425 -
  1.1426     return;
  1.1427   }
  1.1428  
  1.1429 @@ -1125,7 +836,7 @@
  1.1430   * so, here, don't worry about assigning a new task to the slot slave.
  1.1431   *For 2, the task's slot slave has been converted to a free task slave, which
  1.1432   * now has nothing more to do, so send it to the recycle Q (which includes
  1.1433 - * freeing all the semData and meta task structs alloc'd for it).  Then
  1.1434 + * freeing all the langData and meta task structs alloc'd for it).  Then
  1.1435   * decrement the live task count and check end condition.
  1.1436   * 
  1.1437   *PR has to update count of live tasks, and check end of process condition.
  1.1438 @@ -1141,31 +852,31 @@
  1.1439   * 
  1.1440   *Note: slave may be either a slot slave or a free task slave. 
  1.1441   */
  1.1442 -inline void
  1.1443 -PRHandle_EndTask( SlaveVP *requestingSlv )
  1.1444 - { void       *semEnv;
  1.1445 -   PRReqst    *req;  
  1.1446 -   PRLangMetaTask *langMetaTask;
  1.1447 +inline 
  1.1448 +void
  1.1449 +PRHandle_EndTask( PRReqst *req, SlaveVP *requestingSlv )
  1.1450 + { void       *langEnv;
  1.1451     PRProcess  *process;
  1.1452 +   void       *langMetaTask;
  1.1453     
  1.1454 -   req = requestingSlv->request;
  1.1455 -   semEnv = PR_int__give_sem_env_of_req( req, requestingSlv ); //magic num in req
  1.1456 -   langMetaTask = requestingSlv->metaTask->langMetaTask;
  1.1457 +   langEnv = PR_int__give_lang_env_of_req__ML( req, requestingSlv ); //magic num in req
  1.1458 +   langMetaTask = PR_int__give_lang_meta_task_from_slave__ML( requestingSlv, req->langMagicNumber);
  1.1459     
  1.1460     //Do the langlet's request handler
  1.1461 -   //Want to keep PR structs hidden from plugin, so extract semReq..
  1.1462 -   (*req->handler)( langMetaTask, req->semReq, semEnv );
  1.1463 +   //Want to keep PR structs hidden from plugin, so extract langReq..
  1.1464 +   (*req->handler)( req->langReq, requestingSlv, langEnv );
  1.1465     
  1.1466     //Now that the langlet's done with it, recycle the slave if it's a freeTaskSlv
  1.1467     if( requestingSlv->typeOfVP == FreeTaskSlv )
  1.1468 -      PR_int__recycle_slave_multilang( requestingSlv );
  1.1469 +      PR_int__recycle_slave__ML( requestingSlv );
  1.1470     
  1.1471     process->numLiveTasks -= 1;
  1.1472    
  1.1473        //check End Of Process Condition
  1.1474     if( process->numLiveTasks == 0 &&
  1.1475         process->numLiveGenericSlvs == 0 )
  1.1476 -      //Tell the core controller to do wakeup of any waiting OS thread
  1.1477 -      PR_SS__shutdown_process( process );
  1.1478 +    { //Tell the core controller to do wakeup of any waiting OS thread
  1.1479 +      PR_SS__shutdown_process__ML( process );
  1.1480 +    }
  1.1481   }
  1.1482  
     2.1 --- a/CoreController.c	Sun Nov 04 18:39:28 2012 -0800
     2.2 +++ b/CoreController.c	Mon Jan 14 15:31:23 2013 -0800
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright 2010  OpenSourceStewardshipFoundation
     2.6 + * Copyright 2010  OpenSourceResearchInstitute
     2.7   *
     2.8   * Licensed under BSD
     2.9   */
    2.10 @@ -113,12 +113,12 @@
    2.11  
    2.12        //make sure the controllers all start at same time, by making them wait
    2.13     pthread_mutex_lock(  &suspendLock );
    2.14 -   while( !(_PRTopEnv->setupComplete) )
    2.15 +   while( !(_PRTopEnv->firstProcessReady) )
    2.16      { pthread_cond_wait( &suspendCond, &suspendLock );
    2.17      }
    2.18     pthread_mutex_unlock( &suspendLock );
    2.19     
    2.20 -            HOLISTIC__CoreCtrl_Setup;
    2.21 +         HOLISTIC__CoreCtrl_Setup;
    2.22     
    2.23           DEBUG__printf1(TRUE, "started coreCtrlr", thisCoresIdx );
    2.24           
    2.25 @@ -219,7 +219,7 @@
    2.26  terminateCoreCtlr(SlaveVP *currSlv)
    2.27   {
    2.28     //first, free shutdown Slv that jumped here, then end the pthread
    2.29 -   PR_int__dissipate_slaveVP( currSlv );
    2.30 +   PR_int__dissipate_slaveVP__SL( currSlv );
    2.31     pthread_exit( NULL );
    2.32   }
    2.33  
     3.1 --- a/Defines/MEAS__macros_to_be_moved_to_langs.h	Sun Nov 04 18:39:28 2012 -0800
     3.2 +++ b/Defines/MEAS__macros_to_be_moved_to_langs.h	Mon Jan 14 15:31:23 2013 -0800
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
     3.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
     3.7   *  Licensed under GNU General Public License version 2
     3.8   *
     3.9   * Author: seanhalle@yahoo.com
     4.1 --- a/Defines/PR_defs.h	Sun Nov 04 18:39:28 2012 -0800
     4.2 +++ b/Defines/PR_defs.h	Mon Jan 14 15:31:23 2013 -0800
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
     4.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
     4.7   *  Licensed under GNU General Public License version 2
     4.8   *
     4.9   * Author: seanhalle@yahoo.com
     5.1 --- a/Defines/PR_defs__HW_constants.h	Sun Nov 04 18:39:28 2012 -0800
     5.2 +++ b/Defines/PR_defs__HW_constants.h	Mon Jan 14 15:31:23 2013 -0800
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - *  Copyright 2012 OpenSourceStewardshipFoundation
     5.6 + *  Copyright 2012 OpenSourceResearchInstitute
     5.7   *  Licensed under BSD
     5.8   *
     5.9   * Author: seanhalle@yahoo.com
    5.10 @@ -20,9 +20,9 @@
    5.11     // when work-stealing, can make bigger, at risk of losing cache affinity
    5.12  #define NUM_ANIM_SLOTS  1
    5.13  
    5.14 -   //number of PRSemEnv structs created inside a process -- can't start more
    5.15 +   //number of PRLangEnv structs created inside a process -- can't start more
    5.16     // than this many langlets inside a single process
    5.17 -#define NUM_SEM_ENVS_IN_PROCESS 64
    5.18 +#define NUM_IN_COLLECTION 64
    5.19  
    5.20     //These are for backoff inside core-loop, which reduces lock contention
    5.21  #define NUM_REPS_W_NO_WORK_BEFORE_YIELD      10
     6.1 --- a/HW_Dependent_Primitives/PR__HW_measurement.h	Sun Nov 04 18:39:28 2012 -0800
     6.2 +++ b/HW_Dependent_Primitives/PR__HW_measurement.h	Mon Jan 14 15:31:23 2013 -0800
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
     6.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
     6.7   *  Licensed under GNU General Public License version 2
     6.8   *
     6.9   * Author: seanhalle@yahoo.com
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/HW_Dependent_Primitives/PR__MetaInfo.c	Mon Jan 14 15:31:23 2013 -0800
     7.3 @@ -0,0 +1,26 @@
     7.4 +#include <unistd.h>
     7.5 +#include <fcntl.h>
     7.6 +#include <linux/types.h>
     7.7 +#include <linux/perf_event.h>
     7.8 +#include <errno.h>
     7.9 +#include <sys/syscall.h>
    7.10 +#include <linux/prctl.h>
    7.11 +
    7.12 +#include "../PR.h"
    7.13 +
    7.14 +void PR_SS__set_meta_info()
    7.15 + {
    7.16 +   garbage__delete;
    7.17 +   
    7.18 +   _PRTopEnv->metaInfo = PR_int__malloc( sizeof(PRSysMetaInfo) );
    7.19 +       //Meta info gets set by calls from the language during its init,
    7.20 +       // and info registered by calls from inside the application
    7.21 +   _PRTopEnv->metaInfo->assignerInfo;
    7.22 +
    7.23 +   //--------------------------
    7.24 +   //Application
    7.25 +   j += sprintf(buffer+j, "#\n# >> Application <<\n");
    7.26 +   j += sprintf(buffer+j, "# Name: %s\n", _PRTopEnv->metaInfo->appInfo);
    7.27 +   j += sprintf(buffer+j, "# Data Set:\n%s\n",_PRTopEnv->metaInfo->inputSet);
    7.28 +
    7.29 + }
    7.30 \ No newline at end of file
     8.1 --- a/HW_Dependent_Primitives/PR__primitives.h	Sun Nov 04 18:39:28 2012 -0800
     8.2 +++ b/HW_Dependent_Primitives/PR__primitives.h	Mon Jan 14 15:31:23 2013 -0800
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
     8.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
     8.7   *  Licensed under GNU General Public License version 2
     8.8   *
     8.9   * Author: seanhalle@yahoo.com
     9.1 --- a/HW_Dependent_Primitives/PR__primitives_asm.s	Sun Nov 04 18:39:28 2012 -0800
     9.2 +++ b/HW_Dependent_Primitives/PR__primitives_asm.s	Mon Jan 14 15:31:23 2013 -0800
     9.3 @@ -164,7 +164,7 @@
     9.4      movq    0x20(%rdi), %rsp         #restore stack pointer
     9.5      movq    0x18(%rdi), %rbp         #restore frame pointer
     9.6      #argument is in %rdi
     9.7 -    call    PR_int__dissipate_slaveVP
     9.8 +    call    PR_int__dissipate_slaveVP__SL
     9.9      movq    %rbp      , %rsp        #goto the coreCtlrs stack
    9.10      pop     %rbp        #restore the old framepointer
    9.11      ret                 #return from core controller
    10.1 --- a/PR.h	Sun Nov 04 18:39:28 2012 -0800
    10.2 +++ b/PR.h	Mon Jan 14 15:31:23 2013 -0800
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
    10.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
    10.7   *  Licensed under GNU General Public License version 2
    10.8   *
    10.9   * Author: seanhalle@yahoo.com
   10.10 @@ -30,25 +30,7 @@
   10.11  
   10.12  //================================ Typedefs =================================
   10.13  //
   10.14 -typedef unsigned long long    TSCount;
   10.15 -
   10.16 -typedef struct _AnimSlot      AnimSlot;
   10.17 -typedef struct _PRReqst       PRReqst;
   10.18 -typedef struct _SlaveVP       SlaveVP;
   10.19 -typedef struct _MasterVP      MasterVP;
   10.20 -typedef struct _IntervalProbe IntervalProbe;
   10.21 -typedef struct _PRMetaTask    PRMetaTask;
   10.22 -
   10.23 -
   10.24 -typedef SlaveVP *(*SlaveAssigner)  ( void *, AnimSlot*); //semEnv, slot for HW info
   10.25 -typedef void     (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv
   10.26 -typedef void     (*IndivReqHandler)( SlaveVP *, void * ); //prWReqst, semEnv
   10.27 -typedef void     (*TopLevelFnPtr)  ( void *, SlaveVP * ); //initData, animSlv
   10.28 -typedef void       TopLevelFn      ( void *, SlaveVP * ); //initData, animSlv
   10.29 -typedef void     (*ResumeSlvFnPtr) ( SlaveVP *, void * );
   10.30 -      //=========== MEASUREMENT STUFF ==========
   10.31 -        MEAS__Insert_Counter_Handler
   10.32 -      //========================================
   10.33 +#include "PR__structs.h"
   10.34  
   10.35  //============================ HW Dependent Fns ================================
   10.36  
   10.37 @@ -56,338 +38,9 @@
   10.38  #include "HW_Dependent_Primitives/PR__primitives.h"
   10.39  
   10.40  
   10.41 -//============= Request Related ===========
   10.42 -//
   10.43 -
   10.44 -enum PRReqstType  //avoid starting enums at 0, for debug reasons
   10.45 - {
   10.46 -   TaskCreate = 1,
   10.47 -   TaskEnd,
   10.48 -   SlvCreate,
   10.49 -   SlvDissipate,
   10.50 -   Language,
   10.51 -   Service,       //To invoke a PR provided equivalent of a language request (ex: probe)
   10.52 -   Hardware,
   10.53 -   IO,
   10.54 -   OSCall
   10.55 - };
   10.56 -
   10.57 -struct _PRReqst
   10.58 - {
   10.59 -   enum PRReqstType   reqType;//used for special forms that have PR behavior
   10.60 -   void              *semReq;
   10.61 -   PRProcess         *processReqIsIn;
   10.62 -   int32              langMagicNumber;
   10.63 -   TopLevelFn         topLevelFn;
   10.64 -   void              *initData;
   10.65 -   int32             *ID;
   10.66 -   
   10.67 -      //The request handling structure is a bit messy..  for special forms, 
   10.68 -      // such as create and dissipate, the language inserts pointer to handler
   10.69 -      // fn directly into the request..  might change to this for all requests
   10.70 -   IndivReqHandler    handler; //pointer to handler fn for create, dissip, etc
   10.71 -   
   10.72 -   PRReqst *nextReqst;
   10.73 - };
   10.74 -//PRReqst
   10.75 -
   10.76 -enum PRServReqType   //These are equivalent to semantic requests, but for
   10.77 - {                    // PR's services available directly to app, like OS
   10.78 -   make_probe = 1,    // and probe services -- like a PR-wide built-in lang
   10.79 -   throw_excp,
   10.80 -   openFile,
   10.81 -   otherIO
   10.82 - };
   10.83 -
   10.84 -typedef struct
   10.85 - { enum PRServReqType   reqType;
   10.86 -   SlaveVP             *requestingSlv;
   10.87 -   char                *nameStr;  //for create probe
   10.88 -   char                *msgStr;   //for exception
   10.89 -   void                *exceptionData;
   10.90 - }
   10.91 -PRServReq;
   10.92 -
   10.93 -
   10.94 -//====================  Core data structures  ===================
   10.95 -
   10.96 -typedef struct
   10.97 - {
   10.98 -   //for future expansion
   10.99 - }
  10.100 -SlotPerfInfo;
  10.101 -
  10.102 -struct _AnimSlot
  10.103 - {
  10.104 -   int           workIsDone;
  10.105 -   int           needsWorkAssigned;
  10.106 -   SlaveVP      *slaveAssignedToSlot;
  10.107 -   
  10.108 -   int           slotIdx;  //needed by Holistic Model's data gathering
  10.109 -   int           coreSlotIsOn;
  10.110 -   SlotPerfInfo *perfInfo; //used by assigner to pick best slave for core
  10.111 - };
  10.112 -//AnimSlot
  10.113 -
  10.114 -enum VPtype 
  10.115 - { SlotTaskSlv = 1,//Slave tied to an anim slot, only animates tasks
  10.116 -   FreeTaskSlv,   //When a suspended task ends, the slave becomes this
  10.117 -   GenericSlv,     //the VP is explicitly seen in the app code, or task suspends
  10.118 -   Master,
  10.119 -   Shutdown,
  10.120 -   Idle
  10.121 - };
  10.122 - 
  10.123 -/*This structure embodies the state of a slaveVP.  It is reused for masterVP
  10.124 - * and shutdownVPs.
  10.125 - */
  10.126 -struct _SlaveVP
  10.127 - {    //The offsets of these fields are hard-coded into assembly
  10.128 -   void       *stackPtr;         //save the core's stack ptr when suspend
  10.129 -   void       *framePtr;         //save core's frame ptr when suspend
  10.130 -   void       *resumeInstrPtr;   //save core's program-counter when suspend
  10.131 -   void       *coreCtlrFramePtr; //restore before jmp back to core controller
  10.132 -   void       *coreCtlrStackPtr; //restore before jmp back to core controller
  10.133 -   
  10.134 -      //============ below this, no fields are used in asm =============
  10.135 -   
  10.136 -   void       *startOfStack;  //used to free, and to point slave to Fn
  10.137 -   PRProcess  *processSlaveIsIn;
  10.138 -   PRMetaTask *metaTask;
  10.139 -   enum VPtype typeOfVP;      //Slave vs Master vs Shutdown..
  10.140 -   int         slaveID;       //each slave given a globally unique ID
  10.141 -   int         coreAnimatedBy; 
  10.142 -   int         numTimesAssignedToASlot;   //Each assign is for one work-unit, so is an ID
  10.143 -      //note, a scheduling decision is uniquely identified by the triple:
  10.144 -      // <slaveID, coreAnimatedBy, numTimesAssignedToASlot> -- used in record & replay
  10.145 -   
  10.146 -      //for comm -- between master and coreCtlr & btwn wrapper lib and plugin
  10.147 -   AnimSlot   *animSlotAssignedTo;
  10.148 -   PRReqst    *request;      //wrapper lib puts in requests, plugin takes out
  10.149 -   void       *dataRetFromReq;//Return vals from plugin to Wrapper Lib
  10.150 -
  10.151 -      //For language specific data that needs to be in the slave
  10.152 -   void       *semanticData;  //Lang saves lang-specific things in slave here
  10.153 -
  10.154 -      //Task related stuff
  10.155 -//   bool        needsTaskAssigned;
  10.156 -   
  10.157 -        //=========== MEASUREMENT STUFF ==========
  10.158 -         MEAS__Insert_Meas_Fields_into_Slave;
  10.159 -         float64     createPtInSecs;  //time VP created, in seconds
  10.160 -        //========================================
  10.161 - };
  10.162 -//SlaveVP
  10.163 -
  10.164 - 
  10.165 -/* The one and only global variable, holds many odds and ends
  10.166 - */
  10.167 -typedef struct
  10.168 - {    //The offsets of these fields are hard-coded into assembly
  10.169 -   void            *coreCtlrReturnPt;    //offset to this field used in asm
  10.170 -   int8             falseSharePad1[256 - sizeof(void*)];
  10.171 -   int32            masterLock;          //offset to this field used in asm
  10.172 -   int8             falseSharePad2[256 - sizeof(int32)];
  10.173 -      //============ below this, no fields are used in asm =============
  10.174 -
  10.175 -      //Basic PR infrastructure
  10.176 -   SlaveVP        **masterVPs;
  10.177 -   AnimSlot      ***allAnimSlots;
  10.178 - 
  10.179 -   PRProcess      **processes;
  10.180 -   
  10.181 -//move to processEnv      //Slave creation -- global count of slaves existing, across langs and processes
  10.182 -   int32            numSlavesCreated;  //used to give unique ID to processor
  10.183 -   int32            numTasksCreated;   //to give unique ID to a task
  10.184 -
  10.185 -      //Initialization related
  10.186 -   int32            setupComplete;      //use while starting up coreCtlr
  10.187 -
  10.188 -      //Memory management related
  10.189 -   MallocArrays    *freeLists;
  10.190 -   int32            amtOfOutstandingMem;//total currently allocated
  10.191 -
  10.192 -      //Random number seeds -- random nums used in various places  
  10.193 -   uint32_t seed1;
  10.194 -   uint32_t seed2;
  10.195 -
  10.196 -   These_Prob_belong_in_PRPRocess;
  10.197 -//   SlaveVP         *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
  10.198 -//   int32            numLiveFreeTaskSlvs;
  10.199 -//   int32            numLiveThreadSlvs;
  10.200 -//   bool32          *coreIsDone;
  10.201 -//   int32            numCoresDone;
  10.202 -   
  10.203 -//   SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
  10.204 -//   int shutdownInitiated;
  10.205 -   
  10.206 -      //=========== MEASUREMENT STUFF =============
  10.207 -       IntervalProbe   **intervalProbes;
  10.208 -       PrivDynArrayInfo *dynIntervalProbesInfo;
  10.209 -       HashTable        *probeNameHashTbl;
  10.210 -       int32             masterCreateProbeID;
  10.211 -       float64           createPtInSecs; //real-clock time PR initialized
  10.212 -       Histogram       **measHists;
  10.213 -       PrivDynArrayInfo *measHistsInfo;
  10.214 -       MEAS__Insert_Susp_Meas_Fields_into_MasterEnv;
  10.215 -       MEAS__Insert_Master_Meas_Fields_into_MasterEnv;
  10.216 -       MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv;
  10.217 -       MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv;
  10.218 -       MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv;
  10.219 -       MEAS__Insert_System_Meas_Fields_into_MasterEnv;
  10.220 -       MEAS__Insert_Counter_Meas_Fields_into_MasterEnv;
  10.221 -      //==========================================
  10.222 - }
  10.223 -MasterEnv;
  10.224 -
  10.225 -//=====================
  10.226 -typedef struct
  10.227 - { int32     langMagicNumber; //indexes into hash array of semEnvs in PRProcess
  10.228 -   PRSemEnv *chainedSemEnv;   //chains to semEnvs with same hash
  10.229 -   void     *langSemEnv;
  10.230 -   
  10.231 -   SlaveAssigner   slaveAssigner;
  10.232 -   RequestHandler  requestHdlr;
  10.233 -   
  10.234 -   RequestHandler  createTaskHdlr;
  10.235 -   RequestHandler  endTaskHdlr;
  10.236 -   RequestHandler  createSlaveHdlr;
  10.237 -   RequestHandler  dissipateSlaveHdlr;
  10.238 -   RequestHandler  semDataCreator;
  10.239 -   RequestHandler  semDataInitializer;
  10.240 -  
  10.241 -   
  10.242 -      //Track slaves created, separately for each langlet? (in each process)
  10.243 -//   int32            numSlavesCreated;  //gives ordering to processor creation
  10.244 -//   int32            numSlavesAlive;    //used to detect fail-safe shutdown
  10.245 -   
  10.246 -      //when multi-lang, master polls sem env's to find one with work in it..
  10.247 -      // in single-lang case, flag ignored, master always asks lang for work
  10.248 -   int32   hasWork;
  10.249 - }
  10.250 -PRSemEnv;
  10.251 -
  10.252 -//The semantic env of every langlet must start with these two fields, so that
  10.253 -// PR can cast the void * to this struct, in order to access these two fields
  10.254 -typedef struct
  10.255 - { int32     langMagicNumber;
  10.256 -   PRSemEnv *protoSemEnv;
  10.257 - }
  10.258 -PRLangSemEnv;
  10.259 -
  10.260 -//can cast any langlet's sem env to one of these, so PR can access values
  10.261 -typedef struct
  10.262 - { int32     langMagicNumber;
  10.263 -   PRSemEnv *protoSemEnv;
  10.264 - }
  10.265 -PRServSemEnv;
  10.266 -
  10.267 -enum PRTaskType
  10.268 - { GenericSlave = 1,
  10.269 -   SlotTask,
  10.270 -   FreeTask
  10.271 - };
  10.272 -
  10.273 -struct _PRMetaTask
  10.274 - { 
  10.275 -   PRTaskType      taskType;
  10.276 -//   RequestHandler  reqHandler;      //Lang-specific hdlr for create, end, etc
  10.277 -   int32          *taskID;          //is standard PR ID
  10.278 -   SlaveVP        *slaveAssignedTo; //no valid until task animated
  10.279 -   TopLevelFn      topLevelFn;      //This is the Fn executes as the task
  10.280 -   void           *initData;        //The data taken by the function
  10.281 -   void           *langMetaTask;
  10.282 -
  10.283 -   //NOTE: info needed for "wait" functionality is inside lang's metaTask
  10.284 - };
  10.285 -//PRMetaTask
  10.286 -
  10.287 -/*The language's meta task is cast to this struct, inside PR, then the 
  10.288 - * back pointer to protoMetaTask is set.  Keeps existence of PRMetaTask hidden
  10.289 - * from plugin -- so can change later.
  10.290 - */
  10.291 -typedef struct
  10.292 - { int32       langMagicNumber;
  10.293 -   PRMetaTask *protoMetaTask;
  10.294 - }
  10.295 -PRLangMetaTask;
  10.296 - 
  10.297 -typedef struct
  10.298 - {
  10.299 -   void (*freeFn)(void *);
  10.300 - }
  10.301 -PRSemDataTemplate;
  10.302 - 
  10.303 -typedef struct
  10.304 - {
  10.305 -   void (*recycler)(void *);
  10.306 -   void *langSemData;
  10.307 - }
  10.308 -PRSemData;
  10.309 -
  10.310 -typedef struct
  10.311 - { PRSemDataTemplate **semDatas;
  10.312 -   PRSemDataTemplate **semDatasIter;
  10.313 -   int32               numSemDatas;
  10.314 - }
  10.315 -PRSemDataHolder;
  10.316 -//=====================  Top Process level Data Strucs  ======================
  10.317 -
  10.318 -/*This structure holds all the information PR needs to manage a program.  PR
  10.319 - * stores information about what percent of CPU time the program is getting, 
  10.320 - * 
  10.321 - */
  10.322 -typedef struct
  10.323 - { 
  10.324 -   PRSemEnv semEnvs[NUM_SEM_ENVS_IN_PROCESS];    //used as a hash table
  10.325 -   PRSemEnv semEnvList[NUM_SEM_ENVS_IN_PROCESS]; //lines up the semEnvs, so can iterate through
  10.326 -   int32    numSemEnvs;     //must be less than num sem envs.. used to iterate through
  10.327 -    
  10.328 -   int32           numLiveGenericSlvs;
  10.329 -   int32           numLiveFreeTaskSlvs;
  10.330 -   int32           numLiveTasks;
  10.331 -//   bool32          coreIsDone[NUM_CORES][CACHE_LINE_SZ]; //Fixes false sharing
  10.332 -
  10.333 -   PrivQueueStruc *freeTaskSlvRecycleQ;
  10.334 -   SlaveVP         slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
  10.335 -   void           *resultToReturn;
  10.336 -  
  10.337 -   SlaveVP        *seedSlv;   
  10.338 -   
  10.339 -   SlaveAssigner   overrideAssigner;
  10.340 -   
  10.341 -      //These are used to coord with OS thread waiting for process to end
  10.342 -   bool32          executionIsComplete;
  10.343 -   pthread_mutex_t doneLock;
  10.344 -   pthread_cond_t  doneCond;
  10.345 - }
  10.346 -PRProcess;
  10.347 -
  10.348 -
  10.349 -//=========================  Extra Stuff Data Strucs  =======================
  10.350 -typedef struct
  10.351 - {
  10.352 -
  10.353 - }
  10.354 -PRExcp; //exception
  10.355 -
  10.356 -//=======================  OS Thread related  ===============================
  10.357 -
  10.358 -void * coreController( void *paramsIn );  //standard PThreads fn prototype
  10.359 -void * coreCtlr_Seq( void *paramsIn );  //standard PThreads fn prototype
  10.360 -void animationMaster( void *initData, SlaveVP *masterVP );
  10.361 -
  10.362 -
  10.363 -typedef struct
  10.364 - {
  10.365 -   void           *endThdPt;
  10.366 -   unsigned int    coreNum;
  10.367 - }
  10.368 -ThdParams;
  10.369 -
  10.370  //=============================  Global Vars ================================
  10.371  
  10.372 -volatile MasterEnv      *_PRTopEnv __align_to_cacheline__;
  10.373 +volatile TopEnv      *_PRTopEnv __align_to_cacheline__;
  10.374  
  10.375     //these are global, but only used for startup and shutdown
  10.376  pthread_t       coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state
  10.377 @@ -403,7 +56,7 @@
  10.378   * WL   Wrapper Library -- wrapper lib code should only use these
  10.379   * PI   Plugin          -- plugin code should only use these
  10.380   * SS   Startup and Shutdown -- designates these relate to startup & shutdown
  10.381 - * int  internal to PR -- should not be used in wrapper lib or plugin
  10.382 + * int32internal to PR -- should not be used in wrapper lib or plugin
  10.383   * PROS means "OS functions for applications to use"
  10.384   * 
  10.385   * PR_int__ functions touch internal PR data structs and are only safe
  10.386 @@ -413,184 +66,32 @@
  10.387   * 
  10.388   * PR_WL__ functions are all safe for use outside the master lock.
  10.389   * 
  10.390 - * PROS are only safe for applications to use -- they're like a second
  10.391 + * PR_OS are only safe for applications to use -- they're like a second
  10.392   * language mixed in -- but they can't be used inside plugin code, and
  10.393   * aren't meant for use in wrapper libraries, because they are themselves
  10.394   * wrapper-library calls!
  10.395   */
  10.396 -//========== Startup and shutdown ==========
  10.397 -void
  10.398 -PR__start();
  10.399  
  10.400 -SlaveVP* 
  10.401 -PR_SS__create_shutdown_slave();
  10.402 +//============== include internally used fn prototypes ================
  10.403  
  10.404 -void
  10.405 -PR_SS__shutdown();
  10.406 +//include fn prototypes used internally in the proto-runtime implementation
  10.407 +#include "PR__int.h"
  10.408  
  10.409 -void
  10.410 -PR_SS__cleanup_at_end_of_shutdown();
  10.411 +//include fn prototypes used by plugin
  10.412 +#include "PR__PI.h"
  10.413  
  10.414 -void
  10.415 -PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, SlaveVP  *seedVP, int32 VSs_MAGIC_NUMBER );
  10.416 +//include fn prototype used by wrapper library
  10.417 +#include "PR__WL.h"
  10.418  
  10.419 +//=================================
  10.420 +#define implement_me printf("Unimpl Fn: \n%s \n%s : %s\n", __FILE__, __FUNCTION__, __LINE__)
  10.421 +//#define fix_me printf("Fix me at: \n%s \n%s : %s\n", __FILE__, __FUNCTION__, __LINE__)
  10.422  
  10.423 -//==============    ===============
  10.424  
  10.425 -inline SlaveVP *
  10.426 -PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam );
  10.427 -#define PR_PI__create_slaveVP PR_int__create_slaveVP
  10.428 -#define PR_WL__create_slaveVP PR_int__create_slaveVP
  10.429 -
  10.430 -inline 
  10.431 -SlaveVP *
  10.432 -PR_int__create_slot_slave();
  10.433 -
  10.434 -inline 
  10.435 -SlaveVP *
  10.436 -PR_int__create_slaveVP_helper( SlaveVP *newSlv,       TopLevelFnPtr  fnPtr,
  10.437 -                                void      *dataParam, void           *stackLocs );
  10.438 -
  10.439 -inline
  10.440 -PRMetaTask *
  10.441 -PR_int__create_generic_slave_meta_task( void *initData );
  10.442 -
  10.443 -inline
  10.444 -void
  10.445 -PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr,
  10.446 -                              void    *dataParam);
  10.447 -
  10.448 -inline
  10.449 -void
  10.450 -PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr,
  10.451 -                              void    *param);
  10.452 -
  10.453 -inline
  10.454 -void
  10.455 -PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr,
  10.456 -                              void    *param1, void *param2);
  10.457 -
  10.458 -inline
  10.459 -void
  10.460 -PR_int__dissipate_slaveVP( SlaveVP *slaveToDissipate );
  10.461 -#define PR_PI__dissipate_slaveVP PR_int__dissipate_slaveVP
  10.462 -//WL: dissipate a SlaveVP by sending a request
  10.463 -
  10.464 -inline
  10.465 -void
  10.466 -PR_int__dissipate_slaveVP_multilang( SlaveVP *slaveToDissipate );
  10.467 -
  10.468 -inline
  10.469 -void
  10.470 -PR_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
  10.471 -#define PR_PI__throw_exception  PR_int__throw_exception
  10.472 -void
  10.473 -PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv,  PRExcp *excpData );
  10.474 -#define PR_App__throw_exception PR_WL__throw_exception
  10.475 -
  10.476 -inline
  10.477 -void *
  10.478 -PR_int__give_sem_env_for_slave( SlaveVP *slave, int32 magicNumber );
  10.479 -#define PR_PI__give_sem_env_for  PR_int__give_sem_env_for_slave
  10.480 -#define PR_SS__give_sem_env_for_slave  PR_int__give_sem_env_for_slave
  10.481 -//No WL version -- not safe!  if use env in WL, be sure data rd & wr is stable
  10.482 -inline
  10.483 -PRSemEnv *
  10.484 -PR_int__give_proto_sem_env_for_slave( SlaveVP *slave, int32 magicNumber );
  10.485 -#define PR_PI__give_proto_sem_env_for  PR_int__give_proto_sem_env_for_slave
  10.486 -#define PR_SS__give_proto_sem_env_for_slave  PR_int__give_proto_sem_env_for_slave
  10.487 -//No WL version -- not safe!  if use env in WL, be sure data rd & wr is stable
  10.488 -inline
  10.489 -void *
  10.490 -PR_int__give_sem_env_from_process( PRProcess *process, int32 magicNumer );
  10.491 -#define PR_PI__give_sem_env_from_process  PR_int__give_sem_env_from_process
  10.492 -#define PR_SS__give_sem_env_from_process  PR_int__give_sem_env_from_process
  10.493 -//#define PR_WL__give_sem_env_from_process  PR_int__give_sem_env_from_process
  10.494 -//No WL version -- not safe!  if use env in WL, be sure data rd & wr is stable
  10.495 -
  10.496 -inline
  10.497 -void *
  10.498 -PR_int__give_sem_data( SlaveVP *slave, int32 magicNumer );
  10.499 -#define PR_PI__give_sem_data  PR_int__give_sem_data
  10.500 -#define PR_SS__give_sem_data  PR_int__give_sem_data
  10.501 -#define PR_WL__give_sem_data  PR_int__give_sem_data
  10.502 -
  10.503 -
  10.504 -#define PR_int__give_lang_meta_task( slave, magicNumber )\
  10.505 -        slave->metaTask->langMetaTask;
  10.506 -#define PR_PI__give_lang_meta_task  PR_int__give_lang_meta_task
  10.507 -#define PR_SS__give_lang_meta_task  PR_int__give_lang_meta_task
  10.508 -#define PR_WL__give_lang_meta_task  PR_int__give_lang_meta_task
  10.509 -
  10.510 -inline
  10.511 -SlaveVP *
  10.512 -PR_PI__give_slave_assigned_to( PRLangMetaTask *langMetaTask );
  10.513 -        
  10.514 -void 
  10.515 -idle_fn(void* data, SlaveVP *animatingSlv);
  10.516 -
  10.517 -inline void
  10.518 -PR_int__get_master_lock();
  10.519 -
  10.520 -#define PR_int__release_master_lock() _PRTopEnv->masterLock = UNLOCKED
  10.521 -
  10.522 -inline uint32_t
  10.523 -PR_int__randomNumber();
  10.524 -
  10.525 -//==============  Request Related  ===============
  10.526 -
  10.527 -void
  10.528 -PR_WL__suspend_slaveVP_and_send_req( SlaveVP *callingSlv );
  10.529 -
  10.530 -inline void
  10.531 -PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData, SlaveVP *callingSlv );
  10.532 -
  10.533 -inline void
  10.534 -PR_WL__send_sem_request( void *semReq, SlaveVP *callingSlv, int32 magicNum );
  10.535 -
  10.536 -void
  10.537 -PR_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv );
  10.538 -
  10.539 -void inline
  10.540 -PR_WL__send_dissipate_req( SlaveVP *prToDissipate );
  10.541 -
  10.542 -inline void
  10.543 -PR_WL__send_service_request( void *semReqData, SlaveVP *callingSlv );
  10.544 -
  10.545 -PRReqst *
  10.546 -PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
  10.547 -//#define PR_PI__take_next_request_out_of( slave ) slave->requests
  10.548 -
  10.549 -//inline void *
  10.550 -//PR_PI__take_sem_reqst_from( PRReqst *req );
  10.551 -#define PR_PI__take_sem_reqst_from( req ) req->semReqData
  10.552 -
  10.553 -void inline
  10.554 -PR_int__handle_PRServiceReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv,
  10.555 -                       ResumeSlvFnPtr resumeSlvFnPtr );
  10.556 -
  10.557 -//======================== MEASUREMENT ======================
  10.558 -uint64
  10.559 -PR_WL__give_num_plugin_cycles();
  10.560 -uint32
  10.561 -PR_WL__give_num_plugin_animations();
  10.562 -
  10.563 -
  10.564 -//========================= Utilities =======================
  10.565 -inline char *
  10.566 -PR_int__strDup( char *str );
  10.567 -
  10.568 -
  10.569 -//=========================  PR request handlers  ========================
  10.570 -void inline
  10.571 -handleMakeProbe( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
  10.572 -
  10.573 -void inline
  10.574 -handleThrowException( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
  10.575 -//=======================================================================
  10.576 -
  10.577 -//========================= Probes =======================
  10.578 -#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
  10.579 +//========================= Services =======================
  10.580 +//#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
  10.581 +//#include  "Services_Offered_by_PR/Services_Language/PRServ.h"
  10.582 +//#include  "Services_Offered_by_PR/Services_Language/libPRServ.h"
  10.583  
  10.584  //================================================
  10.585  #endif	/* _PR_H */
    11.1 --- a/PR__PI.c	Sun Nov 04 18:39:28 2012 -0800
    11.2 +++ b/PR__PI.c	Mon Jan 14 15:31:23 2013 -0800
    11.3 @@ -1,5 +1,5 @@
    11.4  /*
    11.5 - * Copyright 2010  OpenSourceStewardshipFoundation
    11.6 + * Copyright 2010  OpenSourceResearchInstitute
    11.7   *
    11.8   * Licensed under BSD
    11.9   */
   11.10 @@ -44,9 +44,9 @@
   11.11   *Turn function into macro that just accesses the request field
   11.12   *
   11.13  inline void *
   11.14 -PR_PI__take_sem_reqst_from( PRReqst *req )
   11.15 +PR_PI__take_lang_reqst_from( PRReqst *req )
   11.16   {
   11.17 -   return req->semReqData;
   11.18 +   return req->langReqData;
   11.19   }
   11.20  */
   11.21  
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/PR__PI.h	Mon Jan 14 15:31:23 2013 -0800
    12.3 @@ -0,0 +1,54 @@
    12.4 +/*
    12.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
    12.6 + *  Licensed under GNU General Public License version 2
    12.7 + *
    12.8 + * Author: seanhalle@yahoo.com
    12.9 + * 
   12.10 + */
   12.11 +
   12.12 +#ifndef _PR__PI_H
   12.13 +#define	_PR__PI_H
   12.14 +#define _GNU_SOURCE
   12.15 +
   12.16 +
   12.17 +#include "PR_primitive_data_types.h"
   12.18 +
   12.19 +//=========================  Function Prototypes  ===========================
   12.20 +/* MEANING OF   WL  PI  SS  int PROS
   12.21 + * These indicate which places the function is safe to use.  They stand for:
   12.22 + * 
   12.23 + * WL   Wrapper Library -- wrapper lib code should only use these
   12.24 + * PI   Plugin          -- plugin code should only use these
   12.25 + * SS   Startup and Shutdown -- designates these relate to startup & shutdown
   12.26 + * int32internal to PR -- should not be used in wrapper lib or plugin
   12.27 + * PROS means "OS functions for applications to use"
   12.28 + * 
   12.29 + * PR_int__ functions touch internal PR data structs and are only safe
   12.30 + *  to be used inside the master lock.  However, occasionally, they appear
   12.31 + * in wrapper-lib or plugin code.  In those cases, very careful analysis
   12.32 + * has been done to be sure no concurrency issues could arise.
   12.33 + * 
   12.34 + * PR_WL__ functions are all safe for use outside the master lock.
   12.35 + * 
   12.36 + * PROS are only safe for applications to use -- they're like a second
   12.37 + * language mixed in -- but they can't be used inside plugin code, and
   12.38 + * aren't meant for use in wrapper libraries, because they are themselves
   12.39 + * wrapper-library calls!
   12.40 + */
   12.41 +
   12.42 +inline
   12.43 +SlaveVP *
   12.44 +PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask );
   12.45 +
   12.46 +
   12.47 +PRReqst *
   12.48 +PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
   12.49 +//#define PR_PI__take_next_request_out_of( slave ) slave->requests
   12.50 +
   12.51 +//inline void *
   12.52 +//PR_PI__take_lang_reqst_from( PRReqst *req );
   12.53 +#define PR_PI__take_lang_reqst_from( req ) req->langReqData
   12.54 +
   12.55 +//================================================
   12.56 +#endif	/* _PR__PI_H */
   12.57 +
    13.1 --- a/PR__SS.c	Sun Nov 04 18:39:28 2012 -0800
    13.2 +++ b/PR__SS.c	Mon Jan 14 15:31:23 2013 -0800
    13.3 @@ -1,5 +1,5 @@
    13.4  /*
    13.5 - * Copyright 2010  OpenSourceStewardshipFoundation
    13.6 + * Copyright 2010  OpenSourceResearchInstitute
    13.7   *
    13.8   * Licensed under BSD
    13.9   */
   13.10 @@ -32,7 +32,7 @@
   13.11  create_anim_slots( int32 coreSlotsAreOn );
   13.12  
   13.13  void
   13.14 -create_masterEnv();
   13.15 +create_topEnv();
   13.16  
   13.17  void
   13.18  create_the_coreCtlr_OS_threads();
   13.19 @@ -70,251 +70,307 @@
   13.20   * the requestHandler and slaveAssigner plug-in functions
   13.21   */
   13.22  
   13.23 -/*This allocates PR data structures, populates the master PRProc,
   13.24 - * and master environment, and returns the master environment to the semantic
   13.25 - * layer.
   13.26 +//Check the comments above -- likely out of sync
   13.27 +
   13.28 +/*This allocates PR data structures, populates the top environments.  After
   13.29 + * this call, processes can be started.
   13.30   */
   13.31  void
   13.32  PR__start()
   13.33   {
   13.34 -   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   13.35 -      create_masterEnv();
   13.36 -      printf( "\n\n Running in SEQUENTIAL mode \n\n" );
   13.37 -   #else
   13.38 -      create_masterEnv();
   13.39 -      DEBUG__printf1(dbgInfra,"Offset of lock in masterEnv: %d ", (int32)offsetof(MasterEnv,masterLock) );
   13.40 -      create_the_coreCtlr_OS_threads();
   13.41 -   #endif
   13.42 +   create_topEnv();
   13.43 +   
   13.44 +  #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   13.45 +   printf( "\n\n Running in SEQUENTIAL mode \n\n" );
   13.46 +  #else
   13.47 +   DEBUG__printf1(dbgInfra,"Offset of lock in masterEnv: %d ", (int32)offsetof(TopEnv,masterLock) );
   13.48 +   create_the_coreCtlr_OS_threads();
   13.49 +
   13.50 +  #endif
   13.51   }
   13.52  
   13.53  
   13.54 -/*A process is represented by a structure that holds all the process-specific
   13.55 +/*This creates a new process and sets the mode to single lang for it
   13.56 + *It creates a seed slave, from the top-level fn and initial data passed into
   13.57 + * this fn.
   13.58 + *The only langlet in the created process is the default PRServ.  The rest
   13.59 + * must b e started up via calls  made by the seed VP's top-level fn (passed in
   13.60 + * to this call).
   13.61 + * 
   13.62 + *A process is represented by a structure that holds all the process-specific
   13.63   * information:
   13.64 - *-] The hash-array containing the semantic environs of any langlets started
   13.65 + *-] The hash-array containing the language environs of any langlets started
   13.66   *   inside the process.
   13.67 - *-] Flags used to detect the end of activity in the process
   13.68   *-] Counter of num live slaves and num live tasks in the process
   13.69   * 
   13.70 - *PR automatically generates the seedVP when it creates the process, and
   13.71 - * inserts the processID of the newly created process into it. 
   13.72   */
   13.73  PRProcess *
   13.74 -PR__create_process( TopLevelFnPtr seed_Fn, void *seedData )
   13.75 +PR__create_process__SL( TopLevelFnPtr seed_Fn, void *seedData )
   13.76   { SlaveVP    *seedSlv;
   13.77     PRProcess  *process;
   13.78 -   PRMetaTask *metaTask;
   13.79 -   PRSemEnv   *semEnvs;
   13.80 -   int32       idx;
   13.81 +   PRLangEnv **langEnvs, **langEnvsList;
   13.82 +   
   13.83 +   _PRTopEnv->mode         = SingleLang;
   13.84 +   
   13.85     
   13.86     process = malloc( sizeof(PRProcess) );
   13.87 -   process->numSemEnvs = 0;
   13.88 -   semEnvs = process->semEnvs;
   13.89 -   for( idx = 0; idx < NUM_SEM_ENVS_IN_PROCESS; idx++ )
   13.90 -    { semEnvs[idx].langSemEnv = NULL;
   13.91 -      semEnvs[idx].chainedSemEnv = NULL;
   13.92 +   _PRTopEnv->processes[_PRTopEnv->numProcesses] = process;
   13.93 +   _PRTopEnv->numProcesses += 1;
   13.94 +   
   13.95 +   langEnvs     = malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRCollElem *) );
   13.96 +   ((int32 *)langEnvs)[0]  = NUM_IN_COLLECTION;
   13.97 +   langEnvsList = malloc( NUM_IN_COLLECTION * sizeof(PRCollElem *) );
   13.98 +   process->langEnvs     = langEnvs;
   13.99 +   process->langEnvsList = langEnvsList;
  13.100 +   process->numLangEnvs  = 0;
  13.101 +   
  13.102 +      //A Process starts with one slave, the seed slave
  13.103 +   seedSlv = PR_int__create_slaveVP__ML( seed_Fn, seedData, process );
  13.104 +   seedSlv->typeOfVP           = SeedSlv;
  13.105 +   seedSlv->processSlaveIsIn   = process;
  13.106 +   process->numLiveGenericSlvs = 1; //count the  seed
  13.107 +   process->numLiveTasks       = 0;
  13.108 +   
  13.109 +   PRServLangEnv *
  13.110 +   servicesLangEnv = 
  13.111 +    PR_int__create_lang_env_in_process( sizeof(PRServLangEnv), process, PRServ_MAGIC_NUMBER );
  13.112 +
  13.113 +   servicesLangEnv->slavesReadyToResumeQ = makePrivQ();
  13.114 +   servicesLangEnv->taskReadyQ           = makePrivQ();
  13.115 +   
  13.116 +      //resume seedVP into PR's built-in services language's language env
  13.117 +   process->numEnvsWithWork = 0; //Seed is in PRServ lang env.. resume incrs this
  13.118 +   PRServ__resume_slaveVP( seedSlv, servicesLangEnv );
  13.119 +   
  13.120 +
  13.121 +      //The first process created has to unblock the core controllers.
  13.122 +   if( _PRTopEnv->numProcesses == 1 )
  13.123 +    {
  13.124 +    #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
  13.125 +      //Only difference between version with an OS thread pinned to each core and
  13.126 +      // the sequential version of PR is PR__init_Seq, this, and coreCtlr_Seq.
  13.127 +
  13.128 +            // call the one and only core ctlr (sequential version), in the main thread.
  13.129 +         coreCtlr_Seq( NULL );
  13.130 +         flushRegisters();  //Not sure why here, but leaving to be safe
  13.131 +    #else
  13.132 +         //tell the core controller threads that a process is ready to be animated
  13.133 +         //get lock, to lock out any threads still starting up -- they'll see
  13.134 +         // that firstProcessReady is true before entering while loop, and so never
  13.135 +         // wait on the condition
  13.136 +      pthread_mutex_lock(     &suspendLock );
  13.137 +      _PRTopEnv->firstProcessReady = 1;
  13.138 +      pthread_mutex_unlock(   &suspendLock );
  13.139 +      pthread_cond_broadcast( &suspendCond );
  13.140 +    #endif
  13.141      }
  13.142 -         
  13.143 -      //A Process starts with one slave, the seed slave
  13.144 -   seedSlv = PR_int__create_slaveVP( seed_Fn, seedData );
  13.145 -   
  13.146 -   seedSlv->processSlaveIsIn = process;
  13.147 -   
  13.148 -      //seed slave is a generic slave, so make a generic slave meta task for it
  13.149 -   metaTask          = PR_int__create_generic_slave_meta_task( seedData );
  13.150 -   seedSlv->metaTask = metaTask;
  13.151 -   
  13.152 -   process->numLiveGenericSlvs = 1; //count the  seed
  13.153 -   process->numLiveTasks = 0;
  13.154 -   
  13.155 -   PRServSemEnv *
  13.156 -   servicesSemEnv = PR_SS__malloc( sizeof(PRServSemEnv) );
  13.157 -   PR_SS__register_langlets_semEnv( servicesSemEnv, seedSlv, PRSERV_MAGIC_NUMBER );
  13.158 -
  13.159 -      //resume seedVP into PR's built-in services language's semantic env
  13.160 -   PRServ__resume_slaveVP( seedSlv, servicesSemEnv );
  13.161 +   pthread_mutex_init( process->doneLock, NULL );
  13.162 +   pthread_cond_init( process->doneCond, NULL );
  13.163 +   process->executionIsComplete = FALSE;
  13.164     
  13.165     return process;
  13.166   }
  13.167  
  13.168 +/*This is only called in multi-lang mode.
  13.169 + *It creates a seed slave, from the top-level fn and initial data passed into
  13.170 + * this fn.
  13.171 + *The only langlet in the created process is the default PRServ.  The rest
  13.172 + * must b e started up via calls  made by the seed VP's top-level fn (passed in
  13.173 + * to this call).
  13.174 + * 
  13.175 + *A process is represented by a structure that holds all the process-specific
  13.176 + * information:
  13.177 + *-] The hash-array containing the language environs of any langlets started
  13.178 + *   inside the process.
  13.179 + *-] Counter of num live slaves and num live tasks in the process
  13.180 + * 
  13.181 + */
  13.182 +PRProcess *
  13.183 +PR__create_process__ML( TopLevelFnPtr seed_Fn, void *seedData )
  13.184 + { SlaveVP    *seedSlv;
  13.185 +   PRProcess  *process;
  13.186 +   PRLangEnv **langEnvs, **langEnvsList;
  13.187 +   
  13.188 +   _PRTopEnv->mode         = MultiLang;
  13.189 +   
  13.190 +   
  13.191 +   process = malloc( sizeof(PRProcess) );
  13.192 +   _PRTopEnv->processes[_PRTopEnv->numProcesses] = process;
  13.193 +   _PRTopEnv->numProcesses += 1;
  13.194 +   
  13.195 +   langEnvs     = malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRCollElem *) );
  13.196 +   ((int32 *)langEnvs)[0]  = NUM_IN_COLLECTION;
  13.197 +   langEnvsList = malloc( NUM_IN_COLLECTION * sizeof(PRCollElem *) );
  13.198 +   process->langEnvs     = langEnvs;
  13.199 +   process->langEnvsList = langEnvsList;
  13.200 +   process->numLangEnvs  = 0;
  13.201 +   
  13.202 +      //A Process starts with one slave, the seed slave
  13.203 +   seedSlv = PR_int__create_slaveVP__ML( seed_Fn, seedData, process );
  13.204 +   seedSlv->typeOfVP           = SeedSlv;
  13.205 +   seedSlv->processSlaveIsIn   = process;
  13.206 +   process->numLiveGenericSlvs = 1; //count the  seed 
  13.207 +   process->numLiveTasks       = 0;
  13.208 +   
  13.209 +   PRServLangEnv *
  13.210 +   servicesLangEnv = 
  13.211 +    PR_int__create_lang_env_in_process( sizeof(PRServLangEnv), process, PRServ_MAGIC_NUMBER );
  13.212  
  13.213 -/*This gets the process struct out of the seedVP, then gets the semEnv-holding
  13.214 - * struct out of that, then inserts the semantic env into that struct, using
  13.215 - * the magic number as the key to the sem env placement.  The master will 
  13.216 - * use the magic number from a request to retrieve the semantic env appropriate
  13.217 - * for the construct that made the request.
  13.218 +   servicesLangEnv->slavesReadyToResumeQ = makePrivQ();
  13.219 +   servicesLangEnv->taskReadyQ           = makePrivQ();
  13.220 +   
  13.221 +      //resume seedVP into PR's built-in services language's language env
  13.222 +   process->numEnvsWithWork = 0; //Seed is in PRServ lang env.. resume incrs this
  13.223 +   PRServ__resume_slaveVP( seedSlv, servicesLangEnv );
  13.224 +   
  13.225 +
  13.226 +      //The first process created has to unblock the core controllers.
  13.227 +   if( _PRTopEnv->numProcesses == 1 )
  13.228 +    {
  13.229 +    #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
  13.230 +      //Only difference between version with an OS thread pinned to each core and
  13.231 +      // the sequential version of PR is PR__init_Seq, this, and coreCtlr_Seq.
  13.232 +
  13.233 +            // call the one and only core ctlr (sequential version), in the main thread.
  13.234 +         coreCtlr_Seq( NULL );
  13.235 +         flushRegisters();  //Not sure why here, but leaving to be safe
  13.236 +    #else
  13.237 +         //tell the core controller threads that a process is ready to be animated
  13.238 +         //get lock, to lock out any threads still starting up -- they'll see
  13.239 +         // that firstProcessReady is true before entering while loop, and so never
  13.240 +         // wait on the condition
  13.241 +      pthread_mutex_lock(     &suspendLock );
  13.242 +      _PRTopEnv->firstProcessReady = 1;
  13.243 +      pthread_mutex_unlock(   &suspendLock );
  13.244 +      pthread_cond_broadcast( &suspendCond );
  13.245 +    #endif
  13.246 +    }
  13.247 +   pthread_mutex_init( process->doneLock, NULL );
  13.248 +   pthread_cond_init( process->doneCond, NULL );
  13.249 +   process->executionIsComplete = FALSE;
  13.250 +   
  13.251 +   return process;
  13.252 + }
  13.253 +
  13.254 +
  13.255 +/*are already in Master when detect, inside end-task or dissipate, so call "PR_SS__shutdown_process"
  13.256   */
  13.257  void
  13.258 -PR_SS__register_langlets_semEnv( void *_semEnv, SlaveVP  *seedVP, int32 magicNum )
  13.259 - { PRSemEnv     *protoSemEnv;
  13.260 -   PRProcess    *process;
  13.261 -   PRServSemEnv *semEnv = (PRServSemEnv *)_semEnv;
  13.262 +PR_SS__shutdown_process__ML( PRProcess *process )
  13.263 + { int32 i, processIdx;
  13.264 +   PRProcess **processes;
  13.265 +   
  13.266 +      //remove process from PR's list of processes..
  13.267 +   processes = _PRTopEnv->processes;
  13.268 +   for( i = 0; i < _PRTopEnv->numProcesses; i++ )
  13.269 +    { if( processes[i] == process )
  13.270 +       { processIdx = i;
  13.271 +         break;
  13.272 +       }
  13.273 +    }
  13.274 +   for( i = processIdx +1; i < _PRTopEnv->numProcesses; i++ )
  13.275 +    { processes[i-1] = process[i];
  13.276 +    }
  13.277 +   _PRTopEnv->numProcesses -= 1;
  13.278 +   
  13.279 +      //remove process from the process-to-slot chooser
  13.280 +   _PRTopEnv->currProcessIdx = 0; //start choosing starting at process 0
  13.281 +      
  13.282 +      //call shutdown on each langlet started in process (which frees any
  13.283 +      // langlet-allocd data in langEnv);
  13.284 +      //Then free the lang env
  13.285 +   PRLangEnv *langEnv;
  13.286 +   for( i = 0; i < process->numLangEnvs; i++ )
  13.287 +    { langEnv = PR_int__give_proto_lang_env(process->langEnvsList[i]);
  13.288 +         //The lang shutdowns should free any slaves or tasks in the langEnv
  13.289 +      (*langEnv->shutdownHdlr)(&(langEnv[1]));
  13.290 +      PR_int__free( langEnv );
  13.291 +    }
  13.292 +   PR_int__free( process->langEnvsList ); //list array
  13.293 +   PR_int__free( &(((int32 *)process->langEnvs)[-1]) ); //the collection array
  13.294 +   
  13.295 +      //any slaves from this process still in slots will finish executing, but
  13.296 +      // have no lang env for the request handlers to use!
  13.297 +      //So, have to mark each slave, so the request handling isn't done
  13.298 +   AnimSlot *slot, **animSlots;
  13.299 +   int32 core;
  13.300 +   for( core = 0; core < NUM_CORES; core++ )
  13.301 +    { animSlots = _PRTopEnv->allAnimSlots[core];
  13.302 +      for( i = 0; i < NUM_ANIM_SLOTS; i++ )
  13.303 +       { slot =  animSlots[i];
  13.304 +         if( slot->slaveAssignedToSlot->processSlaveIsIn == process )
  13.305 +          {    //turn off req handling by disallowing slave from chging slot flag
  13.306 +            slot->slaveAssignedToSlot->animSlotAssignedTo = NULL;
  13.307 +            slot->workIsDone = FALSE; //just in case, make sure req hdling off
  13.308 +            slot->needsWorkAssigned = TRUE; //make new slave be assigned
  13.309 +          }
  13.310 +       }
  13.311 +    }
  13.312 +     
  13.313 +      //cause resume of "PR__wait_for_process_to_end()" call
  13.314 +   pthread_mutex_lock(     process->doneLock );
  13.315 +   process->executionIsComplete = TRUE;
  13.316 +   pthread_mutex_unlock(   process->doneLock );
  13.317 +   pthread_cond_broadcast( process->doneCond );
  13.318 +      //BUG: process struct can be freed and re-allocated  before waiter sees
  13.319 +      // executionIsComplete
  13.320  
  13.321 -   process     = seedVP->processSlaveIsIn;
  13.322 -   
  13.323 -   protoSemEnv = PR_int__create_proto_sem_env_in_process( process, magicNum );
  13.324 -   protoSemEnv->langSemEnv      = semEnv;
  13.325 -   protoSemEnv->langMagicNumber = magicNum;
  13.326 -   protoSemEnv->hasWork         = FALSE;
  13.327 -   
  13.328 -   semEnv->protoSemEnv          = protoSemEnv;
  13.329 +      //if last process, cause resume of "PR__wait_for_all_activity_to_end"
  13.330 +   if( _PRTopEnv->numProcesses == 1 )
  13.331 +    { implement_me(); //have to ensure that PRServ has no activity -- do later
  13.332 +      pthread_mutex_lock(     _PRTopEnv->activityDoneLock );
  13.333 +      _PRTopEnv->allActivityIsDone = TRUE;
  13.334 +      pthread_mutex_unlock(   _PRTopEnv->activityDoneLock );
  13.335 +      pthread_cond_broadcast( _PRTopEnv->activityDoneCond );
  13.336 +    }
  13.337 +
  13.338 +      //lastly, free the PRProcess struct itself
  13.339 +   PR_int__free(process);
  13.340   }
  13.341  
  13.342 -/*These store the pointer to handler into the semantic env -- semantic env
  13.343 - * found by using magic num to look it up in the process that the seedVP
  13.344 - * is inside of.
  13.345 +/*This waits for the OS threads in the PR system to end.  Causing them to end
  13.346 + * has to be done separately (haven't worked out details as of this comment)
  13.347   */
  13.348  void
  13.349 -PR_SS__register_create_task_handler( RequestHandler createTaskHandler, SlaveVP *seedVP, int32 magicNum )
  13.350 - { PRSemEnv *semEnv;
  13.351 - 
  13.352 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.353 -   semEnv->createTaskHdlr = createTaskHandler; 
  13.354 - }
  13.355 -void
  13.356 -PR_SS__register_end_task_handler( RequestHandler endTaskHandler, SlaveVP *seedVP, int32 magicNum )
  13.357 - { PRSemEnv *semEnv;
  13.358 - 
  13.359 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.360 -   semEnv->endTaskHdlr = endTaskHandler; 
  13.361 - }
  13.362 -void
  13.363 -PR_SS__register_create_slave_handler( RequestHandler createSlvHandler, SlaveVP *seedVP, int32 magicNum )
  13.364 - { PRSemEnv *semEnv;
  13.365 - 
  13.366 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.367 -   semEnv->createSlaveHdlr = createSlvHandler; 
  13.368 - }
  13.369 -void
  13.370 -PR_SS__register_dissipate_slave_handler( RequestHandler dissipateHandler, SlaveVP *seedVP, int32 magicNum )
  13.371 - { PRSemEnv *semEnv;
  13.372 - 
  13.373 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.374 -   semEnv->dissipateSlaveHdlr = dissipateHandler; 
  13.375 - }
  13.376 -void
  13.377 -PR_SS__register_request_handler( RequestHandler reqHandler, SlaveVP *seedVP, int32 magicNum )
  13.378 - { PRSemEnv *semEnv;
  13.379 - 
  13.380 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.381 -   semEnv->requestHdlr = reqHandler; 
  13.382 - }
  13.383 -void
  13.384 -PR_SS__register_assigner( SlaveAssigner assigner, SlaveVP *seedVP, int32 magicNum )
  13.385 - { PRSemEnv *semEnv;
  13.386 - 
  13.387 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.388 -   semEnv->slaveAssigner = assigner; 
  13.389 - }
  13.390 -void
  13.391 -PR_SS__register_sem_data_creator( SemDataCreator semDataCreator, 
  13.392 -                                              SlaveVP *seedVP, int32 magicNum )
  13.393 - { PRSemEnv *semEnv;
  13.394 - 
  13.395 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.396 -   semEnv->semDataCreator = semDataCreator; 
  13.397 - }
  13.398 -void
  13.399 -PR_SS__register_sem_data_initializer( SemDataInitializer semDataInitializer, 
  13.400 -                                              SlaveVP *seedVP, int32 magicNum )
  13.401 - { PRSemEnv *semEnv;
  13.402 - 
  13.403 -   semEnv = PR_SS__give_proto_sem_env_for_slave( seedVP, magicNum );
  13.404 -   semEnv->semDataInitializer = semDataInitializer; 
  13.405 +PR_SS__wait_for_PR_to_shutdown()
  13.406 + {
  13.407 +      //wait for all to complete
  13.408 +   int coreIdx;
  13.409 +   for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ )
  13.410 +    {
  13.411 +      pthread_join( coreCtlrThdHandles[coreIdx], NULL );
  13.412 +    }
  13.413   }
  13.414  
  13.415 -
  13.416 -
  13.417 -
  13.418 -/*TODO: finish implementing
  13.419 - *This function returns information about the version of PR, the language
  13.420 - * the program is being run in, its version, and information on the 
  13.421 - * hardware.
  13.422 - */
  13.423 -/*
  13.424 -char *
  13.425 -PRServ___give_environment_string()
  13.426 - {
  13.427 -   //--------------------------
  13.428 -    fprintf(output, "#\n# >> Build information <<\n");
  13.429 -    fprintf(output, "# GCC VERSION: %d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
  13.430 -    fprintf(output, "# Build Date: %s %s\n", __DATE__, __TIME__);
  13.431 -    
  13.432 -    fprintf(output, "#\n# >> Hardware information <<\n");
  13.433 -    fprintf(output, "# Hardware Architecture: ");
  13.434 -   #ifdef __x86_64
  13.435 -    fprintf(output, "x86_64");
  13.436 -   #endif //__x86_64
  13.437 -   #ifdef __i386
  13.438 -    fprintf(output, "x86");
  13.439 -   #endif //__i386
  13.440 -    fprintf(output, "\n");
  13.441 -    fprintf(output, "# Number of Cores: %d\n", NUM_CORES);
  13.442 -   //--------------------------
  13.443 -    
  13.444 -   //PR Plugins
  13.445 -    fprintf(output, "#\n# >> PR Plugins <<\n");
  13.446 -    fprintf(output, "# Language : ");
  13.447 -    fprintf(output, _LANG_NAME_);
  13.448 -    fprintf(output, "\n");
  13.449 -       //Meta info gets set by calls from the language during its init,
  13.450 -       // and info registered by calls from inside the application
  13.451 -    fprintf(output, "# Assigner: %s\n", _PRTopEnv->metaInfo->assignerInfo);
  13.452 -
  13.453 -   //--------------------------
  13.454 -   //Application
  13.455 -    fprintf(output, "#\n# >> Application <<\n");
  13.456 -    fprintf(output, "# Name: %s\n", _PRTopEnv->metaInfo->appInfo);
  13.457 -    fprintf(output, "# Data Set:\n%s\n",_PRTopEnv->metaInfo->inputSet);
  13.458 -    
  13.459 -   //--------------------------
  13.460 +void
  13.461 +PR__wait_for_all_activity_to_end()
  13.462 + { 
  13.463 +   pthread_mutex_lock( _PRTopEnv->activityDoneLock );
  13.464 +   while( !(_PRTopEnv->allActivityIsDone) )
  13.465 +    {
  13.466 +      pthread_cond_wait( _PRTopEnv->activityDoneCond,
  13.467 +                         _PRTopEnv->activityDoneLock );
  13.468 +    }
  13.469 +   pthread_mutex_unlock( _PRTopEnv->activityDoneLock );
  13.470   }
  13.471 - */
  13.472  
  13.473  void
  13.474 -PR_SS__shutdown_process( PRProcess *process )
  13.475 - {
  13.476 -   removes from queue of processes, and calls shutdown on each langlet started in it (which frees any langlet-alloc'd data in semEnv & semEnv itself).. then frees the process struct (which frees the proto-semEnv's in array)..  then writes a done flag (in TopEnv?) and signals the condition var that any OS threads might be waiting on (the wait-for-process-to-end call);
  13.477 +PR__wait_for_process_to_end()
  13.478 + { 
  13.479 +   pthread_mutex_lock( _PRTopEnv->activityDoneLock );
  13.480 +   while( !(_PRTopEnv->allActivityIsDone) )
  13.481 +    {
  13.482 +      pthread_cond_wait( _PRTopEnv->activityDoneCond,
  13.483 +                         _PRTopEnv->activityDoneLock );
  13.484 +    }
  13.485 +   pthread_mutex_unlock( _PRTopEnv->activityDoneLock );
  13.486   }
  13.487  
  13.488 -/*A pointer to the startup-function for the language is given as the last
  13.489 - * argument to the call.  Use this to initialize a program in the language.
  13.490 - * This creates a data structure that encapsulates the bookkeeping info
  13.491 - * PR uses to track and schedule a program run.
  13.492 - */
  13.493 -/*PRProcess *
  13.494 -PR__spawn_program_on_data_in_Lang( TopLevelFnPtr seed_fn, void *data )
  13.495 - { PRProcess *newProcess;
  13.496 -   newProcess = malloc( sizeof(PRProcess) );
  13.497 -   
  13.498 -   newProcess->doneLock = PTHREAD_MUTEX_INITIALIZER;
  13.499 -   newProcess->doneCond = PTHREAD_COND_INITIALIZER;
  13.500 -   newProcess->executionIsComplete = FALSE;
  13.501 -   newProcess->numSlavesLive = 0;
  13.502 -   
  13.503 -   newProcess->dataForSeed = data;
  13.504 -   newProcess->seedFnPtr   = prog_seed_fn;
  13.505 -   
  13.506 -      //The language's spawn-process function fills in the plugin function-ptrs in
  13.507 -      // the PRProcess struct, gives the struct to PR, which then makes and
  13.508 -      // queues the seed SlaveVP, which starts processors made from the code being
  13.509 -      // animated.
  13.510 -    
  13.511 -   (*langInitFnPtr)( newProcess );  
  13.512 -   
  13.513 -   return newProcess;
  13.514 - }
  13.515 -*/
  13.516 -
  13.517 -
  13.518 -/*When all SlaveVPs owned by the program-run associated to the process have
  13.519 - * dissipated, then return from this call.  There is no language to cleanup,
  13.520 - * and PR does not shutdown..  but the process bookkeeping structure,
  13.521 - * which is used by PR to track and schedule the program, is freed.
  13.522 - *The PRProcess structure is kept until this call collects the results from it,
  13.523 - * then freed.  If the process is not done yet when PR gets this
  13.524 - * call, then this call waits..  the challenge here is that this call comes from
  13.525 - * a live OS thread that's outside PR..  so, inside here, it waits on a 
  13.526 - * condition..  then it's a PR thread that signals this to wake up..
  13.527 +/*When all work in the process has completed, then return from this call.
  13.528 + * The seedVP of the process may still exist, but it has no work, nor do any
  13.529 + * other VPs..
  13.530 + *The process must be shutdown via a separate call.  That shutdown frees the
  13.531 + * process struct and bookkeeping structs.
  13.532   *First checks whether the process is done, if yes, calls the clean-up fn then
  13.533   * returns the result extracted from the PRProcess struct.
  13.534   *If process not done yet, then performs a wait (in a loop to be sure the
  13.535 @@ -322,9 +378,8 @@
  13.536   * the process ending (last SlaveVP owned by it dissipates), then PR signals
  13.537   * this to wakeup.  This then calls the cleanup fn and returns the result.
  13.538   */
  13.539 -/*
  13.540  void *
  13.541 -PR_App__give_results_when_done_for( PRProcess *process )
  13.542 +PR__give_results_from_process_when_ready( PRProcess *process )
  13.543   { void *result;
  13.544     
  13.545     pthread_mutex_lock( process->doneLock );
  13.546 @@ -333,109 +388,273 @@
  13.547        pthread_cond_wait( process->doneCond,
  13.548                           process->doneLock );
  13.549      }
  13.550 +   result = process->resultToReturn;
  13.551     pthread_mutex_unlock( process->doneLock );
  13.552 -   
  13.553 -   result = process->resultToReturn;
  13.554 -   
  13.555 -   PR_int__cleanup_process_after_done( process );
  13.556 -   free( process );  //was malloc'd above, so free it here
  13.557 -   
  13.558 +      
  13.559     return result;
  13.560   }
  13.561 +
  13.562 +
  13.563 +inline
  13.564 +void *
  13.565 +PR_SS__create_lang_env( int32 size, SlaveVP *slave, int32 magicNum )
  13.566 + {
  13.567 +   return PR_int__create_lang_env_in_process( size, slave->processSlaveIsIn, magicNum );
  13.568 + }
  13.569 +
  13.570 +
  13.571 +/*These store the pointer to handler into the language env -- language env
  13.572 + * found by using magic num to look it up in the process that the seedVP
  13.573 + * is inside of.
  13.574 + */
  13.575 +void
  13.576 +PR_SS__register_create_task_handler( RequestHandler createTaskHandler, SlaveVP *seedVP, int32 magicNum )
  13.577 + { PRLangEnv *langEnv;
  13.578 + 
  13.579 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.580 +   langEnv->createTaskHdlr = createTaskHandler; 
  13.581 + }
  13.582 +void
  13.583 +PR_SS__register_end_task_handler( RequestHandler endTaskHandler, SlaveVP *seedVP, int32 magicNum )
  13.584 + { PRLangEnv *langEnv;
  13.585 + 
  13.586 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.587 +   langEnv->endTaskHdlr = endTaskHandler; 
  13.588 + }
  13.589 +void
  13.590 +PR_SS__register_create_slave_handler( RequestHandler createSlvHandler, SlaveVP *seedVP, int32 magicNum )
  13.591 + { PRLangEnv *langEnv;
  13.592 + 
  13.593 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.594 +   langEnv->createSlaveHdlr = createSlvHandler; 
  13.595 + }
  13.596 +void
  13.597 +PR_SS__register_dissipate_slave_handler( RequestHandler dissipateHandler, SlaveVP *seedVP, int32 magicNum )
  13.598 + { PRLangEnv *langEnv;
  13.599 + 
  13.600 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.601 +   langEnv->dissipateSlaveHdlr = dissipateHandler; 
  13.602 + }
  13.603 +void
  13.604 +PR_SS__register_request_handler( RequestHandler reqHandler, SlaveVP *seedVP, int32 magicNum )
  13.605 + { PRLangEnv *langEnv;
  13.606 + 
  13.607 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.608 +   langEnv->requestHdlr = reqHandler; 
  13.609 + }
  13.610 +void
  13.611 +PR_SS__register_assigner( SlaveAssigner assigner, SlaveVP *seedVP, int32 magicNum )
  13.612 + { PRLangEnv *langEnv;
  13.613 + 
  13.614 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.615 +   langEnv->slaveAssigner = assigner; 
  13.616 + }
  13.617 +void
  13.618 +PR_SS__register_shutdown_handler( RequestHandler shutdownHdlr, SlaveVP *seedVP, int32 magicNum )
  13.619 + { PRLangEnv *langEnv;
  13.620 + 
  13.621 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.622 +   langEnv->shutdownHdlr = shutdownHdlr; 
  13.623 + }
  13.624 +/*
  13.625 +void
  13.626 +PR_SS__register_lang_data_creator( LangDataCreator langDataCreator, 
  13.627 +                                              SlaveVP *seedVP, int32 magicNum )
  13.628 + { PRLangEnv *langEnv;
  13.629 + 
  13.630 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.631 +   langEnv->langDataCreator = langDataCreator; 
  13.632 + }
  13.633 +void
  13.634 +PR_SS__register_lang_data_initializer( LangDataInitializer langDataInitializer, 
  13.635 +                                              SlaveVP *seedVP, int32 magicNum )
  13.636 + { PRLangEnv *langEnv;
  13.637 + 
  13.638 +   langEnv = PR_SS__give_proto_lang_env_for_slave( seedVP, magicNum );
  13.639 +   langEnv->langDataInitializer = langDataInitializer; 
  13.640 + }
  13.641  */
  13.642  
  13.643  
  13.644 +
  13.645 +
  13.646 +/*
  13.647 + *This function returns information about the version of PR, the language
  13.648 + * the program is being run in, its version, and information on the 
  13.649 + * hardware.
  13.650 + */
  13.651 +char *
  13.652 +PRServ___give_environment_string()
  13.653 + { char buffer[10000];
  13.654 +   int32 j;
  13.655 +   
  13.656 +   j = sizeof(int32);  //put total num chars here when done
  13.657 +   //--------------------------
  13.658 +   j += sprintf(buffer+j, "#\n# >> Build information <<\n");
  13.659 +   j += sprintf(buffer+j, "# GCC VERSION: %d.%d.%d\n",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
  13.660 +   j += sprintf(buffer+j, "# Build Date: %s %s\n", __DATE__, __TIME__);
  13.661 +    
  13.662 +   j += sprintf(buffer+j, "#\n# >> Hardware information <<\n");
  13.663 +   j += sprintf(buffer+j, "# Hardware Architecture: ");
  13.664 +   #ifdef __x86_64
  13.665 +   j += sprintf(buffer+j, "x86_64");
  13.666 +   #endif //__x86_64
  13.667 +   #ifdef __i386
  13.668 +   j += sprintf(buffer+j, "x86");
  13.669 +   #endif //__i386
  13.670 +   j += sprintf(buffer+j, "\n");
  13.671 +   j += sprintf(buffer+j, "# Number of Cores: %d\n", NUM_CORES);
  13.672 +   //--------------------------
  13.673 +    
  13.674 +   //PR Plugins
  13.675 +   j += sprintf(buffer+j, "#\n# >> PR Plugins <<\n");
  13.676 +   j += sprintf(buffer+j, "# Language : ");
  13.677 +   j += sprintf(buffer+j, _LANG_NAME_);
  13.678 +   j += sprintf(buffer+j, "\n");
  13.679 +       //Meta info gets set by calls from the language during its init,
  13.680 +       // and info registered by calls from inside the application
  13.681 +   j += sprintf(buffer+j, "# Assigner: %s\n", _PRTopEnv->metaInfo->assignerInfo);
  13.682 +
  13.683 +   //--------------------------
  13.684 +   //Application
  13.685 +   j += sprintf(buffer+j, "#\n# >> Application <<\n");
  13.686 +   j += sprintf(buffer+j, "# Name: %s\n", _PRTopEnv->metaInfo->appInfo);
  13.687 +   j += sprintf(buffer+j, "# Data Set:\n%s\n",_PRTopEnv->metaInfo->inputInfo);
  13.688 +    
  13.689 +   ((int32 *)buffer)[0] = j - sizeof(int32); //insert the number of chars
  13.690 +   //--------------------------
  13.691 +   return (char *) &(((int32 *)buffer)[1]); //return pointer to first char
  13.692 + }
  13.693 +
  13.694  void
  13.695 -create_masterEnv()
  13.696 - { MasterEnv       *masterEnv;
  13.697 +PR__set_app_info( char *info )
  13.698 + { int32 len;
  13.699 +   char *copy;
  13.700 +   len = strlen(info) +1;
  13.701 +   copy = PR_int__malloc(len);
  13.702 +   strcpy(copy, info);
  13.703 +   _PRTopEnv->metaInfo->appInfo = copy;
  13.704 + }
  13.705 +void
  13.706 +PR__set_input_info( char *info )
  13.707 + { int32 len;
  13.708 +   char *copy;
  13.709 +   len = strlen(info) +1;
  13.710 +   copy = PR_int__malloc(len);
  13.711 +   strcpy(copy, info);
  13.712 +   _PRTopEnv->metaInfo->inputInfo = copy;
  13.713 + }
  13.714 +
  13.715 +
  13.716 +
  13.717 +
  13.718 +
  13.719 +
  13.720 +void
  13.721 +create_topEnv()
  13.722 + { TopEnv       *masterEnv;
  13.723     PRQueueStruc   **readyToAnimateQs;
  13.724 -   int              coreIdx;
  13.725 +   int32            coreIdx;
  13.726     SlaveVP        **masterVPs;
  13.727     AnimSlot      ***allAnimSlots; //ptr to array of ptrs
  13.728  
  13.729 +      //Make the top env, which holds everything else
  13.730 +   _PRTopEnv = malloc( sizeof(TopEnv) );
  13.731  
  13.732 -      //Make the master env, which holds everything else
  13.733 -   _PRTopEnv = malloc( sizeof(MasterEnv) );
  13.734 -
  13.735 -        //Very first thing put into the master env is the free-list, seeded
  13.736 +        //Very first thing put into the top env is the free-list, seeded
  13.737          // with a massive initial chunk of memory.
  13.738          //After this, all other mallocs are PR__malloc.
  13.739 -   _PRTopEnv->freeLists        = PR_ext__create_free_list();
  13.740 +   _PRTopEnv->freeLists           = PR_ext__create_free_list();
  13.741 +   _PRTopEnv->amtOfOutstandingMem = 0;
  13.742 +
  13.743 +   //===================== Only PR__malloc after this =====================
  13.744 +   //
  13.745     
  13.746 +   //=================== Both single and multi lang vars ==================
  13.747 +   //
  13.748 +   //
  13.749 +   _PRTopEnv->metaInfo     = PR_int__malloc( sizeof(PRSysMetaInfo) );
  13.750 +   memset( _PRTopEnv->metaInfo, 0, sizeof(PRSysMetaInfo) );
  13.751 +  
  13.752 +   masterVPs               = PR_int__malloc( NUM_CORES * sizeof(SlaveVP *) );
  13.753 +   _PRTopEnv->masterVPs    = masterVPs;
  13.754     
  13.755 -   //===================== Only PR__malloc after this ====================
  13.756 -   masterEnv     = (MasterEnv*)_PRTopEnv;
  13.757 -   
  13.758 -      //Make a readyToAnimateQ for each core controller
  13.759 -   readyToAnimateQs = PR_int__malloc( NUM_CORES * sizeof(PRQueueStruc *) );
  13.760 -   masterVPs        = PR_int__malloc( NUM_CORES * sizeof(SlaveVP *) );
  13.761 +   allAnimSlots            = PR_int__malloc( NUM_CORES * sizeof(AnimSlot *) );
  13.762 +   _PRTopEnv->allAnimSlots = allAnimSlots;
  13.763  
  13.764 -      //One array for each core, several in array, core's masterVP scheds all
  13.765 -   allAnimSlots    = PR_int__malloc( NUM_CORES * sizeof(AnimSlot *) );
  13.766 -
  13.767 -   _PRTopEnv->numSlavesAlive = 0;  //used to detect shut-down condition
  13.768 -
  13.769 -//========================================
  13.770 -   
  13.771 -   Copied__fixThis;
  13.772 -   
  13.773 -   semEnv->freeExtraTaskSlvQ    = makePRQ();
  13.774 -   semEnv->numLiveExtraTaskSlvs   = 0; //must be last
  13.775 -   semEnv->numLiveThreadSlvs      = 1; //must be last, counts the seed
  13.776 -   
  13.777 -   semEnv->shutdownInitiated = FALSE;
  13.778 -//   semEnv->coreIsDone = PR_int__malloc( NUM_CORES * sizeof( bool32 ) );
  13.779 -   
  13.780 +   //Make the master VPs
  13.781 +   for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
  13.782 +    {    
  13.783 +      readyToAnimateQs[ coreIdx ] = makePRQ();
  13.784 +      
  13.785 +         //Q: should give masterVP core-specific info as its init data?
  13.786 +      masterVPs[ coreIdx ] = PR_int__create_slave( (TopLevelFnPtr)&animationMaster, (void*)_PRTopEnv );
  13.787 +      masterVPs[ coreIdx ]->coreAnimatedBy = coreIdx;
  13.788 +      masterVPs[ coreIdx ]->typeOfVP = Master;
  13.789 +      allAnimSlots[ coreIdx ] = create_anim_slots( coreIdx ); //makes for one core
  13.790 +    }
  13.791 +    
  13.792        //For each animation slot, there is an idle slave, and an initial
  13.793        // slave assigned as the current-task-slave.  Create them here.
  13.794     int32    coreNum,  slotNum;
  13.795     SlaveVP *idleSlv, *slotTaskSlv;
  13.796 +   
  13.797     for( coreNum = 0;  coreNum < NUM_CORES; coreNum++ )
  13.798 -    { //semEnv->coreIsDone[coreNum] = FALSE; //use during shutdown
  13.799 +    { //langEnv->coreIsDone[coreNum] = FALSE; //use during shutdown
  13.800      
  13.801        for( slotNum = 0; slotNum < NUM_ANIM_SLOTS; ++slotNum )
  13.802 -       { idleSlv = PR__create_slave_helper( &idle_fn, NULL, semEnv, 0);
  13.803 +       { idleSlv = PR_int__create_slaveVP( &idle_fn, NULL );
  13.804           idleSlv->coreAnimatedBy                = coreNum;
  13.805           idleSlv->animSlotAssignedTo            =
  13.806                                 _PRTopEnv->allAnimSlots[coreNum][slotNum];
  13.807           _PRTopEnv->idleSlv[coreNum][slotNum] = idleSlv;
  13.808           
  13.809 +         
  13.810           slotTaskSlv = PR_int__create_slot_slave( );
  13.811           slotTaskSlv->coreAnimatedBy            = coreNum;
  13.812           slotTaskSlv->animSlotAssignedTo        = 
  13.813                                 _PRTopEnv->allAnimSlots[coreNum][slotNum];
  13.814           
  13.815 -//         slotTaskSlv->needsTaskAssigned = TRUE;
  13.816 -         slotTaskSlv->slaveType         = SlotTaskSlv;
  13.817 +         slotTaskSlv->typeOfVP                     = SlotTaskSlv;
  13.818           _PRTopEnv->slotTaskSlvs[coreNum][slotNum] = slotTaskSlv;
  13.819         }
  13.820      }
  13.821  
  13.822 -      //create the recycle queue where free task slaves are put after their task ends
  13.823 -   semEnv->freeTaskSlvRecycleQ  = makePRQ();
  13.824 +   _PRTopEnv->slaveRecycleQ    = makePRQ();
  13.825     
  13.826 -
  13.827 -   semEnv->numLiveFreeTaskSlvs   = 0;
  13.828 -   semEnv->numLiveGenericSlvs    = 0; //none existent yet.. "create process" creates the seeds  
  13.829 -//==================================================================
  13.830 -   
  13.831 -   _PRTopEnv->numSlavesCreated = 0;  //used by create slave to set slave ID
  13.832 -   for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
  13.833 -    {    
  13.834 -      readyToAnimateQs[ coreIdx ] = makePRQ();
  13.835 -      
  13.836 -         //Q: should give masterVP core-specific info as its init data?
  13.837 -      masterVPs[ coreIdx ] = PR_int__create_slaveVP( (TopLevelFnPtr)&animationMaster, (void*)masterEnv );
  13.838 -      masterVPs[ coreIdx ]->coreAnimatedBy = coreIdx;
  13.839 -      masterVPs[ coreIdx ]->typeOfVP = Master;
  13.840 -      allAnimSlots[ coreIdx ] = create_anim_slots( coreIdx ); //makes for one core
  13.841 -    }
  13.842 -   _PRTopEnv->masterVPs        = masterVPs;
  13.843     _PRTopEnv->masterLock       = UNLOCKED;
  13.844     _PRTopEnv->seed1 = rand()%1000; // init random number generator
  13.845     _PRTopEnv->seed2 = rand()%1000; // init random number generator
  13.846 -   _PRTopEnv->allAnimSlots    = allAnimSlots;
  13.847 -   _PRTopEnv->measHistsInfo = NULL; 
  13.848 +   
  13.849 +   _PRTopEnv->measHistsInfo    = NULL; 
  13.850 +   
  13.851 +   _PRTopEnv->numSlavesCreated = 0;  //used by create slave to set slave ID
  13.852 +  
  13.853 +   //=================== single lang only vars ==================
  13.854 +   //
  13.855 +   //
  13.856 +   _PRTopEnv->numSlavesCreated = 0;  //used to give unique ID to processor
  13.857 +   _PRTopEnv->numTasksCreated  = 0;   //to give unique ID to a task
  13.858 +   _PRTopEnv->numSlavesAlive   = 0;
  13.859 +
  13.860 +   _PRTopEnv->shutdownInitiated = FALSE;
  13.861 +   _PRTopEnv->coreIsDone = PR_int__malloc( NUM_CORES * sizeof( bool32 ) );
  13.862 +   memset( _PRTopEnv->coreIsDone, 0, NUM_CORES * sizeof( bool32 ) );
  13.863 +
  13.864 +   //=================== multi lang only vars ==================
  13.865 +   //
  13.866 +   //
  13.867 +   readyToAnimateQs = PR_int__malloc( NUM_CORES * sizeof(PRQueueStruc *) );
  13.868 +   
  13.869 +   _PRTopEnv->processes    = PR_int__malloc( NUM_IN_COLLECTION * sizeof(PRProcess *) );
  13.870 +   _PRTopEnv->numProcesses = 0;
  13.871 +   _PRTopEnv->currProcessIdx = 0;
  13.872 +   _PRTopEnv->firstProcessReady = FALSE;      //use while starting up coreCtlr   
  13.873 +   
  13.874 +      //initialize flags for waiting for activity within PR to complete
  13.875 +   pthread_mutex_init( _PRTopEnv->activityDoneLock, NULL );
  13.876 +   pthread_cond_init(  _PRTopEnv->activityDoneCond, NULL );
  13.877 +   _PRTopEnv->allActivityIsDone = FALSE;
  13.878  
  13.879     //============================= MEASUREMENT STUFF ========================
  13.880        
  13.881 @@ -484,6 +703,13 @@
  13.882   }
  13.883  
  13.884  
  13.885 +/*This is called during PR startup..  It simple creates the OS threads, with the
  13.886 + * core controller code as the top level function.
  13.887 + *However, there's nothing for these threads to do until a process is created,
  13.888 + * so, the core controller has a cond-var and flag in the top env they all 
  13.889 + * "wait" on.  The process creation call includes a singleton that releases
  13.890 + * all the core controller threads when the first process is created.
  13.891 + */
  13.892  void
  13.893  create_the_coreCtlr_OS_threads()
  13.894   {
  13.895 @@ -494,7 +720,7 @@
  13.896        //Need the threads to be created suspended, and wait for a signal
  13.897        // before proceeding -- gives time after creating to initialize other
  13.898        // stuff before the coreCtlrs set off.
  13.899 -   _PRTopEnv->setupComplete = 0;
  13.900 +   _PRTopEnv->firstProcessReady = 0;
  13.901     
  13.902        //initialize the cond used to make the new threads wait and sync up
  13.903        //must do this before *creating* the threads..
  13.904 @@ -516,94 +742,50 @@
  13.905   }
  13.906  
  13.907  
  13.908 -/*This is what causes the PR system to initialize.. then waits for it to
  13.909 - * exit.
  13.910 +//==========================  SHUT DOWN  ===========================
  13.911 +
  13.912 +/*This is called from the main thread, and causes PR's OS threads to stop
  13.913 + * then cleans up any memory allocated by PR from the OS.
  13.914   * 
  13.915 - *Wrapper lib layer calls this when it wants the system to start running..
  13.916 + *The main thread has a separate call it can use to wait for all work to
  13.917 + * finish, so when this is called, it just shuts down, whether there's
  13.918 + * unfinished work or not.
  13.919 + * 
  13.920 + *However, cores that are performing work won't see this shutdown until
  13.921 + * they finish their current work-unit.
  13.922   */
  13.923 -/*
  13.924 -void
  13.925 -PR_SS__start_the_work_then_wait_until_done()
  13.926 - { 
  13.927 -#ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
  13.928 -   //Only difference between version with an OS thread pinned to each core and
  13.929 -   // the sequential version of PR is PR__init_Seq, this, and coreCtlr_Seq.
  13.930 -   //
  13.931 -         //Instead of un-suspending threads, just call the one and only
  13.932 -         // core ctlr (sequential version), in the main thread.
  13.933 -      coreCtlr_Seq( NULL );
  13.934 -      flushRegisters();
  13.935 -#else
  13.936 -   int coreIdx;
  13.937 -      //Start the core controllers running
  13.938 +PR__shutdown()
  13.939 + { int32 coreIdx;
  13.940     
  13.941 -      //tell the core controller threads that setup is complete
  13.942 -      //get lock, to lock out any threads still starting up -- they'll see
  13.943 -      // that setupComplete is true before entering while loop, and so never
  13.944 -      // wait on the condition
  13.945 -   pthread_mutex_lock(     &suspendLock );
  13.946 -   _PRTopEnv->setupComplete = 1;
  13.947 -   pthread_mutex_unlock(   &suspendLock );
  13.948 -   pthread_cond_broadcast( &suspendCond );
  13.949 +   PR_SS__shutdown_OS_threads();
  13.950     
  13.951 -   
  13.952 -      //wait for all to complete
  13.953 +      //wait for the OS threads to exit
  13.954     for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ )
  13.955      {
  13.956        pthread_join( coreCtlrThdHandles[coreIdx], NULL );
  13.957      }
  13.958 -   
  13.959 -      //NOTE: do not clean up PR env here -- semantic layer has to have
  13.960 -      // a chance to clean up its environment first, then do a call to free
  13.961 -      // the Master env and rest of PR locations
  13.962 -#endif
  13.963 - }
  13.964 -*/
  13.965  
  13.966 -SlaveVP* PR_SS__create_shutdown_slave()
  13.967 - {
  13.968 -   SlaveVP* shutdownVP;
  13.969 -   
  13.970 -   shutdownVP = PR_int__create_slaveVP( &endOSThreadFn, NULL );
  13.971 -   shutdownVP->typeOfVP = Shutdown;
  13.972 -    
  13.973 -   return shutdownVP;
  13.974 +      //Before getting rid of everything, print out any measurements made
  13.975 +   PR_SS__print_out_measurements();
  13.976 +
  13.977 +      //free all memory allocated from the OS
  13.978 +   PR_SS__cleanup_at_end_of_shutdown();
  13.979   }
  13.980  
  13.981 -//TODO: look at architecting cleanest separation between request handler
  13.982 -// and animation master, for dissipate, create, shutdown, and other non-semantic
  13.983 -// requests.  Issue is chain: one removes requests from AppSlv, one dispatches
  13.984 -// on type of request, and one handles each type..  but some types require
  13.985 -// action from both request handler and animation master -- maybe just give the
  13.986 -// request handler calls like:  PR__handle_X_request_type
  13.987  
  13.988 -
  13.989 -/*This is called by the semantic layer's request handler when it decides its
  13.990 - * time to shut down the PR system.  Calling this causes the core controller OS
  13.991 - * threads to exit, which unblocks the entry-point function that started up
  13.992 - * PR, and allows it to grab the result and return to the original single-
  13.993 - * threaded application.
  13.994 +/*Calling this causes the core controller OS threads to exit, 
  13.995   * 
  13.996 - *The _PRTopEnv is needed by this shut down function, so the create-seed-
  13.997 - * and-wait function has to free a bunch of stuff after it detects the
  13.998 - * threads have all died: the masterEnv, the thread-related locations,
  13.999 - * masterVP any AppSlvs that might still be allocated and sitting in the
 13.1000 - * semantic environment, or have been orphaned in the _PRWorkQ.
 13.1001 + *The _PRTopEnv is used inside this shut down function, so it wait until
 13.1002 + * the OS thread shutdown is done before freeing it.
 13.1003 + *  
 13.1004 + *In here,create one core-loop shut-down slave for each core controller 
 13.1005 + * and put them all directly into the animation slots.
 13.1006   * 
 13.1007 - *NOTE: the semantic plug-in is expected to use PR__malloc to get all the
 13.1008 - * locations it needs, and give ownership to masterVP.  Then, they will be
 13.1009 - * automatically freed.
 13.1010 - *
 13.1011 - *In here,create one core-loop shut-down processor for each core controller and put
 13.1012 - * them all directly into the readyToAnimateQ.
 13.1013 - *Note, this function can ONLY be called after the semantic environment no
 13.1014 - * longer cares if AppSlvs get animated after the point this is called.  In
 13.1015 - * other words, this can be used as an abort, or else it should only be
 13.1016 - * called when all AppSlvs have finished dissipate requests -- only at that
 13.1017 - * point is it sure that all results have completed.
 13.1018 + *Note, this function should ONLY be called after all processes have ended,
 13.1019 + * because it doesn't pay attention to whether unfinished work exists.. 
 13.1020   */
 13.1021  void
 13.1022 -PR_SS__shutdown()
 13.1023 +PR_SS__shutdown_OS_threads()
 13.1024   { int32       coreIdx;
 13.1025     SlaveVP    *shutDownSlv;
 13.1026     AnimSlot **animSlots;
 13.1027 @@ -623,6 +805,48 @@
 13.1028   }
 13.1029  
 13.1030  
 13.1031 +SlaveVP* PR_SS__create_shutdown_slave()
 13.1032 + {
 13.1033 +   SlaveVP* shutdownVP;
 13.1034 +   
 13.1035 +   shutdownVP = PR_int__create_slave( &endOSThreadFn, NULL );
 13.1036 +   shutdownVP->typeOfVP = Shutdown;
 13.1037 +    
 13.1038 +   return shutdownVP;
 13.1039 + }
 13.1040 +
 13.1041 +
 13.1042 +
 13.1043 +void
 13.1044 +PR_SS__print_out_measurements()
 13.1045 + {
 13.1046 +   if( _PRTopEnv->measHistsInfo != NULL )
 13.1047 +    { forAllInDynArrayDo( _PRTopEnv->measHistsInfo, (DynArrayFnPtr)&printHist );
 13.1048 +      forAllInDynArrayDo( _PRTopEnv->measHistsInfo, (DynArrayFnPtr)&saveHistToFile);
 13.1049 +      forAllInDynArrayDo( _PRTopEnv->measHistsInfo, (DynArrayFnPtr)&freeHist );
 13.1050 +    }
 13.1051 +   
 13.1052 +   MEAS__Print_Hists_for_Susp_Meas;
 13.1053 +   MEAS__Print_Hists_for_Master_Meas;
 13.1054 +   MEAS__Print_Hists_for_Master_Lock_Meas;
 13.1055 +   MEAS__Print_Hists_for_Malloc_Meas;
 13.1056 +   MEAS__Print_Hists_for_Plugin_Meas;
 13.1057 + }
 13.1058 +
 13.1059 +/*This is run in the main thread, as part of the PR__shutdown() call
 13.1060 + * It frees any memory allocated from the OS
 13.1061 + */
 13.1062 +void
 13.1063 +PR_SS__cleanup_at_end_of_shutdown()
 13.1064 + { 
 13.1065 +      //All the environment data has been allocated with PR__malloc, so just
 13.1066 +      // free the memory obtained by PR__malloc, then free the top env.
 13.1067 +      //These are the only two that use system free 
 13.1068 +   PR_ext__free_free_list( _PRTopEnv->freeLists );
 13.1069 +   free( (void *)_PRTopEnv );
 13.1070 + }
 13.1071 +
 13.1072 +
 13.1073  /*Am trying to be cute, avoiding IF statement in coreCtlr that checks for
 13.1074   * a special shutdown slaveVP.  Ended up with extra-complex shutdown sequence.
 13.1075   *This function has the sole purpose of setting the stack and framePtr
 13.1076 @@ -646,58 +870,6 @@
 13.1077     #endif
 13.1078   }
 13.1079  
 13.1080 -
 13.1081 -/*This is called from the startup & shutdown
 13.1082 - */
 13.1083 -void
 13.1084 -PR_SS__cleanup_at_end_of_shutdown()
 13.1085 - { 
 13.1086 -      //Before getting rid of everything, print out any measurements made
 13.1087 -   if( _PRTopEnv->measHistsInfo != NULL )
 13.1088 -    { forAllInDynArrayDo( _PRTopEnv->measHistsInfo, (DynArrayFnPtr)&printHist );
 13.1089 -      forAllInDynArrayDo( _PRTopEnv->measHistsInfo, (DynArrayFnPtr)&saveHistToFile);
 13.1090 -      forAllInDynArrayDo( _PRTopEnv->measHistsInfo, (DynArrayFnPtr)&freeHist );
 13.1091 -    }
 13.1092 -   
 13.1093 -   MEAS__Print_Hists_for_Susp_Meas;
 13.1094 -   MEAS__Print_Hists_for_Master_Meas;
 13.1095 -   MEAS__Print_Hists_for_Master_Lock_Meas;
 13.1096 -   MEAS__Print_Hists_for_Malloc_Meas;
 13.1097 -   MEAS__Print_Hists_for_Plugin_Meas;
 13.1098 -   
 13.1099 -
 13.1100 -      //All the environment data has been allocated with PR__malloc, so just
 13.1101 -      // free its internal big-chunk and all inside it disappear.
 13.1102 -/*
 13.1103 -   readyToAnimateQs = _PRTopEnv->readyToAnimateQs;
 13.1104 -   masterVPs        = _PRTopEnv->masterVPs;
 13.1105 -   allAnimSlots    = _PRTopEnv->allAnimSlots;
 13.1106 -   
 13.1107 -   for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
 13.1108 -    {
 13.1109 -      freePRQ( readyToAnimateQs[ coreIdx ] );
 13.1110 -         //master Slvs were created external to PR, so use external free
 13.1111 -      PR_int__dissipate_slaveVP( masterVPs[ coreIdx ] );
 13.1112 -      
 13.1113 -      freeAnimSlots( allAnimSlots[ coreIdx ] );
 13.1114 -    }
 13.1115 -   
 13.1116 -   PR_int__free( _PRTopEnv->readyToAnimateQs );
 13.1117 -   PR_int__free( _PRTopEnv->masterVPs );
 13.1118 -   PR_int__free( _PRTopEnv->allAnimSlots );
 13.1119 -   
 13.1120 -   //============================= MEASUREMENT STUFF ========================
 13.1121 -   #ifdef PROBES__TURN_ON_STATS_PROBES
 13.1122 -   freeDynArrayDeep( _PRTopEnv->dynIntervalProbesInfo, &PR_WL__free_probe);
 13.1123 -   #endif
 13.1124 -   //========================================================================
 13.1125 -*/
 13.1126 -      //These are the only two that use system free 
 13.1127 -   PR_ext__free_free_list( _PRTopEnv->freeLists );
 13.1128 -   free( (void *)_PRTopEnv );
 13.1129 - }
 13.1130 -
 13.1131 -
 13.1132  //================================
 13.1133  
 13.1134  
    14.1 --- a/PR__WL.c	Sun Nov 04 18:39:28 2012 -0800
    14.2 +++ b/PR__WL.c	Mon Jan 14 15:31:23 2013 -0800
    14.3 @@ -1,5 +1,5 @@
    14.4  /*
    14.5 - * Copyright 2010  OpenSourceStewardshipFoundation
    14.6 + * Copyright 2010  OpenSourceResearchInstitute
    14.7   *
    14.8   * Licensed under BSD
    14.9   */
   14.10 @@ -25,17 +25,27 @@
   14.11  
   14.12  
   14.13  
   14.14 -inline int32 *
   14.15 -PR__give_task_ID( SlaveVP *animSlv, int32 magicNumber )
   14.16 +inline 
   14.17 +int32 *
   14.18 +PR__give_ID_from_slave( SlaveVP *animSlv, int32 magicNumber )
   14.19   {
   14.20 -   return animSlv->metaTask->taskID;
   14.21 +   return animSlv->ID;
   14.22 + }
   14.23 +
   14.24 +inline
   14.25 +int32 *
   14.26 +PR__give_ID_from_task( void *_task )
   14.27 + { PRMetaTask task;
   14.28 +   task = ((PRMetaTask *)_task)[-1];
   14.29 +   return task->ID;
   14.30   }
   14.31  
   14.32  SlaveVP *
   14.33 -PR__give_slave_of_task_ID( int32 *taskID, SlaveVP *animSlv )
   14.34 +PR__give_owner_of_ID( int32 *taskID, SlaveVP *animSlv )
   14.35   {
   14.36 -   metaTask = lookup( taskID );
   14.37 -   return metaTask->slaveAssignedTo;
   14.38 +    implement_me();
   14.39 +   //metaTask = lookup( taskID );
   14.40 +   //return metaTask->slaveAssignedTo;
   14.41   }
   14.42  
   14.43  /*For this implementation of PR, it may not make much sense to have the
   14.44 @@ -52,15 +62,15 @@
   14.45   * to the plugin.
   14.46   */
   14.47  void
   14.48 -PR_WL__send_create_slaveVP_req( void *semReq, int32 *slvID, SlaveVP *reqstingSlv, 
   14.49 -                                int32 magicNum )
   14.50 +PR_WL__send_create_slaveVP_req( void *langReq, CreateHandler handler, 
   14.51 +                           int32 *slvID, SlaveVP *reqstingSlv, int32 magicNum )
   14.52   { PRReqst req;
   14.53  
   14.54     req.reqType          = SlvCreate;
   14.55     req.ID               = slvID;
   14.56     req.langMagicNumber  = magicNum;
   14.57 -   req.semReq           = semReq;
   14.58 -//   req.nextReqst        = reqstingSlv->request;
   14.59 +   req.langReq          = langReq;
   14.60 +   req.createHdlr       = handler;
   14.61     reqstingSlv->request = &req;
   14.62  
   14.63     PR_WL__suspend_slaveVP_and_send_req( reqstingSlv );
   14.64 @@ -71,7 +81,7 @@
   14.65   *This adds a request to dissipate, then suspends the processor so that the
   14.66   * request handler will receive the request.  The request handler is what
   14.67   * does the work of freeing memory and removing the processor from the
   14.68 - * semantic environment's data structures.
   14.69 + * language environment's data structures.
   14.70   *The request handler also is what figures out when to shutdown the PR
   14.71   * system -- which causes all the core controller threads to die, and returns from
   14.72   * the call that started up PR to perform the work.
   14.73 @@ -89,10 +99,13 @@
   14.74   * pears -- making that suspend the last thing in the Slv's trace.
   14.75   */
   14.76  void
   14.77 -PR_WL__send_dissipate_req( SlaveVP *slaveToDissipate )
   14.78 +PR_WL__send_end_slave_req( RequestHandler handler, SlaveVP *slaveToDissipate,
   14.79 +                                                                int32 magicNum )
   14.80   { PRReqst req;
   14.81  
   14.82     req.reqType                = SlvDissipate;
   14.83 +   req.langMagicNumber        = magicNum;
   14.84 +   req.handler                = handler;
   14.85  //   req.nextReqst              = slaveToDissipate->request;
   14.86     slaveToDissipate->request = &req;
   14.87  
   14.88 @@ -101,16 +114,16 @@
   14.89   
   14.90  inline
   14.91  void
   14.92 -PR_WL__send_create_task_req( TopLevelFn fn, void *initData, void *semReq, 
   14.93 -     int32 *taskID, RequestHandler handler, SlaveVP *animSlv, int32 magicNumber)
   14.94 +PR_WL__send_create_task_req( TopLevelFn fn, void *initData, void *langReq, 
   14.95 +     int32 *taskID, CreateHandler handler, SlaveVP *animSlv, int32 magicNumber)
   14.96   { PRReqst req;
   14.97   
   14.98     req.reqType    = TaskCreate;
   14.99     req.topLevelFn = fn;
  14.100     req.initData   = initData;
  14.101     req.ID         = taskID;
  14.102 -   req.semReq     = semReq;
  14.103 -   req.handler    = handler;
  14.104 +   req.langReq    = langReq;
  14.105 +   req.createHdlr = handler;
  14.106     req.langMagicNumber = magicNumber;
  14.107     animSlv->request = &req;
  14.108     
  14.109 @@ -119,12 +132,12 @@
  14.110  
  14.111  inline
  14.112  void
  14.113 -PR_WL__send_end_task_request( void *semReq, RequestHandler handler, 
  14.114 +PR_WL__send_end_task_request( void *langReq, RequestHandler handler, 
  14.115                                                SlaveVP *animSlv, int32 magicNum )
  14.116   { PRReqst req;
  14.117   
  14.118     req.reqType    = TaskEnd;
  14.119 -   req.semReq     = semReq;
  14.120 +   req.langReq     = langReq;
  14.121     req.handler    = handler;
  14.122     req.langMagicNumber = magicNum;
  14.123     animSlv->request = &req;
  14.124 @@ -137,20 +150,20 @@
  14.125   * has to free any extra requests tacked on before a send, using this.
  14.126   *
  14.127   * This inserts the semantic-layer's request data into standard PR carrier
  14.128 - * request data-struct that is mallocd.  The sem request doesn't need to
  14.129 + * request data-struct that is mallocd.  The lang request doesn't need to
  14.130   * be malloc'd if this is called inside the same call chain before the
  14.131   * send of the last request is called.
  14.132   *
  14.133   *The request handler has to call PR_int__free_PRReq for any of these
  14.134   */
  14.135  inline void
  14.136 -PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData,
  14.137 +PR_WL__add_lang_request_in_mallocd_PRReqst( void *langReqData,
  14.138                                            SlaveVP *callingSlv )
  14.139   { PRReqst *req;
  14.140 -
  14.141 +//WARNING: not update.. may be buggy
  14.142     req = PR_int__malloc( sizeof(PRReqst) );
  14.143     req->reqType         = Language;
  14.144 -   req->semReq          = semReqData;
  14.145 +   req->langReq          = langReqData;
  14.146     req->nextReqst       = callingSlv->request;
  14.147     callingSlv->request  = req;
  14.148   }
  14.149 @@ -170,13 +183,14 @@
  14.150   *Then it does suspend, to cause request to be sent.
  14.151   */
  14.152  inline void
  14.153 -PR_WL__send_sem_request( void *semReqData, SlaveVP *callingSlv, int32 magicNum )
  14.154 +PR_WL__send_lang_request( void *langReqData, RequestHandler handler, 
  14.155 +                                           SlaveVP *callingSlv, int32 magicNum )
  14.156   { PRReqst req;
  14.157  
  14.158     req.reqType         = Language;
  14.159     req.langMagicNumber = magicNum;
  14.160 -   req.
  14.161 -   req.semReq          = semReqData;
  14.162 +   req.langReq         = langReqData;
  14.163 +   req.handler         = handler;
  14.164     req.nextReqst       = callingSlv->request;
  14.165     callingSlv->request = &req;
  14.166     
  14.167 @@ -188,12 +202,12 @@
  14.168   * 
  14.169   */
  14.170  inline void
  14.171 -PR_WL__send_service_request( void *semReqData, SlaveVP *callingSlv )
  14.172 +PR_WL__send_service_request( void *langReqData, SlaveVP *callingSlv )
  14.173   { PRReqst req;
  14.174  
  14.175 -   req.reqType         = PRLang;
  14.176 -   req.langMagicNumber = PRLang_MAGIC_NUMBER;
  14.177 -   req.semReq          = semReqData;
  14.178 +   req.reqType         = Service;
  14.179 +   req.langMagicNumber = PRServ_MAGIC_NUMBER;
  14.180 +   req.langReq          = langReqData;
  14.181     req.nextReqst       = callingSlv->request; //grab any other preceeding 
  14.182     callingSlv->request = &req;
  14.183  
  14.184 @@ -207,15 +221,15 @@
  14.185  void
  14.186  PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv,  PRExcp *excpData )
  14.187   { PRReqst req;
  14.188 -   PRServReq semReq;
  14.189 +   PRServReq langReq;
  14.190  
  14.191 -   req.reqType         = PRSemantic;
  14.192 -   req.semReq      = &semReq;
  14.193 +   req.reqType         = Language;
  14.194 +   req.langReq          = &langReq;
  14.195     req.nextReqst       = reqstSlv->request; //gab any other preceeding 
  14.196     reqstSlv->request   = &req;
  14.197  
  14.198 -   semReq.msgStr        = msgStr;
  14.199 -   semReq.exceptionData = excpData;
  14.200 +   langReq.msgStr        = msgStr;
  14.201 +   langReq.exceptionData = excpData;
  14.202     
  14.203     PR_WL__suspend_slaveVP_and_send_req( reqstSlv );
  14.204   }
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/PR__WL.h	Mon Jan 14 15:31:23 2013 -0800
    15.3 @@ -0,0 +1,122 @@
    15.4 +/*
    15.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
    15.6 + *  Licensed under GNU General Public License version 2
    15.7 + *
    15.8 + * Author: seanhalle@yahoo.com
    15.9 + * 
   15.10 + */
   15.11 +
   15.12 +#ifndef _PR__WL_H
   15.13 +#define	_PR__WL_H
   15.14 +#define _GNU_SOURCE
   15.15 +
   15.16 +#include "PR_primitive_data_types.h"
   15.17 +#include "PR__structs.h"
   15.18 +//=========================  Function Prototypes  ===========================
   15.19 +/* MEANING OF   WL  PI  SS  int PROS
   15.20 + * These indicate which places the function is safe to use.  They stand for:
   15.21 + * 
   15.22 + * WL   Wrapper Library -- wrapper lib code should only use these
   15.23 + * PI   Plugin          -- plugin code should only use these
   15.24 + * SS   Startup and Shutdown -- designates these relate to startup & shutdown
   15.25 + * int32internal to PR -- should not be used in wrapper lib or plugin
   15.26 + * PROS means "OS functions for applications to use"
   15.27 + * 
   15.28 + * PR_int__ functions touch internal PR data structs and are only safe
   15.29 + *  to be used inside the master lock.  However, occasionally, they appear
   15.30 + * in wrapper-lib or plugin code.  In those cases, very careful analysis
   15.31 + * has been done to be sure no concurrency issues could arise.
   15.32 + * 
   15.33 + * PR_WL__ functions are all safe for use outside the master lock.
   15.34 + * 
   15.35 + * PROS are only safe for applications to use -- they're like a second
   15.36 + * language mixed in -- but they can't be used inside plugin code, and
   15.37 + * aren't meant for use in wrapper libraries, because they are themselves
   15.38 + * wrapper-library calls!
   15.39 + */
   15.40 +//========== Startup and shutdown ==========
   15.41 +void
   15.42 +PR__start();
   15.43 +
   15.44 +SlaveVP* 
   15.45 +PR_SS__create_shutdown_slave();
   15.46 +
   15.47 +void
   15.48 +PR_SS__shutdown();
   15.49 +
   15.50 +void
   15.51 +PR_SS__cleanup_at_end_of_shutdown();
   15.52 +
   15.53 +void
   15.54 +PR_SS__register_langlets_langEnv( PRLangEnv *langEnv, SlaveVP  *seedVP, int32 VSs_MAGIC_NUMBER );
   15.55 +
   15.56 +//============== include internally used fn prototypes ================
   15.57 +#include "PR__int.h"
   15.58 +
   15.59 +//==============    ===============
   15.60 +
   15.61 +inline
   15.62 +SlaveVP *
   15.63 +PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask );
   15.64 +
   15.65 +//==============  Request Related  ===============
   15.66 +
   15.67 +void
   15.68 +PR_WL__suspend_slaveVP_and_send_req( SlaveVP *callingSlv );
   15.69 +
   15.70 +inline void
   15.71 +PR_WL__add_lang_request_in_mallocd_PRReqst( void *langReqData, 
   15.72 +                                                          SlaveVP *callingSlv );
   15.73 +
   15.74 +inline void
   15.75 +PR_WL__send_lang_request( void *langReq, SlaveVP *callingSlv, int32 magicNum );
   15.76 +
   15.77 +void
   15.78 +PR_WL__send_create_slaveVP_req( void *langReq, CreateHandler handler, 
   15.79 +                           int32 *slvID, SlaveVP *reqstingSlv, int32 magicNum );
   15.80 +
   15.81 +void inline
   15.82 +PR_WL__send_end_slave_req( SlaveVP *prToDissipate, int32 magicNum );
   15.83 +
   15.84 +inline void
   15.85 +PR_WL__send_service_request( void *langReqData, SlaveVP *callingSlv );
   15.86 +
   15.87 +PRReqst *
   15.88 +PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
   15.89 +//#define PR_PI__take_next_request_out_of( slave ) slave->requests
   15.90 +
   15.91 +//inline void *
   15.92 +//PR_PI__take_lang_reqst_from( PRReqst *req );
   15.93 +#define PR_PI__take_lang_reqst_from( req ) req->langReqData
   15.94 +
   15.95 +//======================== MEASUREMENT ======================
   15.96 +uint64
   15.97 +PR_WL__give_num_plugin_cycles();
   15.98 +uint32
   15.99 +PR_WL__give_num_plugin_animations();
  15.100 +
  15.101 +
  15.102 +//========================= Utilities =======================
  15.103 +void
  15.104 +PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv,  PRExcp *excpData );
  15.105 +#define PR_App__throw_exception PR_WL__throw_exception
  15.106 +
  15.107 +#define implement_me printf("Unimpl Fn: \n%s \n%s : %s\n", __FILE__, __FUNCTION__, __LINE__)
  15.108 +//#define fix_me printf("Fix me at: \n%s \n%s : %s\n", __FILE__, __FUNCTION__, __LINE__)
  15.109 +
  15.110 +//=========================  PR request handlers  ========================
  15.111 +void inline
  15.112 +handleMakeProbe( PRServReq *langReq, void *langEnv );
  15.113 +
  15.114 +void inline
  15.115 +handleThrowException( PRServReq *langReq, void *langEnv );
  15.116 +//=======================================================================
  15.117 +
  15.118 +//========================= Services =======================
  15.119 +//#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
  15.120 +//#include  "Services_Offered_by_PR/Services_Language/PRServ.h"
  15.121 +//#include  "Services_Offered_by_PR/Services_Language/libPRServ.h"
  15.122 +
  15.123 +//================================================
  15.124 +#endif	/* _PR_H */
  15.125 +
    16.1 --- a/PR__int.c	Sun Nov 04 18:39:28 2012 -0800
    16.2 +++ b/PR__int.c	Mon Jan 14 15:31:23 2013 -0800
    16.3 @@ -1,5 +1,5 @@
    16.4  /*
    16.5 - * Copyright 2010  OpenSourceStewardshipFoundation
    16.6 + * Copyright 2010  OpenSourceResearchInstitute
    16.7   *
    16.8   * Licensed under BSD
    16.9   */
   16.10 @@ -25,48 +25,26 @@
   16.11  //===========================================================================
   16.12  //
   16.13  //===========================================================================
   16.14 -
   16.15 -inline SlaveVP *
   16.16 -PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process )
   16.17 +inline
   16.18 +SlaveVP *
   16.19 +PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam )
   16.20   { SlaveVP *newSlv;
   16.21     void    *stackLocs;
   16.22 -
   16.23 -   PR_int__create_slaveVP_helper( fnPtr, dataParam );
   16.24 -           
   16.25 -   process->numLiveGenericSlvs += 1;
   16.26 -
   16.27 -//   newSlv->needsTaskAssigned   = TRUE;
   16.28 -   newSlv->metaTask            = NULL;
   16.29 -   newSlv->typeOfVP            = GenericSlave;
   16.30     
   16.31 -   return newSlv;
   16.32 - }
   16.33 -
   16.34 -
   16.35 -inline SlaveVP *
   16.36 -PR_int__create_slaveVP_helper( TopLevelFnPtr fnPtr, void *dataParam )
   16.37 - { SlaveVP *newSlv;
   16.38 -   void    *stackLocs;
   16.39 -
   16.40     newSlv      = PR_int__malloc( sizeof(SlaveVP) );
   16.41     stackLocs   = PR_int__malloc( VIRT_PROCR_STACK_SIZE );
   16.42     if( stackLocs == 0 )
   16.43      { perror("PR_int__malloc stack"); exit(1); }
   16.44  
   16.45     newSlv->startOfStack = stackLocs;
   16.46 -   newSlv->slaveID      = _PRTopEnv->numSlavesCreated++;
   16.47 +   newSlv->slaveNum     = _PRTopEnv->numSlavesCreated++;
   16.48     newSlv->request      = NULL;
   16.49     newSlv->animSlotAssignedTo = NULL;
   16.50        
   16.51     newSlv->numTimesAssignedToASlot  = 0;  
   16.52  
   16.53 -   #ifdef MODE__MULTI_LANG
   16.54 -   PRSemDataHolder *
   16.55 -   semDataHolder = PR_int__malloc( sizeof(PRSemDataHolder) );
   16.56 -   newSlv->semanticData = semDataHolder;
   16.57 -   #else
   16.58 -   newSlv->semanticData = NULL;
   16.59 -   #endif
   16.60 +   newSlv->langData = NULL;
   16.61 +   newSlv->metaTask     = NULL;
   16.62  
   16.63     PR_int__reset_slaveVP_to_TopLvlFn( newSlv, fnPtr, dataParam );
   16.64     
   16.65 @@ -80,13 +58,138 @@
   16.66     #endif
   16.67     //========================================================================
   16.68  
   16.69 +   newSlv->typeOfVP            = GenericSlave;
   16.70 +   
   16.71     return newSlv;
   16.72   }
   16.73  
   16.74 +inline
   16.75  SlaveVP *
   16.76 -PR_int__create_slot_slave()
   16.77 - { 
   16.78 -    fixme;
   16.79 +PR_int__create_slaveVP__ML( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process )
   16.80 + { SlaveVP *newSlv;
   16.81 + 
   16.82 +   newSlv = PR_int__create_slaveVP( fnPtr, dataParam );
   16.83 +      
   16.84 +   int32 *
   16.85 +   langDatas    = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRLangData *) );
   16.86 +   langDatas[0] = NUM_IN_COLLECTION;    //size held in prolog
   16.87 +   newSlv->langData = &(langDatas[1]); //skip over the size
   16.88 +           
   16.89 +   int32 *
   16.90 +   metaTasks    = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRMetaTask *) );
   16.91 +   metaTasks[0] = NUM_IN_COLLECTION;    //size held in prolog
   16.92 +   newSlv->metaTask = &(metaTasks[1]);
   16.93 +   
   16.94 +   process->numLiveGenericSlvs += 1;
   16.95 + }
   16.96 +
   16.97 +
   16.98 +/*
   16.99 + */
  16.100 +/*
  16.101 +inline
  16.102 +SlaveVP *
  16.103 +PR_int__create_seed_slave__ML( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process )
  16.104 + { SlaveVP *newSlv;
  16.105 + 
  16.106 +   newSlv = PR_int__create_slaveVP( fnPtr, dataParam );
  16.107 +      
  16.108 +   int32 *
  16.109 +   langDatas    = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRLangData *) );
  16.110 +   langDatas[0] = NUM_IN_COLLECTION;       //size held in prolog
  16.111 +   newSlv->langData = &(langDatas[1]); //skip over the size
  16.112 +           
  16.113 +   int32 *
  16.114 +   metaTasks    = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRMetaTask *) );
  16.115 +   metaTasks[0] = NUM_IN_COLLECTION;    //size held in prolog
  16.116 +   newSlv->metaTask = &(metaTasks[1]);  //make slave point to array
  16.117 +   
  16.118 +   newSlv->typeOfVP            = SeedSlv;
  16.119 +   process->numLiveGenericSlvs = 1;
  16.120 + }
  16.121 +*/
  16.122 +
  16.123 +
  16.124 +/*Called when a new slot slave is needed..  takes from recycle pool, and 
  16.125 + * sets the slave up to be a slot slave -- no lang data array, no meta task 
  16.126 + * array.  
  16.127 + */
  16.128 +SlaveVP *
  16.129 +PR_int__get_recycled_slot_slave( )
  16.130 + { SlaveVP *retSlv;
  16.131 + 
  16.132 +      //take slave from recycle Q
  16.133 +   retSlv = readPrivQ( _PRTopEnv->slaveRecycleQ );
  16.134 + 
  16.135 +   if( retSlv != NULL ) 
  16.136 +    {
  16.137 +      //set slave up with slot-slave's initial values.
  16.138 +      retSlv->typeOfVP     = SlotTaskSlv;
  16.139 +      retSlv->slaveNum     = _PRTopEnv->numSlavesCreated++;
  16.140 +      retSlv->numTimesAssignedToASlot  = 0;
  16.141 +      retSlv->request      = NULL;
  16.142 +    }
  16.143 +   else //if none to recycle, create a new one
  16.144 +    { retSlv = PR_int__create_slaveVP_helper( &idle_fn, NULL );
  16.145 +      retSlv->typeOfVP     = SlotTaskSlv; 
  16.146 +    }
  16.147 +   
  16.148 +   return retSlv;
  16.149 + }
  16.150 +
  16.151 +/*A slot slave has no array for lang data nor meta tasks -- it only ever has
  16.152 + * one meta task..
  16.153 + */
  16.154 +SlaveVP *
  16.155 +PR_int__create_slot_slave( )
  16.156 + { SlaveVP *retSlv;
  16.157 + 
  16.158 +    retSlv = PR_int__create_slaveVP_helper( &idle_fn, NULL );
  16.159 +    retSlv->typeOfVP     = SlotTaskSlv; 
  16.160 +   
  16.161 +   return retSlv;
  16.162 + }
  16.163 +
  16.164 +//==========================================================================
  16.165 +/*When a task in a slot slave suspends, the slot slave has to be changed to
  16.166 + * a free task slave, then the slot slave replaced.  The replacement can be
  16.167 + * either a recycled free task slave that finished it's task and has been
  16.168 + * idle in the recycle queue, or else create a new slave to be the slot slave.
  16.169 + *The master only calls this with a slot slave that needs to be replaced.
  16.170 + */
  16.171 +inline void
  16.172 +PR_int__replace_with_new_slot_slv( SlaveVP *requestingSlv, PRProcess *process )
  16.173 + { SlaveVP *newSlotSlv;
  16.174 +
  16.175 +      //get a new slave to be the slot slave
  16.176 +   newSlotSlv  = PR_int__get_recycled_slot_slave( process );
  16.177 +   
  16.178 +      //a slot slave is pinned to a particular slot on a particular core
  16.179 +      //Note, this happens before the request is seen by handler, so nothing
  16.180 +      // has had a chance to change the coreAnimatedBy or anything else..
  16.181 +   newSlotSlv->animSlotAssignedTo = requestingSlv->animSlotAssignedTo;
  16.182 +   newSlotSlv->coreAnimatedBy     = requestingSlv->coreAnimatedBy;
  16.183 +    
  16.184 +      //put it into the slot slave matrix
  16.185 +   int32 slotNum = requestingSlv->animSlotAssignedTo->slotIdx;
  16.186 +   int32 coreNum = requestingSlv->coreAnimatedBy;
  16.187 +   _PRTopEnv->slotTaskSlvs[coreNum][slotNum] = newSlotSlv;
  16.188 +
  16.189 +      //Fix up requester, to be an extra slave now (but not an ended one)
  16.190 +      // because it's active, doesn't go into freeTaskSlvRecycleQ
  16.191 +   requestingSlv->typeOfVP = FreeTaskSlv;
  16.192 +   requestingSlv->processSlaveIsIn = process;
  16.193 +   
  16.194 +   
  16.195 +   int32 *
  16.196 +   langDatas    = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRLangData *) );
  16.197 +   langDatas[0] = NUM_IN_COLLECTION;    //size held in prolog
  16.198 +   newSlotSlv->langData = &(langDatas[1]); //skip over the size
  16.199 +           
  16.200 +   int32 *
  16.201 +   metaTasks    = PR_int__malloc( sizeof(int32) + NUM_IN_COLLECTION * sizeof(PRMetaTask *) );
  16.202 +   metaTasks[0] = NUM_IN_COLLECTION;    //size held in prolog
  16.203 +   newSlotSlv->metaTask = &(metaTasks[1]);
  16.204   }
  16.205  
  16.206  void idle_fn(void* data, SlaveVP *animatingSlv)
  16.207 @@ -97,47 +200,6 @@
  16.208   }
  16.209  
  16.210  
  16.211 -PRMetaTask *
  16.212 -PR_int__create_generic_slave_meta_task( void *initData )
  16.213 - { PRMetaTask *newStub;
  16.214 -         
  16.215 -   newStub = PR_PI__malloc( sizeof(PRMetaTask) );
  16.216 -   newStub->slaveAssignedTo = NULL; //set later
  16.217 -   newStub->taskType        = IS_A_GENERIC_SLV;
  16.218 -   newStub->taskID          = NULL;
  16.219 -
  16.220 -   return newStub;
  16.221 - }
  16.222 -
  16.223 -/*This calls recycle handler registered for each langlet's sem data and meta
  16.224 - * task.  It also recycles the slave struct.
  16.225 - * 
  16.226 - *This assumes that each slave has an array of 
  16.227 - */
  16.228 -void
  16.229 -PR_int__recycle_slave_multilang( SlaveVP *slave )
  16.230 - { int32 semDataIdx, numSemDatas;
  16.231 -   PRSemDataHolder *semDataHolder;
  16.232 -   PRSemData  *protoSemData, **semDatas;
  16.233 - 
  16.234 -   semDataHolder = (PRSemDataHolder *)slave->semanticData;
  16.235 -   semDatas = semDataHolder->semDatasIter;
  16.236 -   
  16.237 -   for( semDataIdx = 0; semDataIdx < numSemDatas; semDataIdx++ )
  16.238 -    { protoSemData = semDatas[ semDataIdx ];
  16.239 -      //instead of looking up the semEnv, just put ptr to recycler in protoSemData
  16.240 -      //To get by without, must iter through hash table..
  16.241 -      (*protoSemData->recycler)(protoSemData->langSemData);
  16.242 -    }
  16.243 -   for( metaTaskIdx = 0; metaTaskIdx < numMetaTasks; metaTaskIdx++ )
  16.244 -    { protoMetaTask = metaTasks[ metaTaskIdx ];
  16.245 -      //instead of looking up the semEnv, just put ptr to recycler in protoSemData
  16.246 -      (*protoMetaTask->recycler)(protoMetaTask->langMetaTask);
  16.247 -    }
  16.248 -   
  16.249 -   writePrivQ( slave, slave->processSlaveIsIn->freeTaskSlvRecycleQ );
  16.250 - }
  16.251 -
  16.252  
  16.253  /* This is for OS requests and PR infrastructure requests, such as to create
  16.254   *  a probe -- a probe is inside the heart of PR-core, it's not part of any
  16.255 @@ -145,26 +207,27 @@
  16.256   *  in the application.. so it crosses abstractions..  so, need some special
  16.257   *  pattern here for handling such requests.
  16.258   * Doing this just like it were a second language sharing PR-core.
  16.259 - * 
  16.260 - * This is called from the language's request handler when it sees a request
  16.261 - *  of type PRSemReq
  16.262 - *
  16.263 - * TODO: Later change this, to give probes their own separate plugin & have
  16.264 - *  PR-core steer the request to appropriate plugin
  16.265 - * Do the same for OS calls -- look later at it..
  16.266   */
  16.267  void inline
  16.268 -PR_int__handle_PRServiceReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv,
  16.269 -                       ResumeSlvFnPtr resumeFn )
  16.270 - { PRServReq *semReq;
  16.271 +PR_int__handle_PRServiceReq( SlaveVP *requestingSlv )
  16.272 + { PRReqst   *req;
  16.273 +   PRServReq *langReq;
  16.274 +   void      *langEnv;
  16.275 +   int32      magicNumber;
  16.276 +   
  16.277 + 
  16.278 +   req = requestingSlv->request;
  16.279 + 
  16.280 +   magicNumber = req->langMagicNumber;
  16.281 +   langEnv = PR_PI__give_lang_env_for( slave, magicNumber );
  16.282  
  16.283 -   semReq = PR_PI__take_sem_reqst_from(req);
  16.284 -   if( semReq == NULL ) return;
  16.285 -   switch( semReq->reqType )  //sem handlers are all in other file
  16.286 +   langReq = PR_PI__take_lang_reqst_from(req);
  16.287 +   if( langReq == NULL ) return;
  16.288 +   switch( langReq->reqType )  //lang handlers are all in other file
  16.289      {
  16.290 -      case make_probe:      handleMakeProbe(   semReq, semEnv, resumeFn);
  16.291 +      case make_probe:      handleMakeProbe(   langReq, langEnv );
  16.292           break;
  16.293 -      case throw_excp:  handleThrowException(  semReq, semEnv, resumeFn);
  16.294 +      case throw_excp:  handleThrowException(  langReq, langEnv );
  16.295           break;
  16.296      }
  16.297   }
  16.298 @@ -189,7 +252,7 @@
  16.299        //return ownership of the Slv and anim slot to Master virt pr
  16.300     animatingSlv->animSlotAssignedTo->workIsDone = TRUE;
  16.301  
  16.302 -        HOLISTIC__Record_HwResponderInvocation_start;
  16.303 +         HOLISTIC__Record_HwResponderInvocation_start;
  16.304           MEAS__Capture_Pre_Susp_Point;
  16.305        //This assembly function is a PR primitive that first saves the
  16.306        // stack and frame pointer, plus an addr inside this assembly code.
  16.307 @@ -226,9 +289,9 @@
  16.308   * of dis-owning it.
  16.309   */
  16.310  void
  16.311 -PR_int__dissipate_slaveVP( SlaveVP *animatingSlv )
  16.312 +PR_int__dissipate_slaveVP__SL( SlaveVP *animatingSlv )
  16.313   {
  16.314 -         DEBUG__printf2(dbgRqstHdlr, "PR int dissipate slaveID: %d, alive: %d",animatingSlv->slaveID, _PRTopEnv->numSlavesAlive-1);
  16.315 +         DEBUG__printf2(dbgRqstHdlr, "PR int dissipate slaveNum: %d, alive: %d",animatingSlv->slaveNum, _PRTopEnv->numSlavesAlive-1);
  16.316        //dis-own all locations owned by this processor, causing to be freed
  16.317        // any locations that it is (was) sole owner of
  16.318     _PRTopEnv->numSlavesAlive -= 1;
  16.319 @@ -247,116 +310,466 @@
  16.320     PR_int__free( animatingSlv );
  16.321   }
  16.322  
  16.323 -/*In multi-lang mode, there are multiple semData in the slave..  
  16.324 +
  16.325 +/*In multi-lang mode, there are multiple langData in the slave..  
  16.326   * 
  16.327   *At some point want to recycle rather than free..
  16.328   * 
  16.329 - *For now, iterate through semData, call registered free-er on each, then
  16.330 + *For now, iterate through langData, call registered free-er on each, then
  16.331   * free the basic slave
  16.332   */
  16.333  void
  16.334 -PR_int__dissipate_slaveVP_multilang( SlaveVP *slave )
  16.335 - { PRSemDataHolder   *semDataHolder;
  16.336 -   PRSemDataTemplate *semData;
  16.337 -   int32              idx;
  16.338 +PR_int__free_slaveVP__ML( SlaveVP *slave )
  16.339 + {       
  16.340 +   PR_int__apply_Fn_to_all_in_collection( &recycleLangDataAsElem, 
  16.341 +                                           (PRCollElem**) slave->langData );
  16.342 +   PR_int__apply_Fn_to_all_in_collection( &recycleMetaTaskAsElem, 
  16.343 +                                           (PRCollElem**) slave->metaTask );
  16.344     
  16.345 -   semDataHolder = (PRSemDataHolder *)slave->semanticData;
  16.346 -   for(idx = 0; idx < semDataHolder->numSemDatas; idx++)
  16.347 -    { 
  16.348 -      semData = semDataHolder->semDatas[idx];
  16.349 -      (*(semData->freeFn))(semData); //this Fn is lang-spec 
  16.350 -    }
  16.351 -   
  16.352 +   PR_int__free( &(((int32*)(slave->langData))[-1]) );
  16.353 +   PR_int__free( &(((int32*)(slave->metaTask))[-1]) );
  16.354     PR_int__free( slave->startOfStack );
  16.355     PR_int__free( slave );   
  16.356   }
  16.357  
  16.358 -inline
  16.359 -void *
  16.360 -PR_int__give_sem_env_of_req( PRReqst *req, SlaveVP *requestingSlv )
  16.361 - {     
  16.362 -   return PR_int__give_sem_env_for_process( requestingSlv->processSlaveIsIn, 
  16.363 -                                                         req->langMagicNumber );
  16.364 +/*This calls recycle handler registered for each langlet's lang data and meta
  16.365 + * task.  It also recycles the slave struct.
  16.366 + * 
  16.367 + *This assumes that each slave has an array of 
  16.368 + */
  16.369 +void
  16.370 +PR_int__recycle_slave__ML( SlaveVP *slave )
  16.371 + { 
  16.372 +   PR_int__apply_Fn_to_all_in_collection( &recycleLangDataAsElem, 
  16.373 +                                           (PRCollElem**) slave->langData );
  16.374 +   PR_int__apply_Fn_to_all_in_collection( &recycleMetaTaskAsElem, 
  16.375 +                                           (PRCollElem**) slave->metaTask );
  16.376 +
  16.377 +   writePrivQ( slave, _PRTopEnv->slaveRecycleQ );
  16.378   }
  16.379  
  16.380 -/*Anticipating multi-tasking
  16.381 - */
  16.382 -inline
  16.383 +void
  16.384 +recycleLangDataAsElem( void *elem )
  16.385 + { PRLangData *langData;
  16.386 +   
  16.387 +   langData = (PRLangData *)elem; //recycler receives the prolog, and must call
  16.388 +   //a PR Fn to convert prolog to lang-specific version.
  16.389 +   
  16.390 +      //apply the recycle fn that's stored in the lang data prolog
  16.391 +   (*(langData->recycler))(langData); //lang registered the recycler    
  16.392 + }
  16.393 +
  16.394 +void
  16.395 +recycleMetaTaskAsElem( void *elem )
  16.396 + { PRMetaTask *metaTask;
  16.397 +   
  16.398 +   metaTask = (PRMetaTask *)elem;  //recycler receives the prolog, and must call
  16.399 +   //a PR Fn to convert prolog to lang-specific version.
  16.400 +   
  16.401 +      //apply the recycle fn that's stored in the lang data prolog
  16.402 +   (*(metaTask->recycler))(metaTask); //lang registered the recycler    
  16.403 + }
  16.404 +
  16.405 +
  16.406 +
  16.407 +//======================================
  16.408 +inline 
  16.409  void *
  16.410 -PR_int__give_sem_env_for_slave( SlaveVP *slave, int32 magicNum )
  16.411 - {    
  16.412 -   return PR_int__give_sem_env_for_process( slave->processSlaveIsIn, magicNum );
  16.413 +PR_int__give_lang_env( PRLangEnv *protoLangEnv )
  16.414 + {
  16.415 +    return (void *) &(protoLangEnv[1]);
  16.416   }
  16.417 -inline
  16.418 -PRSemEnv *
  16.419 -PR_int__give_proto_sem_env_for_slave( SlaveVP *slave, int32 magicNum )
  16.420 - {    
  16.421 -   return PR_int__give_proto_sem_env_for_process( slave->processSlaveIsIn, magicNum );
  16.422 +inline 
  16.423 +PRLangEnv *
  16.424 +PR_int__give_proto_lang_env( void *langEnv )
  16.425 + {
  16.426 +   return (PRLangEnv *) &(((PRLangEnv *)langEnv)[-1]);
  16.427   }
  16.428  
  16.429  inline
  16.430  void *
  16.431 -PR_int__give_sem_env_for_process( PRProcess *process, int32 magicNum )
  16.432 - { PRSemEnv *protoSemEnv;
  16.433 -
  16.434 -   protoSemEnv = lookup_proto_sem_env_in_array( process->semEnvs, magicNum );
  16.435 -   return protoSemEnv->langSemEnv;
  16.436 - }
  16.437 -inline
  16.438 -PRSemEnv *
  16.439 -PR_int__give_proto_sem_env_for_process( PRProcess *process, int32 magicNum )
  16.440 - { 
  16.441 -   return lookup_proto_sem_env_in_array( process->semEnvs, magicNum );
  16.442 +PR_int__create_lang_env_in_process( int32 size, PRProcess process, int32 magicNum )
  16.443 + { PRLangEnv *retEnv;
  16.444 +   PRCollElem **langEnvs;
  16.445 +   
  16.446 +      //make the new lang env, with room for the prolog
  16.447 +   retEnv = PR_int__malloc( sizeof(PRLangEnv) + size );
  16.448 +   
  16.449 +      //process has a PR Collection of lang envs -- get it and insert into it
  16.450 +   langEnvs = (PRCollElem **)process->langEnvs;
  16.451 +   PR_int__insert_elem_into_collection( (PRCollElem *)retEnv, langEnvs, magicNum);
  16.452 +   int32 idxInProcess = process->numLangEnvs;
  16.453 +   process->langEnvsList[idxInProcess] = retEnv;
  16.454 +   retEnv->idxInProcess = idxInProcess;
  16.455 +   process->numLangEnvs += 1;
  16.456 +   
  16.457 +   return &(retEnv[1]); //skip over prolog
  16.458   }
  16.459  
  16.460  inline
  16.461 -PRSemEnv *
  16.462 -lookup_proto_sem_env_in_array( PRSemEnv *semEnvs, int32 magicNum )
  16.463 - { PRSemEnv *retEnv;
  16.464 -   int32 idx;
  16.465 +void *
  16.466 +PR_int__free_lang_env( void *langEnv )
  16.467 + { PRLangEnv   *protoLangEnv = PR_int__give_proto_lang_env( langEnv );
  16.468 +   PRCollElem **langEnvs;
  16.469 +   PRLangEnv  **langEnvsList;
  16.470 +   
  16.471 +      //process has a PR Collection of lang envs -- get it and remove env
  16.472 +   PRProcess *process = protoLangEnv->processEnvIsIn;
  16.473 +   langEnvs = (PRCollElem **)process->langEnvs;
  16.474 +   PR_int__remove_elem_from_collection( (PRCollElem *)protoLangEnv, langEnvs );
  16.475 +   int32 count, idx;
  16.476 +   idx = protoLangEnv->idxInProcess;
  16.477 +   count = (process->numLangEnvs - idx - 1) * sizeof(PRLangEnv *);
  16.478 +   memmove( langEnvsList[idx], langEnvsList[idx+1], count);
  16.479 +   
  16.480 +   PR_int__free( protoLangEnv );
  16.481 + }
  16.482 +
  16.483 +inline
  16.484 +void *
  16.485 +PR_int__give_lang_env_of_req__ML( PRReqst *req, SlaveVP *requestingSlv )
  16.486 + {     
  16.487 +   return PR_int__give_lang_env_from_process( requestingSlv->processSlaveIsIn, 
  16.488 +                                                         req->langMagicNumber );
  16.489 + }
  16.490 +
  16.491 +inline
  16.492 +void *
  16.493 +PR_int__give_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNum )
  16.494 + {    
  16.495 +   return PR_int__give_lang_env_from_process( slave->processSlaveIsIn, magicNum );
  16.496 + }
  16.497 +inline
  16.498 +PRLangEnv *
  16.499 +PR_int__give_proto_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNum )
  16.500 + {    
  16.501 +   return PR_int__give_proto_lang_env_for_process( slave->processSlaveIsIn, magicNum );
  16.502 + }
  16.503 +
  16.504 +inline
  16.505 +void *
  16.506 +PR_int__give_lang_env_from_process( PRProcess *process, int32 magicNum )
  16.507 + { PRLangEnv    *retLangEnv;
  16.508 +   PRCollElem **langEnvs;
  16.509 +   
  16.510 +   langEnvs = (PRCollElem **)process->langEnvs;
  16.511 +   retLangEnv = PR_int__lookup_elem_in_collection( magicNum, langEnvs );
  16.512 +   if( retLangEnv != NULL ) 
  16.513 +      return &(retLangEnv[1]); //skip over prolog
  16.514 +   else
  16.515 +      return NULL;
  16.516 + }
  16.517 +inline
  16.518 +PRLangEnv *
  16.519 +PR_int__give_proto_lang_env_for_process( PRProcess *process, int32 magicNum )
  16.520 + { PRLangEnv    *retLangEnv;
  16.521 +   PRCollElem **langEnvs;
  16.522 +   
  16.523 +   langEnvs = (PRCollElem **)process->langEnvs;
  16.524 +   retLangEnv = PR_int__lookup_elem_in_collection( magicNum, langEnvs );
  16.525 +   return retLangEnv; //return prolog
  16.526 + }
  16.527 +
  16.528 +inline
  16.529 +void
  16.530 +PR_int__set_work_in_lang_env( void *_langEnv )
  16.531 + { PRLangEnv *protoLangEnv = &(((PRLangEnv *)_langEnv)[-1]); //go to the prolog
  16.532 +   if( protoLangEnv->hasWork != TRUE ) 
  16.533 +    { protoLangEnv->hasWork = TRUE;
  16.534 +      protoLangEnv->processEnvIsIn->numEnvsWithWork += 1;
  16.535 +    }
  16.536 + }
  16.537 +inline
  16.538 +void
  16.539 +PR_int__clear_work_in_lang_env( void *_langEnv )
  16.540 + { PRLangEnv *prototLangEnv = &(((PRLangEnv *)_langEnv)[-1]); //back up addr to the prolog
  16.541 +   
  16.542 +   if( prototLangEnv->hasWork != FALSE ) 
  16.543 +    { prototLangEnv->hasWork = FALSE;
  16.544 +      prototLangEnv->processEnvIsIn->numEnvsWithWork -= 1;
  16.545 +    }
  16.546 + }
  16.547 +
  16.548 +/*This is to be called by langlet's assigner.
  16.549 + */
  16.550 +inline
  16.551 +void
  16.552 +PR_int__put_slave_into_slot( SlaveVP *slave, AnimSlot *slot )
  16.553 + {
  16.554 +   slave->coreAnimatedBy   = slot->coreSlotIsOn;
  16.555 +               //if work found, put into slot, and adjust flags and state
  16.556 +   slot->slaveAssignedToSlot = slave;
  16.557 +   slave->animSlotAssignedTo = slot;
  16.558 +   slot->needsWorkAssigned  = FALSE;
  16.559 +
  16.560 +  #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
  16.561 +      //have a slave to be assigned to the slot
  16.562 +      //assignSlv->numTimesAssigned++;
  16.563 +         //get previous occupant of the slot
  16.564 +      PRProcess *process = slave->processSlaveIsIn;
  16.565 +      int32 coreNum = slot->coreSlotIsOn;
  16.566 +      int32 slotNum = slot->slotIdx;
  16.567 +      Unit prev_in_slot = 
  16.568 +         process->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum];
  16.569 +      if(prev_in_slot.vp != 0) //if not first slave in slot, make dependency
  16.570 +       { Dependency newD;      // is a hardware dependency
  16.571 +         newD.from_vp = prev_in_slot.vp;
  16.572 +         newD.from_task = prev_in_slot.task;
  16.573 +         newD.to_vp = slave->slaveNum;
  16.574 +         newD.to_task = slave->numTimesAssignedToASlot;
  16.575 +         addToListOfArrays(Dependency,newD,process->hwArcs);   
  16.576 +       }
  16.577 +      prev_in_slot.vp = slave->slaveNum; //make new slave the new previous
  16.578 +      prev_in_slot.task = slave->numTimesAssignedToASlot;
  16.579 +      process->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] =
  16.580 +         prev_in_slot;        
  16.581 +    
  16.582 +  #endif
  16.583 + }
  16.584 +
  16.585 +
  16.586 +/*This is to be called by langlet's assigner
  16.587 + */
  16.588 +inline
  16.589 +void
  16.590 +PR_int__put_task_into_slot( PRMetaTask *task, PRProcess *process, AnimSlot *slot )
  16.591 + { int32 slotNum, coreNum;
  16.592 +   SlaveVP *slotSlv;
  16.593   
  16.594 -   idx = magicNum & 63; //mask off, leaving lowest 6 bits
  16.595 -   retEnv =  &(semEnvs[idx]); //is array of structs, so take addr
  16.596 -   while( retEnv->langMagicNumber != magicNum ) //assume magicNums unique
  16.597 -    { retEnv = retEnv->chainedSemEnv;
  16.598 -      if( retEnv == NULL ) goto NotFound;
  16.599 +      //get the slot slave to assign the task to..
  16.600 +   slotNum = slot->slotIdx;
  16.601 +   coreNum = slot->coreSlotIsOn;
  16.602 +   slotSlv = _PRTopEnv->slotTaskSlvs[coreNum][slotNum];
  16.603 +
  16.604 +     //point slave to task's function
  16.605 +   PR_int__reset_slaveVP_to_TopLvlFn( slotSlv, task->topLevelFn, task->initData );
  16.606 +   PR_int__insert_meta_task_into_slave__ML( task, slotSlv );
  16.607 +   PR_int__put_slave_into_slot( slotSlv, slot );
  16.608 + }
  16.609 +
  16.610 +//==========================
  16.611 +inline 
  16.612 +PRMetaTask *
  16.613 +PR_int__give_prolog_of_task( void *task )
  16.614 + {
  16.615 +    return (PRMetaTask *) &(((PRMetaTask *)task)[-1]);
  16.616 + }
  16.617 +
  16.618 +inline
  16.619 +void *
  16.620 +PR_int__give_lang_meta_task_of_prolog( PRMetaTask *metaTask)
  16.621 + {
  16.622 +   return (void *)&(metaTask[1]);
  16.623 + }
  16.624 +
  16.625 +
  16.626 +inline
  16.627 +void *
  16.628 +PR_int__create_lang_meta_task__ML( int32 size, int32 magicNum )
  16.629 + { PRMetaTask *retMetaTask;
  16.630 +
  16.631 +      //make the new meta task
  16.632 +   retMetaTask = PR_int__malloc( sizeof(PRMetaTask) + size );
  16.633 +   retMetaTask->chainedMetaTask = NULL;
  16.634 +   retMetaTask->langMagicNumber = magicNum;
  16.635 +   retMetaTask->slaveAssignedTo = NULL;
  16.636 +   retMetaTask->taskType        = SlotTask;
  16.637 +   retMetaTask->ID              = NULL;
  16.638 +     
  16.639 +   return &(retMetaTask[1]); //skip over prolog
  16.640 + }
  16.641 +
  16.642 +/*allocates space for a new lang-meta-task, and inserts it into the slave,
  16.643 + * under the given magic number.
  16.644 + */
  16.645 +inline
  16.646 +void *
  16.647 +PR_int__create_lang_meta_task_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum )
  16.648 + { PRMetaTask *retMetaTask;
  16.649 +   PRCollElem **metaTasks;
  16.650 +
  16.651 +      //make the new meta task
  16.652 +   retMetaTask = PR_int__malloc( sizeof(PRMetaTask) + size );
  16.653 +   retMetaTask->chainedMetaTask = NULL;
  16.654 +   retMetaTask->langMagicNumber = magicNum;
  16.655 +   retMetaTask->slaveAssignedTo = slave;
  16.656 +   retMetaTask->taskType        = GenericSlave;
  16.657 +   retMetaTask->ID              = NULL;
  16.658 +
  16.659 +      //multilang has a "collection" of meta tasks inside the slave
  16.660 +   metaTasks = (PRCollElem **)slave->metaTask; 
  16.661 +   PR_int__insert_elem_into_collection( (PRCollElem *)retMetaTask, 
  16.662 +                                                          metaTasks, magicNum );
  16.663 +   
  16.664 +   return &(retMetaTask[1]); //skip over prolog
  16.665 + }
  16.666 +
  16.667 +inline
  16.668 +void
  16.669 +PR_int__insert_meta_task_into_slave__ML( PRMetaTask *task, SlaveVP *slave )
  16.670 + { 
  16.671 +   task->slaveAssignedTo = slave;
  16.672 +   PR_int__insert_elem_into_collection( (PRCollElem *)task, 
  16.673 +                        (PRCollElem **)slave->metaTask, task->langMagicNumber );
  16.674 + }
  16.675 +inline
  16.676 +void
  16.677 +PR_int__insert_lang_meta_task_into_slave__ML( void *langMetaTask, SlaveVP *slave )
  16.678 + { PRMetaTask *metaTask = &(((PRMetaTask*)langMetaTask)[-1]);
  16.679 +   metaTask->slaveAssignedTo = slave;
  16.680 +   PR_int__insert_elem_into_collection( (PRCollElem *)metaTask, 
  16.681 +                    (PRCollElem **)slave->metaTask, metaTask->langMagicNumber );
  16.682 + }
  16.683 +
  16.684 +inline
  16.685 +void *
  16.686 +PR_int__give_lang_meta_task_from_slave__ML( SlaveVP *slave, int32 magicNum )
  16.687 + { PRMetaTask  *retMetaTask;
  16.688 +   PRCollElem **metaTasks;
  16.689 +   
  16.690 +   metaTasks = (PRCollElem **)slave->metaTask;
  16.691 +   retMetaTask = PR_int__lookup_elem_in_collection( magicNum, metaTasks );
  16.692 +   if( retMetaTask != NULL ) 
  16.693 +      return &(retMetaTask[1]); //skip over prolog
  16.694 +   else
  16.695 +      return NULL;
  16.696 + }
  16.697 +
  16.698 +inline
  16.699 +SlaveVP *
  16.700 +PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask )
  16.701 + { PRMetaTask *metaTask = &(((PRMetaTask*)langMetaTask)[-1]);
  16.702 +   return metaTask->slaveAssignedTo;
  16.703 + }
  16.704 +
  16.705 +//===============================================
  16.706 +/*Allocates space for a new lang-lang-data, and inserts it into the slave,
  16.707 + * under the given magic number.  Also returns it.
  16.708 + */
  16.709 +inline
  16.710 +void *
  16.711 +PR_int__create_lang_data_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum )
  16.712 + { PRLangData   *retLangData;
  16.713 +   PRCollElem **langDatas;
  16.714 +
  16.715 +      //make the new lang Data
  16.716 +   retLangData = PR_int__malloc( sizeof(PRLangData) + size );
  16.717 +   retLangData->chainedLangData = NULL;
  16.718 +   retLangData->langMagicNumber = magicNum;
  16.719 +  
  16.720 +      //multilang has a "collection" of lang datas inside the slave
  16.721 +   langDatas = (PRCollElem **)slave->langData; 
  16.722 +   PR_int__insert_elem_into_collection( (PRCollElem *)retLangData, langDatas, magicNum );
  16.723 +   
  16.724 +   return &(retLangData[1]); //skip over prolog
  16.725 + }
  16.726 +
  16.727 +inline
  16.728 +void *
  16.729 +PR_int__give_lang_data_from_slave__ML( SlaveVP *slave, int32 magicNum )
  16.730 + { PRLangData   *retLangData;
  16.731 +   PRCollElem **langDatas;
  16.732 +   
  16.733 +   langDatas = (PRCollElem **)slave->langData;
  16.734 +   retLangData = PR_int__lookup_elem_in_collection( magicNum, langDatas );
  16.735 +   if( retLangData != NULL ) 
  16.736 +      return &(retLangData[1]); //skip over prolog
  16.737 +   else
  16.738 +      return NULL;
  16.739 + }
  16.740 +
  16.741 +
  16.742 +//===============================================
  16.743 +inline
  16.744 +void
  16.745 +PR_int__insert_elem_into_collection( PRCollElem *elem, PRCollElem **coll, int32 hash )
  16.746 + { int32 idx, numIdxsInColl;
  16.747 +   PRCollElem *test;
  16.748 +
  16.749 +   numIdxsInColl = ((int32 *)coll)[-1]; //prolog holds number of idexes in array
  16.750 +
  16.751 +      //figure out where to link in
  16.752 +   idx = hash & (numIdxsInColl - 1); //mask off, leaving lowest bits
  16.753 +   test = coll[idx];
  16.754 +   elem->chained = NULL; //elem goes at end of any chain, so just being sure here
  16.755 +   if( test == NULL ) //spot empty, so add there
  16.756 +    {    //add to the array
  16.757 +      coll[idx] = elem;
  16.758      }
  16.759 -   return retEnv;
  16.760 +   else //collision -- look for last in chain, then add there
  16.761 +    { while( test->chained != NULL ) 
  16.762 +       { test = test->chained;
  16.763 +       }
  16.764 +         //add new to the end of chain
  16.765 +      test->chained = elem;
  16.766 +    }
  16.767 + }
  16.768 +
  16.769 +inline
  16.770 +void *
  16.771 +PR_int__lookup_elem_in_collection( int32 hash, PRCollElem **coll )
  16.772 + { int32 idx, numIdxsInColl;
  16.773 +   PRCollElem *test;
  16.774 +
  16.775 +   numIdxsInColl = ((int32 *)coll)[-1]; //prolog holds number of indexes in array
  16.776 +
  16.777 +   idx = hash & (numIdxsInColl - 1); //mask off, leaving lowest bits
  16.778 +   test = coll[idx];
  16.779 +   if( test == NULL ) goto NotFound;
  16.780 +   while( test->hash != hash )
  16.781 +    { test = test->chained;
  16.782 +      if( test == NULL ) goto NotFound;
  16.783 +    }
  16.784 +   return test;
  16.785     
  16.786   NotFound:
  16.787     return NULL;
  16.788   }
  16.789  
  16.790  inline
  16.791 -PRSemEnv *
  16.792 -PR_int__create_proto_sem_env_in_process( PRProcess process, int32 magicNum )
  16.793 - { PRSemEnv *semEnvs;
  16.794 -   PRSemEnv *retEnv, *newEnv;
  16.795 -   int32 idx;
  16.796 - 
  16.797 -   semEnvs = process->semEnvs;
  16.798 -   
  16.799 -   idx = magicNum & 63; //mask upper bits off, leaving lowest 6 bits
  16.800 -   retEnv =  &(semEnvs[idx]); //is array of structs, so take addr
  16.801 -   if( retEnv->langSemEnv == NULL ) 
  16.802 -    { //if env that's in array is empty, do nothing, drop down to return sequence
  16.803 +void
  16.804 +PR_int__remove_elem_from_collection( int32 hash, PRCollElem **coll )
  16.805 + { int32 idx, numIdxsInColl;
  16.806 +   PRCollElem *test, *prev;
  16.807 +
  16.808 +   numIdxsInColl = ((int32 *)coll)[-1]; //num indexes in prolog -- power of 2
  16.809 +
  16.810 +   idx = hash & (numIdxsInColl - 1); //mask off, leaving lowest bits (power of 2)
  16.811 +   test = coll[idx];
  16.812 +   if( test == NULL ) return; //not found, nothing to remove
  16.813 +   prev = NULL;
  16.814 +   while( test->hash != hash )
  16.815 +    { prev = test;
  16.816 +      test = test->chained;
  16.817 +      if( test == NULL ) return; //not found, nothing to remove
  16.818      }
  16.819 -   else //look for last environment in chain
  16.820 -    { while( retEnv->chainedSemEnv != NULL ) 
  16.821 -       { retEnv = retEnv->chainedSemEnv;
  16.822 -       }
  16.823 -         //add a new proto sem env to the end of chain
  16.824 -      newEnv = PR_int__malloc( sizeof(PRSemEnv) );
  16.825 -      newEnv->chainedSemEnv = NULL;
  16.826 -      retEnv->chainedSemEnv = newEnv;
  16.827 -      retEnv = newEnv;
  16.828 +   if( prev == NULL)
  16.829 +    { coll[idx] = coll[idx]->chained;
  16.830 +      return;
  16.831      }
  16.832 -
  16.833 -   process->semEnvList[process->numSemEnvs] = retEnv;
  16.834 -   process->numSemEnvs += 1;
  16.835 -   return retEnv;
  16.836 +   else
  16.837 +    { prev->chained = test->chained;
  16.838 +      return;
  16.839 +    }
  16.840   }
  16.841  
  16.842 +inline
  16.843 +void
  16.844 +PR_int__apply_Fn_to_all_in_collection( void (*Fn)(void *), PRCollElem *coll )
  16.845 + { int32 idx, numIdxsInColl;
  16.846 +   PRCollElem *test;
  16.847 +
  16.848 +   numIdxsInColl = ((int32 *)coll)[-1]; //prolog is num idxs
  16.849 +   for( idx = 0; idx < ; idx++ )
  16.850 +    { test = coll[idx];
  16.851 +      while( test != NULL )
  16.852 +       { (*Fn)((void *)test); 
  16.853 +         test = test->chained;  
  16.854 +       }
  16.855 +    }
  16.856 + }
  16.857 +
  16.858 +//==========================================
  16.859  
  16.860  /*Later, improve this -- for now, just exits the application after printing
  16.861   * the error message.
  16.862 @@ -370,7 +783,8 @@
  16.863   }
  16.864  
  16.865  
  16.866 -inline char *
  16.867 +inline 
  16.868 +char *
  16.869  PR_int__strDup( char *str )
  16.870   { char *retStr;
  16.871  
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/PR__int.h	Mon Jan 14 15:31:23 2013 -0800
    17.3 @@ -0,0 +1,245 @@
    17.4 +/*
    17.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
    17.6 + *  Licensed under GNU General Public License version 2
    17.7 + *
    17.8 + * Author: seanhalle@yahoo.com
    17.9 + * 
   17.10 + */
   17.11 +
   17.12 +#ifndef _PR_INT_H
   17.13 +#define	_PR_INT_H
   17.14 +#define _GNU_SOURCE
   17.15 +
   17.16 +
   17.17 +/* MEANING OF   WL  PI  SS  int
   17.18 + * These indicate which places the function is safe to use.  They stand for:
   17.19 + * WL: Wrapper Library
   17.20 + * PI: Plugin 
   17.21 + * SS: Startup and Shutdown
   17.22 + * int: internal to the PR implementation
   17.23 + */
   17.24 +
   17.25 +
   17.26 +inline SlaveVP *
   17.27 +PR_int__create_slave( TopLevelFnPtr fnPtr, void *dataParam );
   17.28 +#define PR_PI__create_slaveVP PR_int__create_slave
   17.29 +#define PR_WL__create_slaveVP PR_int__create_slave
   17.30 +
   17.31 +inline 
   17.32 +SlaveVP *
   17.33 +PR_int__create_slaveVP_helper( SlaveVP *newSlv,       TopLevelFnPtr  fnPtr,
   17.34 +                                void      *dataParam, void           *stackLocs );
   17.35 +
   17.36 +inline
   17.37 +PRMetaTask *
   17.38 +PR_int__create_generic_slave_meta_task( void *initData );
   17.39 +
   17.40 +inline
   17.41 +void
   17.42 +PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr,
   17.43 +                              void    *dataParam);
   17.44 +
   17.45 +inline
   17.46 +void
   17.47 +PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr,
   17.48 +                              void    *param);
   17.49 +
   17.50 +inline
   17.51 +void
   17.52 +PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr,
   17.53 +                             void    *param1, void *param2);
   17.54 +
   17.55 +//===========================================================================
   17.56 +//
   17.57 +//===========================================================================
   17.58 +inline
   17.59 +SlaveVP *
   17.60 +PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam );
   17.61 +
   17.62 +inline
   17.63 +SlaveVP *
   17.64 +PR_int__create_slaveVP__ML( TopLevelFnPtr fnPtr, void *dataParam, PRProcess *process );
   17.65 +
   17.66 +SlaveVP *
   17.67 +PR_int__get_recycled_slot_slave( );
   17.68 +
   17.69 +SlaveVP *
   17.70 +PR_int__create_slot_slave( );
   17.71 +
   17.72 +inline 
   17.73 +void
   17.74 +PR_int__replace_with_new_slot_slv( SlaveVP *slave );
   17.75 +
   17.76 +void 
   17.77 +idle_fn(void* data, SlaveVP *animatingSlv);
   17.78 +
   17.79 +inline
   17.80 +void
   17.81 +PR_int__put_task_into_slot( PRMetaTask *task, PRProcess *process, AnimSlot *slot );
   17.82 +
   17.83 +inline
   17.84 +void
   17.85 +PR_int__put_slave_into_slot( SlaveVP *slave, AnimSlot *slot );
   17.86 +
   17.87 +void inline
   17.88 +PR_int__handle_PRServiceReq(  SlaveVP *requestingSlv );
   17.89 +
   17.90 +void
   17.91 +PR_WL__suspend_slaveVP_and_send_req( SlaveVP *animatingSlv );
   17.92 +
   17.93 +void
   17.94 +PR_int__dissipate_slaveVP__SL( SlaveVP *animatingSlv );
   17.95 +
   17.96 +void
   17.97 +PR_int__free_slaveVP__ML( SlaveVP *slave );
   17.98 +
   17.99 +void
  17.100 +PR_int__recycle_slave__ML( SlaveVP *slave );
  17.101 +
  17.102 +void
  17.103 +recycleLangDataAsElem( void *elem );
  17.104 +
  17.105 +void
  17.106 +recycleMetaTaskAsElem( void *elem );
  17.107 +
  17.108 +inline 
  17.109 +void *
  17.110 +PR_int__give_lang_env( PRLangEnv *protoLangEnv );
  17.111 +
  17.112 +inline 
  17.113 +PRLangEnv *
  17.114 +PR_int__give_proto_lang_env( void *langEnv );
  17.115 +
  17.116 +inline
  17.117 +void *
  17.118 +PR_int__create_lang_env_in_process( int32 size, PRProcess process, int32 magicNum );
  17.119 +
  17.120 +inline
  17.121 +void *
  17.122 +PR_int__free_lang_env( void *langEnv );
  17.123 +
  17.124 +inline
  17.125 +void *
  17.126 +PR_int__give_lang_env_of_req__ML( PRReqst *req, SlaveVP *requestingSlv );
  17.127 +
  17.128 +inline
  17.129 +void *
  17.130 +PR_int__give_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNum );
  17.131 +#define PR_PI__give_lang_env_for  PR_int__give_lang_env_for_slave__ML
  17.132 +#define PR_SS__give_lang_env_for_slave  PR_int__give_lang_env_for_slave__ML
  17.133 +//No WL version -- not safe!  if use env in WL, be sure data rd & wr is stable
  17.134 +
  17.135 +inline
  17.136 +PRLangEnv *
  17.137 +PR_int__give_proto_lang_env_for_slave__ML( SlaveVP *slave, int32 magicNumber );
  17.138 +#define PR_PI__give_proto_lang_env_for  PR_int__give_proto_lang_env_for_slave__ML
  17.139 +#define PR_SS__give_proto_lang_env_for_slave  PR_int__give_proto_lang_env_for_slave__ML
  17.140 +//No WL version -- not safe!  if use env in WL, be sure data rd & wr is stable
  17.141 +
  17.142 +inline
  17.143 +void *
  17.144 +PR_int__give_lang_env_from_process( PRProcess *process, int32 magicNum );
  17.145 +#define PR_PI__give_lang_env_from_process  PR_int__give_lang_env_from_process
  17.146 +#define PR_SS__give_lang_env_from_process  PR_int__give_lang_env_from_process
  17.147 +//#define PR_WL__give_lang_env_from_process  PR_int__give_lang_env_from_process
  17.148 +//No WL version -- not safe!  if use env in WL, be sure data rd & wr is stable
  17.149 +
  17.150 +inline
  17.151 +PRLangEnv *
  17.152 +PR_int__give_proto_lang_env_for_process( PRProcess *process, int32 magicNum );
  17.153 +
  17.154 +inline
  17.155 +void
  17.156 +PR_int__set_work_in_lang_env( void *_langEnv );
  17.157 +
  17.158 +inline
  17.159 +void
  17.160 +PR_int__clear_work_in_lang_env( void *_langEnv );
  17.161 +
  17.162 +inline 
  17.163 +PRMetaTask *
  17.164 +PR_int__give_prolog_of_task( void *task );
  17.165 +
  17.166 +inline
  17.167 +void *
  17.168 +PR_int__give_lang_meta_task_of_prolog( PRMetaTask *metaTask);
  17.169 +
  17.170 +inline
  17.171 +void *
  17.172 +PR_int__create_lang_meta_task__ML( int32 size, int32 magicNum );
  17.173 +
  17.174 +inline
  17.175 +void *
  17.176 +PR_int__create_lang_meta_task_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum );
  17.177 +
  17.178 +inline
  17.179 +void
  17.180 +PR_int__insert_meta_task_into_slave__ML( PRMetaTask *task, SlaveVP *slave );
  17.181 +
  17.182 +inline
  17.183 +void
  17.184 +PR_int__insert_lang_meta_task_into_slave__ML( void *langMetaTask, SlaveVP *slave );
  17.185 +
  17.186 +inline
  17.187 +void *
  17.188 +PR_int__give_lang_meta_task_from_slave__ML( SlaveVP *slave, int32 magicNumer );
  17.189 +//#define PR_int__give_lang_meta_task_from_slave__ML( slave, magicNumber )\
  17.190 +        slave->metaTask->langMetaTask;
  17.191 +#define PR_PI__give_lang_meta_task_from_slave__ML  PR_int__give_lang_meta_task_from_slave__ML
  17.192 +#define PR_SS__give_lang_meta_task_from_slave__ML  PR_int__give_lang_meta_task_from_slave__ML
  17.193 +#define PR_WL__give_lang_meta_task_from_slave__ML  PR_int__give_lang_meta_task_from_slave__ML
  17.194 +
  17.195 +inline
  17.196 +SlaveVP *
  17.197 +PR_PI__give_slave_lang_meta_task_assigned_to( void *langMetaTask );
  17.198 +
  17.199 +inline
  17.200 +void *
  17.201 +PR_int__create_lang_data_in_slave__ML( int32 size, SlaveVP *slave, int32 magicNum );
  17.202 +
  17.203 +inline
  17.204 +void *
  17.205 +PR_int__give_lang_data_from_slave__ML( SlaveVP *slave, int32 magicNumer );
  17.206 +#define PR_PI__give_lang_data  PR_int__give_lang_data_from_slave__ML
  17.207 +#define PR_SS__give_lang_data  PR_int__give_lang_data_from_slave__ML
  17.208 +#define PR_WL__give_lang_data  PR_int__give_lang_data_from_slave__ML
  17.209 +
  17.210 +inline
  17.211 +void
  17.212 +PR_int__insert_elem_into_collection( PRCollElem *elem, PRCollElem **coll, int32 hash );
  17.213 +
  17.214 +inline
  17.215 +void *
  17.216 +PR_int__lookup_elem_in_collection( int32 hash, PRCollElem **coll );
  17.217 +
  17.218 +inline
  17.219 +void
  17.220 +PR_int__remove_elem_from_collection( int32 hash, PRCollElem **coll );
  17.221 +
  17.222 +inline
  17.223 +void
  17.224 +PR_int__apply_Fn_to_all_in_collection( void (*Fn)(void *), PRCollElem *coll );
  17.225 +
  17.226 +void
  17.227 +PR_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
  17.228 +#define PR_PI__throw_exception  PR_int__throw_exception
  17.229 +
  17.230 +inline char *
  17.231 +PR_int__strDup( char *str );
  17.232 +
  17.233 +inline void
  17.234 +PR_int__backoff_for_TooLongToGetLock( int32 numTriesToGetLock );
  17.235 +
  17.236 +inline void
  17.237 +PR_int__get_master_lock();
  17.238 +
  17.239 +#define PR_int__release_master_lock() _PRTopEnv->masterLock = UNLOCKED
  17.240 +
  17.241 +inline uint32_t
  17.242 +PR_int__randomNumber();
  17.243 +
  17.244 +inline void
  17.245 +PR_int__backoff_for_TooLongToGetLock( int32 numTriesToGetLock );
  17.246 +
  17.247 +#endif	/* _PR_INT_H */
  17.248 +
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/PR__structs.h	Mon Jan 14 15:31:23 2013 -0800
    18.3 @@ -0,0 +1,418 @@
    18.4 +/*
    18.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
    18.6 + *  Licensed under GNU General Public License version 2
    18.7 + *
    18.8 + * Author: seanhalle@yahoo.com
    18.9 + * 
   18.10 + */
   18.11 +
   18.12 +#ifndef _PR__structs_H
   18.13 +#define	_PR__structs_H
   18.14 +#define _GNU_SOURCE
   18.15 +
   18.16 +#include "PR_primitive_data_types.h"
   18.17 +
   18.18 +#include <pthread.h>
   18.19 +#include <sys/time.h>
   18.20 +
   18.21 +
   18.22 +//================================ Typedefs =================================
   18.23 +//
   18.24 +typedef unsigned long long    TSCount;
   18.25 +
   18.26 +typedef struct _AnimSlot      AnimSlot;
   18.27 +typedef struct _PRReqst       PRReqst;
   18.28 +typedef struct _SlaveVP       SlaveVP;
   18.29 +typedef struct _MasterVP      MasterVP;
   18.30 +typedef struct _IntervalProbe IntervalProbe;
   18.31 +typedef struct _PRLangEnv     PRLangEnv;   //a prolog
   18.32 +typedef struct _PRMetaTask    PRMetaTask; //a prolog
   18.33 +typedef struct _PRLangData    PRLangData;  //a prolog
   18.34 +typedef struct _PRCollElem    PRCollElem; //generic form of the prologs
   18.35 +
   18.36 +typedef SlaveVP *(*SlaveAssigner)  ( void *, AnimSlot* ); //langEnv, slot for HW info
   18.37 +typedef void     (*RequestHandler) ( void *, SlaveVP *, void * ); //req, slv, langEnv
   18.38 +typedef void    *(*CreateHandler)  ( void *, SlaveVP *, void * ); //req, slv, langEnv
   18.39 +typedef void     (*TopLevelFnPtr)  ( void *, SlaveVP * ); //initData, animSlv
   18.40 +typedef void       TopLevelFn      ( void *, SlaveVP * ); //initData, animSlv
   18.41 +typedef void     (*ResumeSlvFnPtr) ( SlaveVP *, void * );
   18.42 +      //=========== MEASUREMENT STUFF ==========
   18.43 +        MEAS__Insert_Counter_Handler
   18.44 +      //========================================
   18.45 +
   18.46 +//============================ HW Dependent Fns ================================
   18.47 +
   18.48 +#include "HW_Dependent_Primitives/PR__HW_measurement.h"
   18.49 +#include "HW_Dependent_Primitives/PR__primitives.h"
   18.50 +
   18.51 +
   18.52 +typedef struct
   18.53 + { //These are set by the plugin during startup and the application
   18.54 +   char *assignerInfo;
   18.55 +   char *appInfo;
   18.56 +   char *inputInfo;
   18.57 + }
   18.58 +PRSysMetaInfo;
   18.59 +
   18.60 +//=====================  Process Data Struct  ======================
   18.61 +
   18.62 +/*This structure holds all the information PR needs to manage a program.  PR
   18.63 + * stores information about what percent of CPU time the program is getting, 
   18.64 + * 
   18.65 + */
   18.66 +typedef struct
   18.67 + { 
   18.68 +   int32     numEnvsWithWork;
   18.69 +   void     *resultToReturn;
   18.70 +    
   18.71 +   PRLangEnv *langEnvs[NUM_IN_COLLECTION];     //used as a hash table
   18.72 +   PRLangEnv *langEnvsList[NUM_IN_COLLECTION]; //for fast linear scan of envs
   18.73 +   int32      numLangEnvs;                     //for fast linear scan of envs
   18.74 +    
   18.75 +   SlaveVP        *seedSlv;
   18.76 +   
   18.77 +   int32           numLiveGenericSlvs;
   18.78 +   int32           numLiveTasks;
   18.79 +
   18.80 +   SlaveAssigner   overrideAssigner;
   18.81 +  
   18.82 +   
   18.83 +   
   18.84 +      //These are used to coord with an OS thread waiting for process to end
   18.85 +   bool32          executionIsComplete;
   18.86 +   pthread_mutex_t doneLock;
   18.87 +   pthread_cond_t  doneCond;   
   18.88 +
   18.89 +      //=========== MEASUREMENT STUFF =============
   18.90 +       IntervalProbe   **intervalProbes;
   18.91 +       PrivDynArrayInfo *dynIntervalProbesInfo;
   18.92 +       HashTable        *probeNameHashTbl;
   18.93 +       int32             masterCreateProbeID;
   18.94 +       float64           createPtInSecs; //real-clock time PR initialized
   18.95 +       Histogram       **measHists;
   18.96 +       PrivDynArrayInfo *measHistsInfo;
   18.97 +       MEAS__Insert_Susp_Meas_Fields_into_MasterEnv;
   18.98 +       MEAS__Insert_Master_Meas_Fields_into_MasterEnv;
   18.99 +       MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv;
  18.100 +       MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv;
  18.101 +       MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv;
  18.102 +       MEAS__Insert_System_Meas_Fields_into_MasterEnv;
  18.103 +       MEAS__Insert_Counter_Meas_Fields_into_MasterEnv;
  18.104 +      //==========================================
  18.105 + }
  18.106 +PRProcess;
  18.107 +
  18.108 +
  18.109 +//============= Request Related ===========
  18.110 +//
  18.111 +
  18.112 +enum PRReqstType  //avoid starting enums at 0, for debug reasons
  18.113 + {
  18.114 +   TaskCreate = 1,
  18.115 +   TaskEnd,
  18.116 +   SlvCreate,
  18.117 +   SlvDissipate,
  18.118 +   Language,
  18.119 +   Service,       //To invoke a PR provided equivalent of a language request (ex: probe)
  18.120 +   Hardware,
  18.121 +   IO,
  18.122 +   OSCall
  18.123 + };
  18.124 +
  18.125 +struct _PRReqst
  18.126 + {
  18.127 +   enum PRReqstType   reqType;//used for special forms that have PR behavior
  18.128 +   void              *langReq;
  18.129 +   PRProcess         *processReqIsIn;
  18.130 +   int32              langMagicNumber;
  18.131 +   TopLevelFnPtr      topLevelFn;
  18.132 +   void              *initData;
  18.133 +   int32             *ID;
  18.134 +   
  18.135 +      //The request handling structure is a bit messy..  for special forms, 
  18.136 +      // such as create and dissipate, the language inserts pointer to handler
  18.137 +      // fn directly into the request..  might change to this for all requests
  18.138 +   RequestHandler    handler; //pointer to handler fn 
  18.139 +   CreateHandler     createHdlr; //special because returns something
  18.140 +   
  18.141 +   PRReqst *nextReqst;
  18.142 + };
  18.143 +//PRReqst
  18.144 +
  18.145 +enum PRServReqType   //These are equivalent to lang requests, but for
  18.146 + {                    // PR's services available directly to app, like OS
  18.147 +   make_probe = 1,    // and probe services -- like a PR-wide built-in lang
  18.148 +   throw_excp,
  18.149 +   openFile,
  18.150 +   otherIO
  18.151 + };
  18.152 +
  18.153 +typedef struct
  18.154 + { enum PRServReqType   reqType;
  18.155 +   SlaveVP             *requestingSlv;
  18.156 +   char                *nameStr;  //for create probe
  18.157 +   char                *msgStr;   //for exception
  18.158 +   void                *exceptionData;
  18.159 + }
  18.160 +PRServReq;
  18.161 +
  18.162 +
  18.163 +//====================  Core data structures  ===================
  18.164 +
  18.165 +typedef struct
  18.166 + {
  18.167 +   //for future expansion
  18.168 + }
  18.169 +SlotPerfInfo;
  18.170 +
  18.171 +struct _AnimSlot
  18.172 + {
  18.173 +   int32         workIsDone;
  18.174 +   int32         needsWorkAssigned;
  18.175 +   SlaveVP      *slaveAssignedToSlot;
  18.176 +   
  18.177 +   int32         slotIdx;  //needed by Holistic Model's data gathering
  18.178 +   int32         coreSlotIsOn;
  18.179 +   SlotPerfInfo *perfInfo; //used by assigner to pick best slave for core
  18.180 + };
  18.181 +//AnimSlot
  18.182 +
  18.183 +enum VPtype 
  18.184 + { SlotTaskSlv = 1,//Slave tied to an anim slot, only animates tasks
  18.185 +   FreeTaskSlv,   //When a suspended task ends, the slave becomes this
  18.186 +   GenericSlv,     //the VP is explicitly seen in the app code, or task suspends
  18.187 +   SeedSlv,
  18.188 +   Master,
  18.189 +   Shutdown,
  18.190 +   Idle
  18.191 + };
  18.192 + 
  18.193 +/*This structure embodies the state of a slaveVP.  It is reused for masterVP
  18.194 + * and shutdownVPs.
  18.195 + */
  18.196 +struct _SlaveVP
  18.197 + {    //The offsets of these fields are hard-coded into assembly
  18.198 +   void       *stackPtr;         //save the core's stack ptr when suspend
  18.199 +   void       *framePtr;         //save core's frame ptr when suspend
  18.200 +   void       *resumeInstrPtr;   //save core's program-counter when suspend
  18.201 +   void       *coreCtlrFramePtr; //restore before jmp back to core controller
  18.202 +   void       *coreCtlrStackPtr; //restore before jmp back to core controller
  18.203 +   
  18.204 +      //============ below this, no fields are used in asm =============
  18.205 +   
  18.206 +   void       *startOfStack;  //used to free, and to point slave to Fn
  18.207 +   PRProcess  *processSlaveIsIn;
  18.208 +   enum VPtype typeOfVP;      //Slave vs Master vs Shutdown..
  18.209 +   int32       slaveNum;      //each slave given it's seq in creation
  18.210 +   int32      *ID;       //App defines meaning of each int in array
  18.211 +   int32       coreAnimatedBy; 
  18.212 +   int32       numTimesAssignedToASlot;   //Each assign is for one work-unit, so is an ID
  18.213 +      //note, a scheduling decision is uniquely identified by the triple:
  18.214 +      // <slaveNum, coreAnimatedBy, numTimesAssignedToASlot> -- used in record & replay
  18.215 +   
  18.216 +      //for comm -- between master and coreCtlr & btwn wrapper lib and plugin
  18.217 +   AnimSlot   *animSlotAssignedTo;
  18.218 +   PRReqst    *request;      //wrapper lib puts in requests, plugin takes out
  18.219 +   void       *dataRetFromReq;//Return vals from plugin to Wrapper Lib
  18.220 +
  18.221 +      //For language specific data that needs to be in the slave
  18.222 +      //These are accessed  directly for single-lang, but multi-lang places
  18.223 +      // a holder here instead, then uses magic num to get lang's version
  18.224 +   void       *langData;  //Lang saves lang-specific things in slave here
  18.225 +   void       *metaTask;
  18.226 +
  18.227 +        //=========== MEASUREMENT STUFF ==========
  18.228 +         MEAS__Insert_Meas_Fields_into_Slave;
  18.229 +         float64     createPtInSecs;  //time VP created, in seconds
  18.230 +        //========================================
  18.231 +         
  18.232 +//   int8       cacheLinePad[512 - sizeof(contents)]; //for false sharing
  18.233 + };
  18.234 +//SlaveVP
  18.235 +
  18.236 + 
  18.237 +enum PRMode
  18.238 + { SingleLang = 1,
  18.239 +   StandaloneWTasks,
  18.240 +   MultiLang      
  18.241 + };
  18.242 + 
  18.243 +/* The one and only global variable, holds many odds and ends
  18.244 + */
  18.245 +typedef struct
  18.246 + {    //The offsets of these fields are hard-coded into assembly
  18.247 +   void            *coreCtlrReturnPt;    //offset to this field used in asm
  18.248 +   int8             falseSharePad1[256 - sizeof(void*)];
  18.249 +   int32            masterLock;          //offset to this field used in asm
  18.250 +   int8             falseSharePad2[256 - sizeof(int32)];
  18.251 +      //============ below this, no fields are used in asm =============
  18.252 +
  18.253 +      //Basic PR infrastructure
  18.254 +   enum PRMode      mode;
  18.255 +   SlaveVP        **masterVPs;
  18.256 +   AnimSlot      ***allAnimSlots;
  18.257 +   PrivQueueStruc  *slaveRecycleQ;
  18.258 +   SlaveVP         *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
  18.259 +   SlaveVP         *idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
  18.260 +   
  18.261 +      //Memory management related
  18.262 +   MallocArrays    *freeLists;
  18.263 +   int32            amtOfOutstandingMem;//total currently allocated
  18.264 +
  18.265 +      //Random number seeds -- random nums used in various places  
  18.266 +   uint32_t         seed1;
  18.267 +   uint32_t         seed2;
  18.268 +
  18.269 +   PRSysMetaInfo   *metaInfo; //info about this PR system -- vers, build, etc
  18.270 +   
  18.271 +   //============== This only used by multi-lang mode ============
  18.272 +   PRProcess      **processes;
  18.273 +   int32            numProcesses;
  18.274 +   int32            currProcessIdx;    //used to choose which process gets slot
  18.275 +   int32            firstProcessReady; //use while starting up coreCtlr
  18.276 +   RequestHandler   free_lang_data;    //lang data persists after langlet stops
  18.277 +                                       //so need freer when end slaves
  18.278 +   
  18.279 +      //initialize flags for waiting for activity within PR to complete
  18.280 +   bool32          allActivityIsDone;
  18.281 +   pthread_mutex_t activityDoneLock;
  18.282 +   pthread_cond_t  activityDoneCond;   
  18.283 +
  18.284 +   
  18.285 +   //============== Below this is only used by single-lang mode ==============
  18.286 +   void            *protoLangEnv;
  18.287 +      //Slave creation -- global count of slaves existing, across langs and processes
  18.288 +   int32            numSlavesCreated;  //used to give unique ID to processor
  18.289 +   int32            numTasksCreated;   //to give unique ID to a task
  18.290 +   int32            numSlavesAlive;
  18.291 +
  18.292 +   bool32          *coreIsDone;
  18.293 +   int32            numCoresDone;
  18.294 +   int32            shutdownInitiated;
  18.295 +   
  18.296 +   
  18.297 +      //=========== MEASUREMENT STUFF =============
  18.298 +       IntervalProbe   **intervalProbes;
  18.299 +       PrivDynArrayInfo *dynIntervalProbesInfo;
  18.300 +       HashTable        *probeNameHashTbl;
  18.301 +       int32             masterCreateProbeID;
  18.302 +       float64           createPtInSecs; //real-clock time PR initialized
  18.303 +       Histogram       **measHists;
  18.304 +       PrivDynArrayInfo *measHistsInfo;
  18.305 +       MEAS__Insert_Susp_Meas_Fields_into_MasterEnv;
  18.306 +       MEAS__Insert_Master_Meas_Fields_into_MasterEnv;
  18.307 +       MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv;
  18.308 +       MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv;
  18.309 +       MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv;
  18.310 +       MEAS__Insert_System_Meas_Fields_into_MasterEnv;
  18.311 +       MEAS__Insert_Counter_Meas_Fields_into_MasterEnv;
  18.312 +      //==========================================
  18.313 + }
  18.314 +TopEnv;
  18.315 +
  18.316 +
  18.317 +//===================== These are prologs ====================
  18.318 +//===A prolog is data immediately before pointer returned by a create function.
  18.319 +//=
  18.320 +struct _PRLangEnv
  18.321 + { //============== First two must match PRCollElem ==============
  18.322 +   int32     langMagicNumber; //indexes into hash array of langEnvs in PRProcess
  18.323 +   PRLangEnv *chainedLangEnv;   //chains to langEnvs with same hash
  18.324 +   //=============================================================
  18.325 +   
  18.326 +   SlaveAssigner   slaveAssigner;
  18.327 +   RequestHandler  requestHdlr; 
  18.328 +   RequestHandler  shutdownHdlr; //called when lang ended or process shutdown
  18.329 +
  18.330 +/*
  18.331 +   CreateTaskHdlr  createTaskHdlr;
  18.332 +   RequestHandler  endTaskHdlr; 
  18.333 +   CreateSlvHdlr   createSlaveHdlr;
  18.334 +   RequestHandler  dissipateSlaveHdlr;
  18.335 + */ 
  18.336 +   RequestHandler  langDataCreator;
  18.337 +   RequestHandler  langDataInitializer;
  18.338 +     
  18.339 +      //when multi-lang, master polls lang env's to find one with work in it..
  18.340 +      // in single-lang case, flag ignored, master always asks lang for work
  18.341 +   int32           hasWork;
  18.342 +   PRProcess      *processEnvIsIn;
  18.343 +   
  18.344 +   int32           idxInProcess; //index into array of langEnvs in the process
  18.345 + };
  18.346 +//PRLangEnv -- this is the prolog of every lang's lang env
  18.347 +
  18.348 +enum PRTaskType
  18.349 + { GenericSlave = 1,
  18.350 +   SlotTask,
  18.351 +   FreeTask
  18.352 + };
  18.353 +
  18.354 +struct _PRMetaTask
  18.355 + { //============== First two must match PRCollElem ==============
  18.356 +   int32           langMagicNumber;
  18.357 +   PRMetaTask     *chainedMetaTask;
  18.358 +   //=============================================================
  18.359 +   enum PRTaskType taskType;
  18.360 +   int32          *ID;              //is standard PR ID
  18.361 +   SlaveVP        *slaveAssignedTo; //no valid until task animated
  18.362 +   TopLevelFnPtr   topLevelFn;      //This is the Fn executes as the task
  18.363 +   void           *initData;        //The data taken by the function
  18.364 +   void          (*recycler)(void *);
  18.365 +
  18.366 +   //NOTE: info needed for "wait" functionality is inside lang's metaTask
  18.367 + };
  18.368 +//PRMetaTask -- prolog of every lang's meta task
  18.369 +
  18.370 +struct _PRLangData
  18.371 + { //============== First two must match PRCollElem ==============
  18.372 +   int32      langMagicNumber;
  18.373 +   PRLangData *chainedLangData;
  18.374 +   //=============================================================
  18.375 +   void     (*recycler)(void *);
  18.376 +   void      *langLangData;
  18.377 + };
  18.378 +//PRLangData -- this is the prolog of each lang's lang data
  18.379 +
  18.380 +struct _PRCollElem
  18.381 + {
  18.382 +   int32       hash;
  18.383 +   PRCollElem *chained;
  18.384 + };
  18.385 +//PRCollElem -- this is generic form of all the prologs
  18.386 +
  18.387 +
  18.388 +
  18.389 +//The language env of PR's services langlet
  18.390 +typedef struct
  18.391 + { 
  18.392 +   PrivQueueStruc  *slavesReadyToResumeQ; //Shared (slaves not pinned)
  18.393 +   PrivQueueStruc  *taskReadyQ;           //Shared (tasks not pinned)
  18.394 + }
  18.395 +PRServLangEnv;
  18.396 +
  18.397 +
  18.398 +
  18.399 +//=========================  Extra Stuff Data Strucs  =======================
  18.400 +typedef struct
  18.401 + {
  18.402 +
  18.403 + }
  18.404 +PRExcp; //exception
  18.405 +
  18.406 +//=======================  OS Thread related  ===============================
  18.407 +
  18.408 +void * coreController( void *paramsIn );  //standard PThreads fn prototype
  18.409 +void * coreCtlr_Seq( void *paramsIn );  //standard PThreads fn prototype
  18.410 +void animationMaster( void *initData, SlaveVP *masterVP );
  18.411 +
  18.412 +
  18.413 +typedef struct
  18.414 + {
  18.415 +   void           *endThdPt;
  18.416 +   unsigned int    coreNum;
  18.417 + }
  18.418 +ThdParams;
  18.419 +
  18.420 +#endif	/* _PR__structs_H */
  18.421 +
    19.1 --- a/PR_primitive_data_types.h	Sun Nov 04 18:39:28 2012 -0800
    19.2 +++ b/PR_primitive_data_types.h	Mon Jan 14 15:31:23 2013 -0800
    19.3 @@ -1,5 +1,5 @@
    19.4  /*
    19.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
    19.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
    19.7   *  Licensed under GNU General Public License version 2
    19.8   *  
    19.9   * Author: seanhalle@yahoo.com
    20.1 --- a/Services_Offered_by_PR/Measurement_and_Stats/MEAS__macros.h	Sun Nov 04 18:39:28 2012 -0800
    20.2 +++ b/Services_Offered_by_PR/Measurement_and_Stats/MEAS__macros.h	Mon Jan 14 15:31:23 2013 -0800
    20.3 @@ -1,5 +1,5 @@
    20.4  /*
    20.5 - *  Copyright 2009 OpenSourceStewardshipFoundation.org
    20.6 + *  Copyright 2009 OpenSourceResearchInstitute.org
    20.7   *  Licensed under GNU General Public License version 2
    20.8   *
    20.9   * Author: seanhalle@yahoo.com
   20.10 @@ -368,7 +368,7 @@
   20.11     
   20.12     #define HOLISTIC__Insert_Master_Global_Vars \
   20.13          int vpid,task; \
   20.14 -        CounterHandler counterHandler = masterEnv->counterHandler;
   20.15 +        CounterHandler counterHandler = _PRTopEnv->counterHandler;
   20.16     
   20.17     #define HOLISTIC__Record_last_work lastVPBeforeMaster = currVP;
   20.18  
   20.19 @@ -376,7 +376,7 @@
   20.20        uint64 cycles,instrs,cachem; \
   20.21        saveCyclesAndInstrs(thisCoresIdx,cycles, instrs,cachem); \
   20.22        if(lastVPBeforeMaster){ \
   20.23 -        (*counterHandler)(AppResponderInvocation_start,lastVPBeforeMaster->slaveID,lastVPBeforeMaster->numTimesAssignedToASlot,lastVPBeforeMaster,cycles,instrs,cachem); \
   20.24 +        (*counterHandler)(AppResponderInvocation_start,lastVPBeforeMaster->slaveNum,lastVPBeforeMaster->numTimesAssignedToASlot,lastVPBeforeMaster,cycles,instrs,cachem); \
   20.25          lastVPBeforeMaster = NULL; \
   20.26        } else { \
   20.27            _PRTopEnv->start_master_lock[thisCoresIdx][0] = cycles; \
   20.28 @@ -395,7 +395,7 @@
   20.29                  * would be erroneously counted as invocation time.
   20.30                  */
   20.31     #define HOLISTIC__Record_AppResponder_start \
   20.32 -               vpid = currSlot->slaveAssignedToSlot->slaveID; \
   20.33 +               vpid = currSlot->slaveAssignedToSlot->slaveNum; \
   20.34                 task = currSlot->slaveAssignedToSlot->numTimesAssignedToASlot; \
   20.35                 uint64 cycles, instrs, cachem; \
   20.36                 saveCyclesAndInstrs(thisCoresIdx,cycles, instrs,cachem); \
   20.37 @@ -429,30 +429,30 @@
   20.38          uint64 cycles,instrs,cachem; \
   20.39          saveCyclesAndInstrs(thisCoresIdx,cycles,instrs,cachem); \
   20.40          if(empty){ \
   20.41 -            (*counterHandler)(AssignerInvocation_start,assignedSlaveVP->slaveID,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,masterEnv->start_master_lock[thisCoresIdx][0],masterEnv->start_master_lock[thisCoresIdx][1],masterEnv->start_master_lock[thisCoresIdx][2]); \
   20.42 +            (*counterHandler)(AssignerInvocation_start,assignedSlaveVP->slaveNum,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,_PRTopEnv->start_master_lock[thisCoresIdx][0],_PRTopEnv->start_master_lock[thisCoresIdx][1],masterEnv->start_master_lock[thisCoresIdx][2]); \
   20.43          } \
   20.44 -        (*counterHandler)(Timestamp_start,assignedSlaveVP->slaveID,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,tsc,0,0); \
   20.45 -        (*counterHandler)(Assigner_start,assignedSlaveVP->slaveID,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,tmp_cycles,tmp_instrs,tmp_cachem); \
   20.46 -        (*counterHandler)(Assigner_end,assignedSlaveVP->slaveID,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,cycles,instrs,tmp_cachem);
   20.47 +        (*counterHandler)(Timestamp_start,assignedSlaveVP->slaveNum,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,tsc,0,0); \
   20.48 +        (*counterHandler)(Assigner_start,assignedSlaveVP->slaveNum,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,tmp_cycles,tmp_instrs,tmp_cachem); \
   20.49 +        (*counterHandler)(Assigner_end,assignedSlaveVP->slaveNum,assignedSlaveVP->numTimesAssignedToASlot,assignedSlaveVP,cycles,instrs,tmp_cachem);
   20.50  
   20.51     #define HOLISTIC__Record_Work_start \
   20.52          if(currVP){ \
   20.53                  uint64 cycles,instrs,cachem; \
   20.54                  saveCyclesAndInstrs(thisCoresIdx,cycles, instrs,cachem); \
   20.55 -                (*counterHandler)(Work_start,currVP->slaveID,currVP->numTimesAssignedToASlot,currVP,cycles,instrs,cachem); \
   20.56 +                (*counterHandler)(Work_start,currVP->slaveNum,currVP->numTimesAssignedToASlot,currVP,cycles,instrs,cachem); \
   20.57          }
   20.58     
   20.59     #define HOLISTIC__Record_Work_end \
   20.60         if(currVP){ \
   20.61                 uint64 cycles,instrs,cachem; \
   20.62                 saveCyclesAndInstrs(thisCoresIdx,cycles, instrs,cachem); \
   20.63 -               (*counterHandler)(Work_end,currVP->slaveID,currVP->numTimesAssignedToASlot,currVP,cycles,instrs,cachem); \
   20.64 +               (*counterHandler)(Work_end,currVP->slaveNum,currVP->numTimesAssignedToASlot,currVP,cycles,instrs,cachem); \
   20.65         }
   20.66  
   20.67     #define HOLISTIC__Record_HwResponderInvocation_start \
   20.68          uint64 cycles,instrs,cachem; \
   20.69          saveCyclesAndInstrs(animatingSlv->coreAnimatedBy,cycles, instrs,cachem); \
   20.70 -        (*(_PRTopEnv->counterHandler))(HwResponderInvocation_start,animatingSlv->slaveID,animatingSlv->numTimesAssignedToASlot,animatingSlv,cycles,instrs,cachem); 
   20.71 +        (*(_PRTopEnv->counterHandler))(HwResponderInvocation_start,animatingSlv->slaveNum,animatingSlv->numTimesAssignedToASlot,animatingSlv,cycles,instrs,cachem); 
   20.72          
   20.73  
   20.74     #define getReturnAddressBeforeLibraryCall(vp_ptr, res_ptr) do{     \
    21.1 --- a/Services_Offered_by_PR/Memory_Handling/vmalloc.c	Sun Nov 04 18:39:28 2012 -0800
    21.2 +++ b/Services_Offered_by_PR/Memory_Handling/vmalloc.c	Mon Jan 14 15:31:23 2013 -0800
    21.3 @@ -366,8 +366,7 @@
    21.4  PR_ext__create_free_list()
    21.5  {     
    21.6     //Initialize containers for small chunks and fill with zeros
    21.7 -   _PRTopEnv->freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) );
    21.8 -   MallocArrays *freeLists = _PRTopEnv->freeLists;
    21.9 +   MallocArrays *freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) );
   21.10     
   21.11     freeLists->smallChunks = 
   21.12             (MallocProlog**)malloc(SMALL_CHUNK_COUNT*sizeof(MallocProlog*));