changeset 26:a60399b62614 ML_dev

Update.. in middle of changes..
author Sean Halle <seanhalle@yahoo.com>
date Thu, 18 Oct 2012 02:44:30 -0700
parents 5bc52d3eae7d
children 3b30da4643d1
files Measurement/VSs_Counter_Recording.c Measurement/VSs_Counter_Recording.h Measurement/VSs_Measurement.h Measurement/dependency.c VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c VSs_Request_Handlers.h VSs_singleton_asm.s
diffstat 10 files changed, 515 insertions(+), 1058 deletions(-) [+]
line diff
     1.1 --- a/Measurement/VSs_Counter_Recording.c	Mon Sep 03 03:26:12 2012 -0700
     1.2 +++ b/Measurement/VSs_Counter_Recording.c	Thu Oct 18 02:44:30 2012 -0700
     1.3 @@ -4,18 +4,20 @@
     1.4   */
     1.5  
     1.6  #include "VSs_Counter_Recording.h"
     1.7 -#include "VMS_impl/VMS.h"
     1.8 +#include "PR_impl/PR.h"
     1.9  #include "VSs_impl/VSs.h"
    1.10  
    1.11  #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
    1.12  
    1.13 -void VSs__init_counter_data_structs(){
    1.14 -    VSsSemEnv *semanticEnv = _VMSMasterEnv->semanticEnv;
    1.15 -    int i;
    1.16 -    for(i=0;i<NUM_CORES;i++){
    1.17 -        semanticEnv->counterList[i] = makeListOfArrays(sizeof(CounterEvent), 128);
    1.18 +void VSs__init_counter_data_structs( SlaveVP *slave )
    1.19 + {
    1.20 +   VSsSemEnv *semanticEnv = 
    1.21 +                (VSsSemEnv *)PR_SS__give_sem_env_for( slave, VSs_MAGIC_NUMBER );
    1.22 +   int i;
    1.23 +   for(i=0;i<NUM_CORES;i++)
    1.24 +    { semanticEnv->counterList[i] = makeListOfArrays(sizeof(CounterEvent), 128);
    1.25      }
    1.26 -}
    1.27 + }
    1.28  
    1.29  void addToListOfArraysCounterEvent(CounterEvent value, ListOfArrays* list){
    1.30      int offset_in_fragment = list->next_free_index % list->num_entries_per_fragment; 
    1.31 @@ -36,7 +38,7 @@
    1.32          return;
    1.33       }
    1.34  
    1.35 -    VSsSemEnv *semanticEnv = _VMSMasterEnv->semanticEnv;
    1.36 +    VSsSemEnv *semanticEnv = _PRMasterEnv->semanticEnv;
    1.37              
    1.38      CounterEvent e;
    1.39      e.event_type = evt_type;
     2.1 --- a/Measurement/VSs_Counter_Recording.h	Mon Sep 03 03:26:12 2012 -0700
     2.2 +++ b/Measurement/VSs_Counter_Recording.h	Thu Oct 18 02:44:30 2012 -0700
     2.3 @@ -8,7 +8,7 @@
     2.4  #ifndef VSs_COUNTER_RECORDING_H
     2.5  #define	VSs_COUNTER_RECORDING_H
     2.6  
     2.7 -#include "VMS_impl/VMS.h"
     2.8 +#include "PR_impl/PR.h"
     2.9  
    2.10  typedef struct {
    2.11     int event_type;
     3.1 --- a/Measurement/VSs_Measurement.h	Mon Sep 03 03:26:12 2012 -0700
     3.2 +++ b/Measurement/VSs_Measurement.h	Thu Oct 18 02:44:30 2012 -0700
     3.3 @@ -26,8 +26,8 @@
     3.4     #define ReceiveOfTypeHistIdx   4
     3.5  
     3.6     #define MEAS__Make_Meas_Hists_for_Language \
     3.7 -      _VMSMasterEnv->measHistsInfo = \
     3.8 -                 makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \
     3.9 +      _PRMasterEnv->measHistsInfo = \
    3.10 +                 makePrivDynArrayOfSize( (void***)&(_PRMasterEnv->measHists), 200); \
    3.11         makeAMeasHist( SendFromToHistIdx,   "SendFromTo",    50, 0, 100 ) \
    3.12         makeAMeasHist( SendOfTypeHistIdx,   "SendOfType",    50, 0, 100 ) \
    3.13         makeAMeasHist( ReceiveFromToHistIdx,"ReceiveFromTo", 50, 0, 100 ) \
    3.14 @@ -40,7 +40,7 @@
    3.15     #define Meas_endSendFromTo \
    3.16         saveLowTimeStampCountInto( endStamp ); \
    3.17         addIntervalToHist( startStamp, endStamp, \
    3.18 -                                _VMSMasterEnv->measHists[ SendFromToHistIdx ] );
    3.19 +                                _PRMasterEnv->measHists[ SendFromToHistIdx ] );
    3.20  
    3.21     #define Meas_startSendOfType \
    3.22         int32 startStamp, endStamp; \
    3.23 @@ -49,7 +49,7 @@
    3.24     #define Meas_endSendOfType \
    3.25         saveLowTimeStampCountInto( endStamp ); \
    3.26         addIntervalToHist( startStamp, endStamp, \
    3.27 -                                _VMSMasterEnv->measHists[ SendOfTypeHistIdx ] );
    3.28 +                                _PRMasterEnv->measHists[ SendOfTypeHistIdx ] );
    3.29  
    3.30     #define Meas_startReceiveFromTo \
    3.31         int32 startStamp, endStamp; \
    3.32 @@ -58,7 +58,7 @@
    3.33     #define Meas_endReceiveFromTo \
    3.34         saveLowTimeStampCountInto( endStamp ); \
    3.35         addIntervalToHist( startStamp, endStamp, \
    3.36 -                                _VMSMasterEnv->measHists[ ReceiveFromToHistIdx ] );
    3.37 +                                _PRMasterEnv->measHists[ ReceiveFromToHistIdx ] );
    3.38  
    3.39     #define Meas_startReceiveOfType \
    3.40         int32 startStamp, endStamp; \
    3.41 @@ -67,7 +67,7 @@
    3.42     #define Meas_endReceiveOfType \
    3.43         saveLowTimeStampCountInto( endStamp ); \
    3.44         addIntervalToHist( startStamp, endStamp, \
    3.45 -                                _VMSMasterEnv->measHists[ReceiveOfTypeHistIdx ] );
    3.46 +                                _PRMasterEnv->measHists[ReceiveOfTypeHistIdx ] );
    3.47  
    3.48  #else //===================== turned off ==========================
    3.49  
     4.1 --- a/Measurement/dependency.c	Mon Sep 03 03:26:12 2012 -0700
     4.2 +++ b/Measurement/dependency.c	Thu Oct 18 02:44:30 2012 -0700
     4.3 @@ -1,8 +1,8 @@
     4.4  #include "dependency.h"
     4.5 -#include "VMS_impl/VMS.h"
     4.6 +#include "PR_impl/PR.h"
     4.7  
     4.8  Dependency* new_dependency(int from_vp, int from_task, int to_vp, int to_task){
     4.9 -    Dependency* newDep = (Dependency*) VMS_int__malloc(sizeof(Dependency));
    4.10 +    Dependency* newDep = (Dependency*) PR_int__malloc(sizeof(Dependency));
    4.11      if (newDep!=NULL){
    4.12          newDep->from_vp = from_vp;
    4.13          newDep->from_task = from_task;
    4.14 @@ -13,7 +13,7 @@
    4.15  }
    4.16  
    4.17  NtoN* new_NtoN(int id){
    4.18 -    NtoN* newn = (NtoN*) VMS_int__malloc(sizeof(NtoN));
    4.19 +    NtoN* newn = (NtoN*) PR_int__malloc(sizeof(NtoN));
    4.20      newn->id = id;
    4.21      newn->senders = makeListOfArrays(sizeof(Unit), 64);
    4.22      newn->receivers = makeListOfArrays(sizeof(Unit), 64);
     5.1 --- a/VSs.c	Mon Sep 03 03:26:12 2012 -0700
     5.2 +++ b/VSs.c	Thu Oct 18 02:44:30 2012 -0700
     5.3 @@ -16,11 +16,6 @@
     5.4  
     5.5  //==========================================================================
     5.6  
     5.7 -void
     5.8 -VSs__init();
     5.9 -
    5.10 -void
    5.11 -VSs__init_Helper();
    5.12  //==========================================================================
    5.13  
    5.14  
    5.15 @@ -31,8 +26,8 @@
    5.16  /*These are the library functions *called in the application*
    5.17   * 
    5.18   *There's a pattern for the outside sequential code to interact with the
    5.19 - * VMS_HW code.
    5.20 - *The VMS_HW system is inside a boundary..  every VSs system is in its
    5.21 + * PR_HW code.
    5.22 + *The PR_HW system is inside a boundary..  every VSs system is in its
    5.23   * own directory that contains the functions for each of the processor types.
    5.24   * One of the processor types is the "seed" processor that starts the
    5.25   * cascade of creating all the processors that do the work.
    5.26 @@ -58,60 +53,6 @@
    5.27  
    5.28  //===========================================================================
    5.29  
    5.30 -/*This is the "border crossing" function -- the thing that crosses from the
    5.31 - * outside world, into the VMS_HW world.  It initializes and starts up the
    5.32 - * VMS system, then creates one processor from the specified function and
    5.33 - * puts it into the readyQ.  From that point, that one function is resp.
    5.34 - * for creating all the other processors, that then create others, and so
    5.35 - * forth.
    5.36 - *When all the processors, including the seed, have dissipated, then this
    5.37 - * function returns.  The results will have been written by side-effect via
    5.38 - * pointers read from, or written into initData.
    5.39 - *
    5.40 - *NOTE: no Threads should exist in the outside program that might touch
    5.41 - * any of the data reachable from initData passed in to here
    5.42 - */
    5.43 -void
    5.44 -VSs__create_seed_slave_and_do_work( TopLevelFnPtr fnPtr, void *initData )
    5.45 - { VSsSemEnv   *semEnv;
    5.46 -   SlaveVP     *seedSlv;
    5.47 -   VSsSemData  *semData;
    5.48 -   VSsTaskStub *threadTaskStub, *parentTaskStub;
    5.49 -
    5.50 -   VSs__init();      //normal multi-thd
    5.51 -   
    5.52 -   semEnv = _VMSMasterEnv->semanticEnv;
    5.53 -
    5.54 -      //VSs starts with one processor, which is put into initial environ,
    5.55 -      // and which then calls create() to create more, thereby expanding work
    5.56 -   seedSlv = VSs__create_slave_helper( fnPtr, initData,
    5.57 -                                     semEnv, semEnv->nextCoreToGetNewSlv++ );
    5.58 -   
    5.59 -      //seed slave is a thread slave, so make a thread's task stub for it
    5.60 -      // and then make another to stand for the seed's parent task.  Make
    5.61 -      // the parent be already ended, and have one child (the seed).  This
    5.62 -      // will make the dissipate handler do the right thing when the seed
    5.63 -      // is dissipated.
    5.64 -   threadTaskStub = create_thread_task_stub( initData );
    5.65 -   parentTaskStub = create_thread_task_stub( NULL );
    5.66 -   parentTaskStub->isEnded = TRUE;
    5.67 -   parentTaskStub->numLiveChildThreads = 1; //so dissipate works for seed
    5.68 -   threadTaskStub->parentTaskStub = parentTaskStub;
    5.69 -   
    5.70 -   semData = (VSsSemData *)seedSlv->semanticData;
    5.71 -      //seedVP is a thread, so has a permanent task
    5.72 -   semData->needsTaskAssigned = FALSE;
    5.73 -   semData->taskStub = threadTaskStub;
    5.74 -   semData->slaveType = ThreadSlv;
    5.75 -
    5.76 -   resume_slaveVP( seedSlv, semEnv ); //returns right away, just queues Slv
    5.77 -   
    5.78 -   VMS_SS__start_the_work_then_wait_until_done();      //normal multi-thd
    5.79 -
    5.80 -   VSs__cleanup_after_shutdown();
    5.81 - }
    5.82 -
    5.83 -
    5.84  int32
    5.85  VSs__giveMinWorkUnitCycles( float32 percentOverhead )
    5.86   {
    5.87 @@ -134,9 +75,12 @@
    5.88   * saves jump point, and second jumps back several times to get reliable time
    5.89   */
    5.90  void
    5.91 -VSs__start_primitive()
    5.92 - { saveLowTimeStampCountInto( ((VSsSemEnv *)(_VMSMasterEnv->semanticEnv))->
    5.93 -                              primitiveStartTime );
    5.94 +VSs__begin_primitive()
    5.95 + { VSsSemData *semData;
    5.96 +   
    5.97 +   semData = (VSsSemData *)PR_WL__give_sem_data( animSlv, VSs_MAGIC_NUMBER);
    5.98 +
    5.99 +   saveLowTimeStampCountInto( semData->primitiveStartTime );
   5.100   }
   5.101  
   5.102  /*Just quick and dirty for now -- make reliable later
   5.103 @@ -145,262 +89,21 @@
   5.104   * also to throw out any "weird" values due to OS interrupt or TSC rollover
   5.105   */
   5.106  int32
   5.107 -VSs__end_primitive_and_give_cycles()
   5.108 +VSs__end_primitive_and_give_cycles( SlaveVP animSlv )
   5.109   { int32 endTime, startTime;
   5.110 +   VSsSemData *semData;
   5.111 +   
   5.112     //TODO: fix by repeating time-measurement
   5.113     saveLowTimeStampCountInto( endTime );
   5.114 -   startTime =((VSsSemEnv*)(_VMSMasterEnv->semanticEnv))->primitiveStartTime;
   5.115 +   semData = (VSsSemData *)PR_WL__give_sem_data( animSlv, VSs_MAGIC_NUMBER);
   5.116 +   startTime = semData->primitiveStartTime;
   5.117     return (endTime - startTime);
   5.118   }
   5.119  
   5.120 +
   5.121  //===========================================================================
   5.122  
   5.123 -/*Initializes all the data-structures for a VSs system -- but doesn't
   5.124 - * start it running yet!
   5.125 - *
   5.126 - *This runs in the main thread -- before VMS starts up
   5.127 - * 
   5.128 - *This sets up the semantic layer over the VMS system
   5.129 - *
   5.130 - *First, calls VMS_Setup, then creates own environment, making it ready
   5.131 - * for creating the seed processor and then starting the work.
   5.132 - */
   5.133 -void
   5.134 -VSs__init()
   5.135 - {
   5.136 -   VMS_SS__init();
   5.137 -      //masterEnv, a global var, now is partially set up by init_VMS
   5.138 -      // after this, have VMS_int__malloc and VMS_int__free available
   5.139  
   5.140 -   VSs__init_Helper();
   5.141 - }
   5.142 -
   5.143 -
   5.144 -void idle_fn(void* data, SlaveVP *animatingSlv){
   5.145 -    while(1){
   5.146 -        VMS_int__suspend_slaveVP_and_send_req(animatingSlv);
   5.147 -    }
   5.148 -}
   5.149 -
   5.150 -void
   5.151 -VSs__init_Helper()
   5.152 - { VSsSemEnv       *semanticEnv;
   5.153 -   int32            i, coreNum, slotNum;
   5.154 -   VSsSemData      *semData;
   5.155 - 
   5.156 -      //Hook up the semantic layer's plug-ins to the Master virt procr
   5.157 -   _VMSMasterEnv->requestHandler = &VSs__Request_Handler;
   5.158 -   _VMSMasterEnv->slaveAssigner  = &VSs__assign_slaveVP_to_slot;
   5.159 -
   5.160 -      //create the semantic layer's environment (all its data) and add to
   5.161 -      // the master environment
   5.162 -   semanticEnv = VMS_int__malloc( sizeof( VSsSemEnv ) );
   5.163 -   _VMSMasterEnv->semanticEnv = semanticEnv;
   5.164 -   
   5.165 -   #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
   5.166 -   _VMSMasterEnv->counterHandler = &VSs__counter_handler;
   5.167 -   VSs__init_counter_data_structs();
   5.168 -   #endif
   5.169 -
   5.170 -   semanticEnv->shutdownInitiated = FALSE;
   5.171 -   semanticEnv->coreIsDone = VMS_int__malloc( NUM_CORES * sizeof( bool32 ) );
   5.172 -      //For each animation slot, there is an idle slave, and an initial
   5.173 -      // slave assigned as the current-task-slave.  Create them here.
   5.174 -   SlaveVP *idleSlv, *slotTaskSlv;
   5.175 -   for( coreNum = 0; coreNum < NUM_CORES; coreNum++ )
   5.176 -    { semanticEnv->coreIsDone[coreNum] = FALSE; //use during shutdown
   5.177 -    
   5.178 -      for( slotNum = 0; slotNum < NUM_ANIM_SLOTS; ++slotNum )
   5.179 -       { idleSlv = VSs__create_slave_helper( &idle_fn, NULL, semanticEnv, 0);
   5.180 -         idleSlv->coreAnimatedBy                = coreNum;
   5.181 -         idleSlv->animSlotAssignedTo            =
   5.182 -                               _VMSMasterEnv->allAnimSlots[coreNum][slotNum];
   5.183 -         semanticEnv->idleSlv[coreNum][slotNum] = idleSlv;
   5.184 -         
   5.185 -         slotTaskSlv = VSs__create_slave_helper( &idle_fn, NULL, semanticEnv, 0);
   5.186 -         slotTaskSlv->coreAnimatedBy            = coreNum;
   5.187 -         slotTaskSlv->animSlotAssignedTo        = 
   5.188 -                               _VMSMasterEnv->allAnimSlots[coreNum][slotNum];
   5.189 -         
   5.190 -         semData                    = slotTaskSlv->semanticData;
   5.191 -         semData->needsTaskAssigned = TRUE;
   5.192 -         semData->slaveType         = SlotTaskSlv;
   5.193 -         semanticEnv->slotTaskSlvs[coreNum][slotNum] = slotTaskSlv;
   5.194 -       }
   5.195 -    }
   5.196 -
   5.197 -      //create the ready queues, hash tables used for matching and so forth
   5.198 -   semanticEnv->slavesReadyToResumeQ = makeVMSQ();
   5.199 -   semanticEnv->freeExtraTaskSlvQ    = makeVMSQ();
   5.200 -   semanticEnv->taskReadyQ           = makeVMSQ();
   5.201 -   
   5.202 -   semanticEnv->argPtrHashTbl  = makeHashTable32( 16, &VMS_int__free );
   5.203 -   semanticEnv->commHashTbl    = makeHashTable32( 16, &VMS_int__free );
   5.204 -   
   5.205 -   semanticEnv->nextCoreToGetNewSlv = 0;
   5.206 -   
   5.207 -
   5.208 -   //TODO: bug -- turn these arrays into dyn arrays to eliminate limit
   5.209 -   //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( );
   5.210 -   //semanticEnv->transactionStrucs = makeDynArrayInfo( );
   5.211 -   for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ )
   5.212 -    {
   5.213 -      semanticEnv->fnSingletons[i].endInstrAddr      = NULL;
   5.214 -      semanticEnv->fnSingletons[i].hasBeenStarted    = FALSE;
   5.215 -      semanticEnv->fnSingletons[i].hasFinished       = FALSE;
   5.216 -      semanticEnv->fnSingletons[i].waitQ             = makeVMSQ();
   5.217 -      semanticEnv->transactionStrucs[i].waitingVPQ   = makeVMSQ();
   5.218 -    }
   5.219 -
   5.220 -   semanticEnv->numLiveExtraTaskSlvs   = 0; //must be last
   5.221 -   semanticEnv->numLiveThreadSlvs      = 1; //must be last, counts the seed
   5.222 -
   5.223 -   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   5.224 -   semanticEnv->unitList = makeListOfArrays(sizeof(Unit),128);
   5.225 -   semanticEnv->ctlDependenciesList = makeListOfArrays(sizeof(Dependency),128);
   5.226 -   semanticEnv->commDependenciesList = makeListOfArrays(sizeof(Dependency),128);
   5.227 -   semanticEnv->dynDependenciesList = makeListOfArrays(sizeof(Dependency),128);
   5.228 -   semanticEnv->ntonGroupsInfo = makePrivDynArrayOfSize((void***)&(semanticEnv->ntonGroups),8);
   5.229 -   
   5.230 -   semanticEnv->hwArcs = makeListOfArrays(sizeof(Dependency),128);
   5.231 -   memset(semanticEnv->last_in_slot,0,sizeof(NUM_CORES * NUM_ANIM_SLOTS * sizeof(Unit)));
   5.232 -   #endif
   5.233 - }
   5.234 -
   5.235 -
   5.236 -/*Frees any memory allocated by VSs__init() then calls VMS_int__shutdown
   5.237 - */
   5.238 -void
   5.239 -VSs__cleanup_after_shutdown()
   5.240 - { VSsSemEnv *semanticEnv;
   5.241 -   
   5.242 -   semanticEnv = _VMSMasterEnv->semanticEnv;
   5.243 -
   5.244 -   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   5.245 -   //UCC
   5.246 -   FILE* output;
   5.247 -   int n;
   5.248 -   char filename[255];    
   5.249 -    for(n=0;n<255;n++)
   5.250 -    {
   5.251 -        sprintf(filename, "./counters/UCC.%d",n);
   5.252 -        output = fopen(filename,"r");
   5.253 -        if(output)
   5.254 -        {
   5.255 -            fclose(output);
   5.256 -        }else{
   5.257 -            break;
   5.258 -        }
   5.259 -    }
   5.260 -   if(n<255){
   5.261 -    printf("Saving UCC to File: %s ...\n", filename);
   5.262 -    output = fopen(filename,"w+");
   5.263 -    if(output!=NULL){
   5.264 -        set_dependency_file(output);
   5.265 -        //fprintf(output,"digraph Dependencies {\n");
   5.266 -        //set_dot_file(output);
   5.267 -        //FIXME:  first line still depends on counters being enabled, replace w/ unit struct!
   5.268 -        //forAllInDynArrayDo(_VMSMasterEnv->counter_history_array_info, &print_dot_node_info );
   5.269 -        forAllInListOfArraysDo(semanticEnv->unitList, &print_unit_to_file);
   5.270 -        forAllInListOfArraysDo( semanticEnv->commDependenciesList, &print_comm_dependency_to_file );
   5.271 -        forAllInListOfArraysDo( semanticEnv->ctlDependenciesList, &print_ctl_dependency_to_file );
   5.272 -        forAllInDynArrayDo(semanticEnv->ntonGroupsInfo,&print_nton_to_file);
   5.273 -        //fprintf(output,"}\n");
   5.274 -        fflush(output);
   5.275 -
   5.276 -    } else
   5.277 -        printf("Opening UCC file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n");
   5.278 -   } else {
   5.279 -       printf("Could not open UCC file, please clean \"counters\" folder. (Must contain less than 255 files.)\n");
   5.280 -   }
   5.281 -   //Loop Graph
   5.282 -   for(n=0;n<255;n++)
   5.283 -    {
   5.284 -        sprintf(filename, "./counters/LoopGraph.%d",n);
   5.285 -        output = fopen(filename,"r");
   5.286 -        if(output)
   5.287 -        {
   5.288 -            fclose(output);
   5.289 -        }else{
   5.290 -            break;
   5.291 -        }
   5.292 -    }
   5.293 -   if(n<255){
   5.294 -    printf("Saving LoopGraph to File: %s ...\n", filename);
   5.295 -    output = fopen(filename,"w+");
   5.296 -    if(output!=NULL){
   5.297 -        set_dependency_file(output);
   5.298 -        //fprintf(output,"digraph Dependencies {\n");
   5.299 -        //set_dot_file(output);
   5.300 -        //FIXME:  first line still depends on counters being enabled, replace w/ unit struct!
   5.301 -        //forAllInDynArrayDo(_VMSMasterEnv->counter_history_array_info, &print_dot_node_info );
   5.302 -        forAllInListOfArraysDo( semanticEnv->unitList, &print_unit_to_file );
   5.303 -        forAllInListOfArraysDo( semanticEnv->commDependenciesList, &print_comm_dependency_to_file );
   5.304 -        forAllInListOfArraysDo( semanticEnv->ctlDependenciesList, &print_ctl_dependency_to_file );
   5.305 -        forAllInListOfArraysDo( semanticEnv->dynDependenciesList, &print_dyn_dependency_to_file );
   5.306 -        forAllInListOfArraysDo( semanticEnv->hwArcs, &print_hw_dependency_to_file );
   5.307 -        //fprintf(output,"}\n");
   5.308 -        fflush(output);
   5.309 -
   5.310 -    } else
   5.311 -        printf("Opening LoopGraph file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n");
   5.312 -   } else {
   5.313 -       printf("Could not open LoopGraph file, please clean \"counters\" folder. (Must contain less than 255 files.)\n");
   5.314 -   }
   5.315 -   
   5.316 -   
   5.317 -   freeListOfArrays(semanticEnv->unitList);
   5.318 -   freeListOfArrays(semanticEnv->commDependenciesList);
   5.319 -   freeListOfArrays(semanticEnv->ctlDependenciesList);
   5.320 -   freeListOfArrays(semanticEnv->dynDependenciesList);
   5.321 -   
   5.322 -   #endif
   5.323 -#ifdef HOLISTIC__TURN_ON_PERF_COUNTERS    
   5.324 -    for(n=0;n<255;n++)
   5.325 -    {
   5.326 -        sprintf(filename, "./counters/Counters.%d.csv",n);
   5.327 -        output = fopen(filename,"r");
   5.328 -        if(output)
   5.329 -        {
   5.330 -            fclose(output);
   5.331 -        }else{
   5.332 -            break;
   5.333 -        }
   5.334 -    }
   5.335 -    if(n<255){
   5.336 -    printf("Saving Counter measurements to File: %s ...\n", filename);
   5.337 -    output = fopen(filename,"w+");
   5.338 -    if(output!=NULL){
   5.339 -        set_counter_file(output);
   5.340 -        int i;
   5.341 -        for(i=0;i<NUM_CORES;i++){
   5.342 -            forAllInListOfArraysDo( semanticEnv->counterList[i], &print_counter_events_to_file );
   5.343 -            fflush(output);
   5.344 -        }
   5.345 -
   5.346 -    } else
   5.347 -        printf("Opening UCC file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n");
   5.348 -   } else {
   5.349 -       printf("Could not open UCC file, please clean \"counters\" folder. (Must contain less than 255 files.)\n");
   5.350 -   }
   5.351 -    
   5.352 -#endif
   5.353 -/* It's all allocated inside VMS's big chunk -- that's about to be freed, so
   5.354 - *  nothing to do here
   5.355 -   
   5.356 -
   5.357 -   for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
   5.358 -    {
   5.359 -      VMS_int__free( semanticEnv->readyVPQs[coreIdx]->startOfData );
   5.360 -      VMS_int__free( semanticEnv->readyVPQs[coreIdx] );
   5.361 -    }
   5.362 -   VMS_int__free( semanticEnv->readyVPQs );
   5.363 -   
   5.364 -   freeHashTable( semanticEnv->commHashTbl );
   5.365 -   VMS_int__free( _VMSMasterEnv->semanticEnv );
   5.366 - */
   5.367 -   VMS_SS__cleanup_at_end_of_shutdown();
   5.368 - }
   5.369  
   5.370  
   5.371  //===========================================================================
   5.372 @@ -408,18 +111,33 @@
   5.373  SlaveVP *
   5.374  VSs__create_thread( TopLevelFnPtr fnPtr,   void *initData,
   5.375                          SlaveVP *creatingThd )
   5.376 + { 
   5.377 +   return VSs__create_thread_w_ID_and_affinity( fnPtr, initData, NO_ID,
   5.378 +                                                        ANY_CORE, creatingThd );
   5.379 + }
   5.380 +
   5.381 +SlaveVP *
   5.382 +VSs__create_thread_w_ID( TopLevelFnPtr fnPtr,   void *initData, int32 *thdID,
   5.383 +                         SlaveVP *creatingThd )
   5.384 + { 
   5.385 +   return VSs__create_thread_w_ID_and_affinity( fnPtr, initData, thdID, 
   5.386 +                                                        ANY_CORE, creatingThd );
   5.387 + }
   5.388 +
   5.389 +
   5.390 +SlaveVP *
   5.391 +VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr,   void *initData, 
   5.392 +                    int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd )
   5.393   { VSsSemReq reqData;
   5.394  
   5.395        //the semantic request data is on the stack and disappears when this
   5.396        // call returns -- it's guaranteed to remain in the VP's stack for as
   5.397        // long as the VP is suspended.
   5.398 -   reqData.reqType            = 0; //know type because in a VMS create req
   5.399 -   reqData.fnPtr              = fnPtr;
   5.400 -   reqData.initData           = initData;
   5.401 -   reqData.callingSlv         = creatingThd;
   5.402 -
   5.403 -   VMS_WL__send_create_slaveVP_req( &reqData, creatingThd );
   5.404 -
   5.405 +   reqData.reqType            = create_slave; //know type because in a PR create req
   5.406 +   reqData.coreToAssignOnto   = coreToAssignOnto;
   5.407 +   
   5.408 +   PR_WL__send_create_slaveVP_req( &reqData, fnPtr, initData, thdID, 
   5.409 +                                                creatingThd, VSs_MAGIC_NUMBER );
   5.410     return creatingThd->dataRetFromReq;
   5.411   }
   5.412  
   5.413 @@ -432,9 +150,8 @@
   5.414   */
   5.415  void
   5.416  VSs__end_thread( SlaveVP *thdToEnd )
   5.417 - { VSsSemData *semData;
   5.418 -   
   5.419 -   VMS_WL__send_dissipate_req( thdToEnd );
   5.420 + {    
   5.421 +   PR_WL__send_dissipate_req( thdToEnd, VSs_MAGIC_NUMBER );
   5.422   }
   5.423  
   5.424  
   5.425 @@ -454,34 +171,25 @@
   5.426     reqData.taskType   = taskType;
   5.427     reqData.args       = args;
   5.428     reqData.callingSlv = animSlv;
   5.429 -  
   5.430 -   reqData.taskID     = NULL;
   5.431 - 
   5.432 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.433 - }
   5.434 -
   5.435 -inline int32 *
   5.436 -VSs__create_taskID_of_size( int32 numInts, SlaveVP *animSlv )
   5.437 - { int32 *taskID;
   5.438     
   5.439 -   taskID    = VMS_WL__malloc( sizeof(int32) + numInts * sizeof(int32) );
   5.440 -   taskID[0] = numInts;
   5.441 -   return taskID;
   5.442 +      //Create task is a special form, so have to pass as parameters, the
   5.443 +      // top-level-fn of task and the data for that fn, plus lang's req,
   5.444 +      // animating slave, and lang's magic number
   5.445 +   PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID, animSlv, VSs_MAGIC_NUMBER );
   5.446   }
   5.447  
   5.448  void
   5.449  VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, 
   5.450                            SlaveVP     *animSlv)
   5.451   { VSsSemReq  reqData;
   5.452 -
   5.453 + 
   5.454     reqData.reqType    = submit_task;
   5.455     
   5.456     reqData.taskType   = taskType;
   5.457     reqData.args       = args;
   5.458 -   reqData.taskID     = taskID;
   5.459     reqData.callingSlv = animSlv;
   5.460   
   5.461 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.462 +   PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID, animSlv, VSs_MAGIC_NUMBER );
   5.463   }
   5.464  
   5.465  
   5.466 @@ -490,8 +198,8 @@
   5.467   * assigner here.. only one slave, no slave ReadyQ, and so on..
   5.468   *Can either make the assigner take the next task out of the taskQ, or can
   5.469   * leave all as it is, and make task-end take the next task.
   5.470 - *Note: this fits the case in the new VMS for no-context tasks, so will use
   5.471 - * the built-in taskQ of new VMS, and should be local and much faster.
   5.472 + *Note: this fits the case in the new PR for no-context tasks, so will use
   5.473 + * the built-in taskQ of new PR, and should be local and much faster.
   5.474   * 
   5.475   *The task-stub is saved in the animSlv, so the request handler will get it
   5.476   * from there, along with the task-type which has arg types, and so on..
   5.477 @@ -500,7 +208,7 @@
   5.478   * instead, can make a single slave per core, and coreCtrlr looks up the
   5.479   * slave from having the core number.
   5.480   * 
   5.481 - *But, to stay compatible with all the other VMS languages, leave it in..
   5.482 + *But, to stay compatible with all the other PR languages, leave it in..
   5.483   */
   5.484  void
   5.485  VSs__end_task( SlaveVP *animSlv )
   5.486 @@ -509,20 +217,23 @@
   5.487     reqData.reqType      = end_task;
   5.488     reqData.callingSlv   = animSlv;
   5.489     
   5.490 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.491 +   PR_WL__send_end_task_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.492   }
   5.493  
   5.494  
   5.495 +/*Waits for all tasks that are direct children to end, then resumes calling
   5.496 + * task or thread
   5.497 + */
   5.498  void
   5.499  VSs__taskwait(SlaveVP *animSlv)
   5.500 -{
   5.501 + {
   5.502      VSsSemReq  reqData;
   5.503  
   5.504     reqData.reqType      = taskwait;
   5.505     reqData.callingSlv   = animSlv;
   5.506     
   5.507 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.508 -}
   5.509 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.510 + }
   5.511  
   5.512  
   5.513  
   5.514 @@ -532,7 +243,7 @@
   5.515  inline int32 *
   5.516  VSs__give_self_taskID( SlaveVP *animSlv )
   5.517   {
   5.518 -   return ((VSsSemData*)animSlv->semanticData)->taskStub->taskID;
   5.519 +   return PR__give_task_ID( animSlv, VSs_MAGIC_NUMBER );
   5.520   }
   5.521  
   5.522  //================================ send ===================================
   5.523 @@ -551,7 +262,7 @@
   5.524     
   5.525     reqData.nextReqInHashEntry = NULL;
   5.526  
   5.527 -   VMS_WL__send_sem_request( &reqData, senderSlv );
   5.528 +   PR_WL__send_sem_request( &reqData, senderSlv, VSs_MAGIC_NUMBER );
   5.529  
   5.530        //When come back from suspend, no longer own data reachable from msg
   5.531   }
   5.532 @@ -569,7 +280,7 @@
   5.533  
   5.534     reqData.nextReqInHashEntry = NULL;
   5.535  
   5.536 -   VMS_WL__send_sem_request( &reqData, senderSlv );
   5.537 +   PR_WL__send_sem_request( &reqData, senderSlv, VSs_MAGIC_NUMBER );
   5.538   }
   5.539  
   5.540  
   5.541 @@ -594,7 +305,7 @@
   5.542     
   5.543     reqData.nextReqInHashEntry = NULL;
   5.544  
   5.545 -   VMS_WL__send_sem_request( &reqData, receiverSlv );
   5.546 +   PR_WL__send_sem_request( &reqData, receiverSlv, VSs_MAGIC_NUMBER );
   5.547     
   5.548     return receiverSlv->dataRetFromReq;
   5.549   }
   5.550 @@ -619,7 +330,7 @@
   5.551     reqData.nextReqInHashEntry = NULL;
   5.552        DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]);
   5.553        
   5.554 -   VMS_WL__send_sem_request( &reqData, receiverSlv );
   5.555 +   PR_WL__send_sem_request( &reqData, receiverSlv, VSs_MAGIC_NUMBER );
   5.556  
   5.557     return receiverSlv->dataRetFromReq;
   5.558   }
   5.559 @@ -655,10 +366,10 @@
   5.560     reqData.reqType     = singleton_fn_start;
   5.561     reqData.singletonID = singletonID;
   5.562  
   5.563 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.564 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.565     if( animSlv->dataRetFromReq ) //will be 0 or addr of label in end singleton
   5.566      {
   5.567 -       VSsSemEnv *semEnv = VMS_int__give_sem_env_for( animSlv );
   5.568 +       VSsSemEnv *semEnv = PR_WL__give_sem_env_for( animSlv, VSs_MAGIC_NUMBER );
   5.569         asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID]));
   5.570      }
   5.571   }
   5.572 @@ -678,7 +389,7 @@
   5.573     reqData.reqType          = singleton_data_start;
   5.574     reqData.singletonPtrAddr = singletonAddr;
   5.575  
   5.576 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.577 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.578     if( animSlv->dataRetFromReq ) //either 0 or end singleton's return addr
   5.579      {    //Assembly code changes the return addr on the stack to the one
   5.580           // saved into the singleton by the end-singleton-fn
   5.581 @@ -703,13 +414,13 @@
   5.582  
   5.583        //don't need this addr until after at least one singleton has reached
   5.584        // this function
   5.585 -   VSsSemEnv *semEnv = VMS_int__give_sem_env_for( animSlv );
   5.586 +   VSsSemEnv *semEnv = PR_WL__give_sem_env_for( animSlv, VSs_MAGIC_NUMBER );
   5.587     asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID]));
   5.588  
   5.589     reqData.reqType     = singleton_fn_end;
   5.590     reqData.singletonID = singletonID;
   5.591  
   5.592 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.593 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.594  
   5.595  EndSingletonInstrAddr:
   5.596     return;
   5.597 @@ -726,15 +437,12 @@
   5.598        // data singleton -- that data-singleton can only be given to exactly
   5.599        // one instance in the code of this function.  However, can use this
   5.600        // function in different places for different data-singletons.
   5.601 -//   (*(singletonAddr))->endInstrAddr =  &&EndDataSingletonInstrAddr;
   5.602 -
   5.603 -
   5.604     asm_save_ret_to_singleton(*singletonPtrAddr);
   5.605  
   5.606     reqData.reqType          = singleton_data_end;
   5.607     reqData.singletonPtrAddr = singletonPtrAddr;
   5.608  
   5.609 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.610 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.611   }
   5.612  
   5.613  /*This executes the function in the masterVP, so it executes in isolation
   5.614 @@ -758,7 +466,7 @@
   5.615     reqData.fnToExecInMaster = ptrToFnToExecInMaster;
   5.616     reqData.dataForFn        = data;
   5.617  
   5.618 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.619 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.620   }
   5.621  
   5.622  
   5.623 @@ -781,11 +489,11 @@
   5.624     VSsSemReq  reqData;
   5.625  
   5.626        //
   5.627 -   reqData.callingSlv      = animSlv;
   5.628 +   reqData.callingSlv  = animSlv;
   5.629     reqData.reqType     = trans_start;
   5.630     reqData.transID     = transactionID;
   5.631  
   5.632 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.633 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.634   }
   5.635  
   5.636  /*This suspends to the master, then uses transactionID as index into an
   5.637 @@ -807,30 +515,12 @@
   5.638     reqData.reqType     = trans_end;
   5.639     reqData.transID     = transactionID;
   5.640  
   5.641 -   VMS_WL__send_sem_request( &reqData, animSlv );
   5.642 +   PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER );
   5.643   }
   5.644  
   5.645  //======================== Internal ==================================
   5.646  /*
   5.647   */
   5.648 -SlaveVP *
   5.649 -VSs__create_slave_with( TopLevelFnPtr fnPtr,   void *initData,
   5.650 -                        SlaveVP *creatingSlv )
   5.651 - { VSsSemReq reqData;
   5.652 -
   5.653 -      //the semantic request data is on the stack and disappears when this
   5.654 -      // call returns -- it's guaranteed to remain in the VP's stack for as
   5.655 -      // long as the VP is suspended.
   5.656 -   reqData.reqType            = 0; //know type because in a VMS create req
   5.657 -   reqData.coreToAssignOnto = -1; //means round-robin assign
   5.658 -   reqData.fnPtr              = fnPtr;
   5.659 -   reqData.initData           = initData;
   5.660 -   reqData.callingSlv             = creatingSlv;
   5.661 -
   5.662 -   VMS_WL__send_create_slaveVP_req( &reqData, creatingSlv );
   5.663 -
   5.664 -   return creatingSlv->dataRetFromReq;
   5.665 - }
   5.666  
   5.667  SlaveVP *
   5.668  VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData,
   5.669 @@ -846,7 +536,7 @@
   5.670     reqData.initData           = initData;
   5.671     reqData.callingSlv         = creatingSlv;
   5.672  
   5.673 -   VMS_WL__send_create_slaveVP_req( &reqData, creatingSlv );
   5.674 +   PR_WL__send_create_slaveVP_req( &reqData, creatingSlv, VSs_MAGIC_NUMBER );
   5.675  
   5.676     return creatingSlv->dataRetFromReq;
   5.677   }
     6.1 --- a/VSs.h	Mon Sep 03 03:26:12 2012 -0700
     6.2 +++ b/VSs.h	Thu Oct 18 02:44:30 2012 -0700
     6.3 @@ -11,24 +11,28 @@
     6.4  
     6.5  #include "Queue_impl/PrivateQueue.h"
     6.6  #include "Hash_impl/PrivateHash.h"
     6.7 -#include "VMS_impl/VMS.h"
     6.8 +#include "PR_impl/PR.h"
     6.9  #include "Measurement/dependency.h"
    6.10  
    6.11  
    6.12  //===========================================================================
    6.13 +   //uniquely identifies VSs -- should be a jenkins char-hash of "VSs" to int32
    6.14 +#define VSs_MAGIC_NUMBER 0000000001
    6.15 +
    6.16  #define NUM_STRUCS_IN_SEM_ENV 1000
    6.17  
    6.18     //This is hardware dependent -- it's the number of cycles of scheduling
    6.19     // overhead -- if a work unit is fewer than this, it is better being
    6.20     // combined sequentially with other work
    6.21 -   //This value depends on both VMS overhead and VSs's plugin.  At some point
    6.22 +   //This value depends on both PR overhead and VSs's plugin.  At some point
    6.23     // it will be derived by perf-counter measurements during init of VSs
    6.24  #define MIN_WORK_UNIT_CYCLES 20000
    6.25  
    6.26  //===========================================================================
    6.27  /*This header defines everything specific to the VSs semantic plug-in
    6.28   */
    6.29 -typedef struct _VSsSemReq   VSsSemReq;
    6.30 +typedef struct _VSsSemReq    VSsSemReq;
    6.31 +typedef struct _VSsTaskStub  VSsTaskStub;
    6.32  typedef void  (*VSsTaskFnPtr )   ( void *, SlaveVP *);
    6.33  typedef void  (*PtrToAtomicFn )  ( void * ); //executed atomically in master
    6.34  //===========================================================================
    6.35 @@ -45,6 +49,10 @@
    6.36  #define IS_ENDED    NULL
    6.37  #define SEED_SLV    NULL
    6.38  
    6.39 +#define NO_ID       NULL
    6.40 +#define ANY_CORE    -1
    6.41 +
    6.42 +//===========================================================================
    6.43  typedef struct
    6.44   {
    6.45     VSsTaskFnPtr fn;
    6.46 @@ -65,22 +73,24 @@
    6.47   }
    6.48  VSsPointerEntry;
    6.49  
    6.50 -typedef struct
    6.51 +/*This is placed into semData, used for dependencies and wait construct*/
    6.52 +struct _VSsTaskStub
    6.53   {
    6.54 -   void       **args; //ctld args must come first, as ptrs
    6.55 -   VSsTaskType *taskType;
    6.56 -   int32       *taskID;
    6.57 -   int32        numBlockingProp;
    6.58 -   SlaveVP     *slaveAssignedTo; //only valid before end task (thread)
    6.59 -   VSsPointerEntry  **ptrEntries;
    6.60 -   void*        parentTaskStub;
    6.61 +   int32             langMagicNumber; //magic num must be 1st field of langMetaTask
    6.62 +   PRMetaTask       *protoMetaTask;   //back-link must always be 2nd field
    6.63 +   void            **args;            //ctld args must be the first ones (as ptrs)
    6.64 +   VSsPointerEntry **ptrEntries;
    6.65 +   int32             numBlockingProp;
    6.66 +   
    6.67 +   VSsTaskType *taskType; //has VSs lang related info
    6.68 +   
    6.69 +   VSsTaskStub *parentTaskStub; //for liveness, for the wait construct
    6.70     int32        numLiveChildTasks;
    6.71     int32        numLiveChildThreads;
    6.72     bool32       isWaitingForChildTasksToEnd;
    6.73     bool32       isWaitingForChildThreadsToEnd;
    6.74     bool32       isEnded;
    6.75 - }
    6.76 -VSsTaskStub;
    6.77 + };
    6.78  
    6.79  
    6.80  typedef struct
    6.81 @@ -144,7 +154,7 @@
    6.82     SlaveVP           *callingSlv;
    6.83     VSsTaskType       *taskType;
    6.84     void              *args;
    6.85 -   VSsTaskStub       *taskStub;
    6.86 +//   VSsTaskStub       *taskStub;  //not needed -- get via PR accessor from slv
    6.87     
    6.88     SlaveVP           *senderSlv;
    6.89     SlaveVP           *receiverSlv;
    6.90 @@ -153,12 +163,13 @@
    6.91     int32              msgType;
    6.92     void              *msg;
    6.93     VSsSemReq         *nextReqInHashEntry;
    6.94 -   int32             *taskID;
    6.95 +//In PRReq:   int32             *taskID;
    6.96     
    6.97     TopLevelFnPtr      fnPtr;
    6.98     void              *initData;
    6.99     int32              coreToAssignOnto;
   6.100  
   6.101 +//These, below, should move to util language..
   6.102     int32              sizeToMalloc;
   6.103     void              *ptrToFree;
   6.104  
   6.105 @@ -174,15 +185,15 @@
   6.106  
   6.107  
   6.108  typedef struct
   6.109 - {
   6.110 + { PRSemEnv        *protoSemEnv;
   6.111     PrivQueueStruc  *slavesReadyToResumeQ; //Shared (slaves not pinned)
   6.112 -   PrivQueueStruc  *freeExtraTaskSlvQ;    //Shared
   6.113 +   PrivQueueStruc  *freeTaskSlvRecycleQ;    //Shared
   6.114     PrivQueueStruc  *taskReadyQ;           //Shared (tasks not pinned)
   6.115 -   SlaveVP         *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
   6.116 +//   SlaveVP         *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
   6.117     HashTable       *argPtrHashTbl;
   6.118     HashTable       *commHashTbl;
   6.119 -   int32            numLiveExtraTaskSlvs;
   6.120 -   int32            numLiveThreadSlvs;
   6.121 +//   int32            numLiveFreeTaskSlvs;
   6.122 +//   int32            numLiveThreadSlvs;
   6.123     int32            nextCoreToGetNewSlv;
   6.124     int32            primitiveStartTime;
   6.125  
   6.126 @@ -190,8 +201,11 @@
   6.127     VSsSingleton     fnSingletons[NUM_STRUCS_IN_SEM_ENV];
   6.128     VSsTrans         transactionStrucs[NUM_STRUCS_IN_SEM_ENV];
   6.129  
   6.130 -   bool32          *coreIsDone;
   6.131 -   int32            numCoresDone;
   6.132 +//   bool32          *coreIsDone;
   6.133 +//   int32            numCoresDone;
   6.134 +   
   6.135 +//   SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
   6.136 +//   int shutdownInitiated;
   6.137     
   6.138     #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   6.139     ListOfArrays* unitList;
   6.140 @@ -207,8 +221,6 @@
   6.141     #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
   6.142     ListOfArrays* counterList[NUM_CORES];
   6.143     #endif
   6.144 -   SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
   6.145 -   int shutdownInitiated;
   6.146   }
   6.147  VSsSemEnv;
   6.148  
   6.149 @@ -221,19 +233,20 @@
   6.150   };
   6.151  //TransListElem
   6.152   
   6.153 +/* PR now handles what this used to be used for
   6.154  enum VSsSlvType
   6.155 - { ExtraTaskSlv = 1,
   6.156 + { FreeTaskSlv = 1,
   6.157     SlotTaskSlv,
   6.158     ThreadSlv
   6.159   };
   6.160 +*/
   6.161   
   6.162  typedef struct
   6.163   {
   6.164 -   int32           highestTransEntered;
   6.165 -   TransListElem  *lastTransEntered;
   6.166 -   bool32          needsTaskAssigned;
   6.167 -   VSsTaskStub    *taskStub;
   6.168 -   enum VSsSlvType slaveType;
   6.169 +   int32            highestTransEntered;
   6.170 +   TransListElem   *lastTransEntered;
   6.171 +   int32            primitiveStartTime;
   6.172 +//   VSsTaskStub     *taskStub; //get from slave via PR accessor
   6.173   }
   6.174  VSsSemData;
   6.175   
   6.176 @@ -246,7 +259,7 @@
   6.177  VSs__giveMinWorkUnitCycles( float32 percentOverhead );
   6.178  
   6.179  void
   6.180 -VSs__start_primitive();
   6.181 +VSs__begin_primitive();
   6.182  
   6.183  int32
   6.184  VSs__end_primitive_and_give_cycles();
   6.185 @@ -260,7 +273,7 @@
   6.186  //=======================
   6.187  
   6.188  void
   6.189 -VSs__init();
   6.190 +VSs__start( SlaveVP *seedSlv );
   6.191  
   6.192  void
   6.193  VSs__cleanup_after_shutdown();
   6.194 @@ -276,9 +289,9 @@
   6.195  
   6.196  //=======================
   6.197  
   6.198 -#define VSs__malloc( numBytes, callingSlave ) VMS_App__malloc( numBytes, callingSlave)
   6.199 +#define VSs__malloc( numBytes, callingSlave ) PR_App__malloc( numBytes, callingSlave)
   6.200  
   6.201 -#define VSs__free(ptrToFree, callingSlave ) VMS_App__free( ptrToFree, callingSlave )
   6.202 +#define VSs__free(ptrToFree, callingSlave ) PR_App__free( ptrToFree, callingSlave )
   6.203  
   6.204  
   6.205  //=======================
   6.206 @@ -351,8 +364,8 @@
   6.207  VSs__create_slave_helper( TopLevelFnPtr fnPtr, void *initData,
   6.208                            VSsSemEnv *semEnv,    int32 coreToAssignOnto );
   6.209  
   6.210 -VSsTaskStub *
   6.211 -create_thread_task_stub( void *initData );
   6.212 +PRMetaTask *
   6.213 +PR_int__create_generic_slave_meta_task( void *initData );
   6.214  
   6.215  
   6.216  SlaveVP *
   6.217 @@ -363,9 +376,6 @@
   6.218  VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr,    void *initData,
   6.219                              SlaveVP *creatingSlv, int32 coreToAssignOnto);
   6.220  
   6.221 -void 
   6.222 -idle_fn(void* data, SlaveVP *animatingSlv);
   6.223 -
   6.224  //=====================  Measurement of Lang Overheads  =====================
   6.225  #include "Measurement/VSs_Measurement.h"
   6.226  
     7.1 --- a/VSs_PluginFns.c	Mon Sep 03 03:26:12 2012 -0700
     7.2 +++ b/VSs_PluginFns.c	Thu Oct 18 02:44:30 2012 -0700
     7.3 @@ -16,13 +16,13 @@
     7.4  resume_slaveVP( SlaveVP *slave, VSsSemEnv *semEnv );
     7.5  
     7.6  inline void
     7.7 -handleSemReq( VMSReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv );
     7.8 +handleSemReq( PRReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv );
     7.9  
    7.10  inline void
    7.11  handleDissipate(                SlaveVP *requestingSlv, VSsSemEnv *semEnv );
    7.12  
    7.13  inline void
    7.14 -handleCreate(    VMSReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv );
    7.15 +handleCreate(    PRReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv );
    7.16  
    7.17  //============================== Assigner ==================================
    7.18  //
    7.19 @@ -30,6 +30,9 @@
    7.20   * VPs, and by tasks being able to suspend.
    7.21   *It can't use an explicit slave to animate a task because of stack
    7.22   * pollution. So, it has to keep the two kinds separate.
    7.23 + * 
    7.24 + *Q: one assigner for both tasks and slaves, or separate?
    7.25 + * 
    7.26   *Simplest way for the assigner logic is with a Q for extra empty task
    7.27   * slaves, and another Q for slaves of both types that are ready to resume.
    7.28   *
    7.29 @@ -52,10 +55,8 @@
    7.30  VSs__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot )
    7.31   { SlaveVP     *returnSlv;
    7.32     VSsSemEnv   *semEnv;
    7.33 -   VSsSemData  *semData;
    7.34     int32        coreNum, slotNum;
    7.35 -   VSsTaskStub *newTaskStub;
    7.36 -   SlaveVP     *extraSlv;
    7.37 +   PRMetaTask  *returnMetaTask = NULL, *newTaskStub;
    7.38    
    7.39     coreNum = slot->coreSlotIsOn;
    7.40     slotNum = slot->slotIdx;
    7.41 @@ -66,173 +67,79 @@
    7.42     returnSlv = readPrivQ( semEnv->slavesReadyToResumeQ );
    7.43     if( returnSlv != NULL )  //Yes, have a slave, so return it.
    7.44      { returnSlv->coreAnimatedBy   = coreNum;
    7.45 -    
    7.46 -         //have work, so reset Done flag (when work generated on other core)
    7.47 -      if( semEnv->coreIsDone[coreNum] == TRUE ) //reads are higher perf
    7.48 -         semEnv->coreIsDone[coreNum] = FALSE;   //don't just write always
    7.49 -      goto ReturnTheSlv;
    7.50 +      returnMetaTask = returnSlv->metaTask;
    7.51 +      goto ReturnTheMetaTask;
    7.52      }
    7.53     
    7.54 -      //If none, speculate will have a task, so get the slot slave
    7.55 -      //TODO: false sharing ?  (think not bad cause mostly read..)
    7.56 -   returnSlv = semEnv->slotTaskSlvs[coreNum][slotNum];
    7.57 -   
    7.58 -   semData = (VSsSemData *)returnSlv->semanticData;
    7.59 -
    7.60 -      //There is always a curr task slave, and it always needs a task
    7.61 -      // (task slaves that are resuming are in resumeQ)
    7.62     newTaskStub = readPrivQ( semEnv->taskReadyQ );
    7.63     if( newTaskStub != NULL )
    7.64 -    {    //point slave to task's function, and mark slave as having task
    7.65 -      VMS_int__reset_slaveVP_to_TopLvlFn( returnSlv, 
    7.66 -                          newTaskStub->taskType->fn, newTaskStub->args );
    7.67 -      semData->taskStub            = newTaskStub;
    7.68 -      newTaskStub->slaveAssignedTo = returnSlv;
    7.69 -      semData->needsTaskAssigned   = FALSE;
    7.70 -      
    7.71 -         //have work, so reset Done flag, if was set
    7.72 -      if( semEnv->coreIsDone[coreNum] == TRUE ) //reads are higher perf
    7.73 -         semEnv->coreIsDone[coreNum] = FALSE;   //don't just write always
    7.74 -      goto ReturnTheSlv;
    7.75 +    { returnMetaTask = newTaskStub->protoMetaTask;
    7.76 +      goto ReturnTheMetaTask;
    7.77      }
    7.78 -   else
    7.79 -    {    //no task, so try to clean up unused extra task slaves
    7.80 -      extraSlv = readPrivQ( semEnv->freeExtraTaskSlvQ );
    7.81 -      if( extraSlv != NULL )
    7.82 -       {    //have two slaves need tasks, so delete one
    7.83 -            //This both bounds the num extras, and delivers shutdown cond
    7.84 -         handleDissipate( extraSlv, semEnv );
    7.85 -            //then return NULL
    7.86 -         returnSlv = NULL;
    7.87 -         goto ReturnTheSlv;
    7.88 -       }
    7.89 -      else
    7.90 -       { //candidate for shutdown.. if all extras dissipated, and no tasks
    7.91 -         // and no ready to resume slaves, then no way to generate
    7.92 -         // more tasks (on this core -- other core might have task still)
    7.93 -         if( semEnv->numLiveExtraTaskSlvs == 0 && 
    7.94 -             semEnv->numLiveThreadSlvs == 0 )
    7.95 -          { //This core sees no way to generate more tasks, so say it
    7.96 -            if( semEnv->coreIsDone[coreNum] == FALSE )
    7.97 -             { semEnv->numCoresDone += 1;
    7.98 -               semEnv->coreIsDone[coreNum] = TRUE;
    7.99 -               #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   7.100 -               semEnv->shutdownInitiated = TRUE;
   7.101 -               
   7.102 -               #else
   7.103 -               if( semEnv->numCoresDone == NUM_CORES )
   7.104 -                { //means no cores have work, and none can generate more
   7.105 -                  semEnv->shutdownInitiated = TRUE;
   7.106 -                }
   7.107 -               #endif
   7.108 -             }
   7.109 -          }
   7.110 -            //return NULL.. no task and none to resume
   7.111 -         returnSlv = NULL;
   7.112 -            //except if shutdown has been initiated by this or other core
   7.113 -         if(semEnv->shutdownInitiated) 
   7.114 -          { returnSlv = VMS_SS__create_shutdown_slave();
   7.115 -          }
   7.116 -         goto ReturnTheSlv; //don't need, but completes pattern
   7.117 -       } //if( extraSlv != NULL )
   7.118 -    } //if( newTaskStub == NULL )
   7.119 -   //outcome: 1)slave was just pointed to task, 2)no tasks, so slave NULL
   7.120  
   7.121 -ReturnTheSlv:  //Nina, doing gotos to here should help with holistic..
   7.122 +ReturnTheMetaTask:  //doing gotos to here should help with holistic..
   7.123  
   7.124     #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   7.125 -   if( returnSlv == NULL )
   7.126 -    { returnSlv = semEnv->idleSlv[coreNum][slotNum]; 
   7.127 +   //This no longer works -- should be moved into PR in master
   7.128 +   //This assumes the task has already been assigned to a slave, which happens
   7.129 +   // inside Master..
   7.130 +   if( returnMetaTask == NULL )
   7.131 +    { returnSlv = semEnv->process->idleSlv[coreNum][slotNum]; 
   7.132      
   7.133           //things that would normally happen in resume(), but these VPs
   7.134           // never go there
   7.135 -      returnSlv->assignCount++; //Somewhere here!
   7.136 -      Unit newu;
   7.137 -      newu.vp = returnSlv->slaveID;
   7.138 -      newu.task = returnSlv->assignCount;
   7.139 -      addToListOfArrays(Unit,newu,semEnv->unitList);
   7.140 +      returnSlv->numTimesAssignedToASlot++;
   7.141 +      Unit newU;
   7.142 +      newU.vp = returnSlv->slaveID;
   7.143 +      newU.task = returnSlv->numTimesAssignedToASlot;
   7.144 +      addToListOfArrays(Unit,newU,semEnv->unitList);
   7.145  
   7.146 -      if (returnSlv->assignCount > 1)
   7.147 -       { Dependency newd;
   7.148 -         newd.from_vp = returnSlv->slaveID;
   7.149 -         newd.from_task = returnSlv->assignCount - 1;
   7.150 -         newd.to_vp = returnSlv->slaveID;
   7.151 -         newd.to_task = returnSlv->assignCount;
   7.152 -         addToListOfArrays(Dependency, newd ,semEnv->ctlDependenciesList);  
   7.153 +      if (returnSlv->numTimesAssignedToASlot > 1)
   7.154 +       { Dependency newD;
   7.155 +         newD.from_vp = returnSlv->slaveID;
   7.156 +         newD.from_task = returnSlv->numTimesAssignedToASlot - 1;
   7.157 +         newD.to_vp = returnSlv->slaveID;
   7.158 +         newD.to_task = returnSlv->numTimesAssignedToASlot;
   7.159 +         addToListOfArrays(Dependency, newD, semEnv->ctlDependenciesList);  
   7.160         }
   7.161 +      returnMetaTask = returnSlv->metaTask;
   7.162      }
   7.163 -   #endif
   7.164 -   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   7.165 -   if( returnSlv != NULL )
   7.166 +   else //returnSlv != NULL
   7.167      { //assignSlv->numTimesAssigned++;
   7.168        Unit prev_in_slot = 
   7.169           semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum];
   7.170        if(prev_in_slot.vp != 0)
   7.171 -       { Dependency newd;
   7.172 -         newd.from_vp = prev_in_slot.vp;
   7.173 -         newd.from_task = prev_in_slot.task;
   7.174 -         newd.to_vp = returnSlv->slaveID;
   7.175 -         newd.to_task = returnSlv->assignCount;
   7.176 -         addToListOfArrays(Dependency,newd,semEnv->hwArcs);   
   7.177 +       { Dependency newD;
   7.178 +         newD.from_vp = prev_in_slot.vp;
   7.179 +         newD.from_task = prev_in_slot.task;
   7.180 +         newD.to_vp = returnSlv->slaveID;
   7.181 +         newD.to_task = returnSlv->numTimesAssignedToASlot;
   7.182 +         addToListOfArrays(Dependency,newD,semEnv->hwArcs);   
   7.183         }
   7.184        prev_in_slot.vp = returnSlv->slaveID;
   7.185 -      prev_in_slot.task = returnSlv->assignCount;
   7.186 +      prev_in_slot.task = returnSlv->numTimesAssignedToASlot;
   7.187        semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] =
   7.188           prev_in_slot;        
   7.189      }
   7.190     #endif
   7.191 -   return( returnSlv );
   7.192 +   return( returnMetaTask );
   7.193   }
   7.194  
   7.195  
   7.196  //===========================  Request Handler  ============================
   7.197  //
   7.198  /*
   7.199 - * (BTW not inline because invoked indirectly via a pointer)
   7.200 + * (Not inline because invoked indirectly via a pointer)
   7.201   */
   7.202 +
   7.203  void
   7.204 -VSs__Request_Handler( SlaveVP *requestingSlv, void *_semEnv )
   7.205 - { VSsSemEnv *semEnv;
   7.206 -   VMSReqst  *req;
   7.207 -   
   7.208 -   semEnv = (VSsSemEnv *)_semEnv;
   7.209 -
   7.210 -   req    = VMS_PI__take_next_request_out_of( requestingSlv );
   7.211 -
   7.212 -   while( req != NULL )
   7.213 -    {
   7.214 -      switch( req->reqType )
   7.215 -       { case semantic:     handleSemReq(        req, requestingSlv, semEnv);
   7.216 -            break;
   7.217 -         case createReq:    handleCreate(        req, requestingSlv, semEnv);
   7.218 -            break;
   7.219 -         case dissipate:    handleDissipate(          requestingSlv, semEnv);
   7.220 -            break;
   7.221 -         case VMSSemantic:  VMS_PI__handle_VMSSemReq(req, requestingSlv, semEnv,
   7.222 -                                           (ResumeSlvFnPtr) &resume_slaveVP);
   7.223 -            break;
   7.224 -         default:
   7.225 -            break;
   7.226 -       }
   7.227 -      
   7.228 -      req = VMS_PI__take_next_request_out_of( requestingSlv );
   7.229 -    } //while( req != NULL )
   7.230 -
   7.231 - }
   7.232 -
   7.233 -
   7.234 -inline void
   7.235 -handleSemReq( VMSReqst *req, SlaveVP *reqSlv, VSsSemEnv *semEnv )
   7.236 +handleSemReq( PRReqst *req, SlaveVP *reqSlv, VSsSemEnv *semEnv )
   7.237   { VSsSemReq *semReq;
   7.238  
   7.239 -   semReq = VMS_PI__take_sem_reqst_from(req);
   7.240 +   semReq = PR_PI__take_sem_reqst_from(req);
   7.241     if( semReq == NULL ) return;
   7.242     switch( semReq->reqType )  //sem handlers are all in other file
   7.243      {
   7.244 -      case submit_task:     handleSubmitTask(   semReq,         semEnv);
   7.245 -         break; 
   7.246 -      case end_task:        handleEndTask(      semReq,         semEnv);
   7.247 -         break;
   7.248        case send_type_to:    handleSendTypeTo(   semReq,         semEnv);
   7.249           break;
   7.250        case send_from_to:    handleSendFromTo(   semReq,         semEnv);
   7.251 @@ -268,209 +175,6 @@
   7.252  
   7.253  
   7.254  
   7.255 -//=========================== VMS Request Handlers ==============================
   7.256 -/*SlaveVP dissipate -- this is NOT task-end!, only call this to get rid of
   7.257 - * extra task slaves, and to end explicitly created threads
   7.258 - */
   7.259 -inline void
   7.260 -handleDissipate( SlaveVP *requestingSlv, VSsSemEnv *semEnv )
   7.261 - { VSsSemData  *semData;
   7.262 -   VSsTaskStub *parentTaskStub, *ownTaskStub;
   7.263 - 
   7.264 -         DEBUG__printf1(dbgRqstHdlr,"Dissipate request from processor %d",
   7.265 -                                                     requestingSlv->slaveID)
   7.266 -   semData = (VSsSemData *)requestingSlv->semanticData;
   7.267 -
   7.268 -   if( semData->slaveType == ExtraTaskSlv )
   7.269 -    { semEnv->numLiveExtraTaskSlvs -= 1; //for detecting shutdown condition
   7.270 -         //Has no task assigned, so no parents and no children, so free self
   7.271 -      goto FreeSlaveStateAndReturn;
   7.272 -    }
   7.273 -
   7.274 -   if( semData->slaveType == SlotTaskSlv )
   7.275 -    {    //should never call dissipate on a slot assigned slave
   7.276 -      VMS_PI__throw_exception( "dissipate a slot-assigned slave", requestingSlv, NULL );
   7.277 -    }
   7.278 -
   7.279 -      //if make it to here, then is a thread slave ending
   7.280 -   semEnv->numLiveThreadSlvs -= 1; //for detecting shutdown condition
   7.281 -   
   7.282 -   ownTaskStub    = semData->taskStub;
   7.283 -   parentTaskStub = ownTaskStub->parentTaskStub;
   7.284 -   parentTaskStub->numLiveChildThreads -= 1;  //not freed, even if ended
   7.285 -   
   7.286 -      //if all children ended, then free this task's stub
   7.287 -      // else, keep stub around, and last child will free it (below)
   7.288 -   if( ownTaskStub->numLiveChildTasks   == 0 &&
   7.289 -       ownTaskStub->numLiveChildThreads == 0 )
   7.290 -      free_task_stub( ownTaskStub );
   7.291 -   else
   7.292 -      ownTaskStub->isEnded = TRUE; //for children to see when they end
   7.293 -
   7.294 -      //Now, check on parents waiting on child threads to end
   7.295 -   if( parentTaskStub->isWaitingForChildThreadsToEnd &&
   7.296 -       parentTaskStub->numLiveChildThreads == 0 )
   7.297 -    { parentTaskStub->isWaitingForChildThreadsToEnd = FALSE;
   7.298 -      if( parentTaskStub->isWaitingForChildTasksToEnd )
   7.299 -        return; //still waiting on tasks (should be impossible)
   7.300 -      else //parent free to resume
   7.301 -        resume_slaveVP( parentTaskStub->slaveAssignedTo, semEnv );
   7.302 -    }
   7.303 -   
   7.304 -      //check if this is last child of ended parent (note, not possible to
   7.305 -      // have more than one level of ancestor waiting to be freed)
   7.306 -   if( parentTaskStub->isEnded )
   7.307 -    { if( parentTaskStub->numLiveChildTasks   == 0 && 
   7.308 -          parentTaskStub->numLiveChildThreads == 0 )
   7.309 -         free_task_stub( parentTaskStub ); //just stub, semData already freed
   7.310 -    }
   7.311 -
   7.312 -      //Free the semData and requesting slave's base state for all cases
   7.313 - FreeSlaveStateAndReturn:
   7.314 -   VMS_PI__free( semData );
   7.315 -   VMS_PI__dissipate_slaveVP( requestingSlv );
   7.316 -   return; 
   7.317 -      //Note, this is not a location to check for shutdown because doesn't
   7.318 -      // say anything about work availability here.. check for shutdown in
   7.319 -      // places try to get work for the core (in the assigner)
   7.320 - }
   7.321 -
   7.322 -   
   7.323 -
   7.324 -/*Re-use this in the entry-point fn
   7.325 - */
   7.326 -inline SlaveVP *
   7.327 -VSs__create_slave_helper( TopLevelFnPtr fnPtr, void *initData,
   7.328 -                          VSsSemEnv *semEnv,    int32 coreToAssignOnto )
   7.329 - { SlaveVP    *newSlv;
   7.330 -   VSsSemData   *semData;
   7.331 -
   7.332 -      //This is running in master, so use internal version
   7.333 -   newSlv = VMS_PI__create_slaveVP( fnPtr, initData );
   7.334 -
   7.335 -      //task slaves differ from thread slaves by the settings in the taskStub
   7.336 -      //so, don't create task stub here, only create semData, which is same
   7.337 -      // for all kinds of slaves
   7.338 -   semData = VMS_PI__malloc( sizeof(VSsSemData) );
   7.339 -   semData->highestTransEntered = -1;
   7.340 -   semData->lastTransEntered    = NULL;
   7.341 -   semData->needsTaskAssigned   = TRUE;
   7.342 -   semData->taskStub            = NULL;
   7.343 -   
   7.344 -   newSlv->semanticData = semData;
   7.345 -
   7.346 -   //=================== Assign new processor to a core =====================
   7.347 -   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   7.348 -   newSlv->coreAnimatedBy = 0;
   7.349 -
   7.350 -   #else
   7.351 -      //Assigning slaves to cores is part of SSR code..
   7.352 -   if(coreToAssignOnto < 0 || coreToAssignOnto >= NUM_CORES )
   7.353 -    {    //out-of-range, so round-robin assignment
   7.354 -      newSlv->coreAnimatedBy = semEnv->nextCoreToGetNewSlv;
   7.355 -
   7.356 -      if( semEnv->nextCoreToGetNewSlv >= NUM_CORES - 1 )
   7.357 -          semEnv->nextCoreToGetNewSlv  = 0;
   7.358 -      else
   7.359 -          semEnv->nextCoreToGetNewSlv += 1;
   7.360 -    }
   7.361 -   else //core num in-range, so use it
   7.362 -    { newSlv->coreAnimatedBy = coreToAssignOnto;
   7.363 -    }
   7.364 -   #endif
   7.365 -   //========================================================================
   7.366 -   
   7.367 -   return newSlv;
   7.368 - }
   7.369 -
   7.370 -VSsTaskStub *
   7.371 -create_thread_task_stub( void *initData )
   7.372 - { VSsTaskStub *newStub;
   7.373 -         
   7.374 -   newStub = VMS_PI__malloc( sizeof(VSsTaskStub) );
   7.375 -   newStub->numBlockingProp = 0;
   7.376 -   newStub->slaveAssignedTo = NULL; //set later
   7.377 -   newStub->taskType        = IS_A_THREAD;
   7.378 -   newStub->ptrEntries      = NULL;
   7.379 -   newStub->args            = initData;  
   7.380 -   newStub->numLiveChildTasks              = 0;
   7.381 -   newStub->numLiveChildThreads            = 0;
   7.382 -   newStub->parentTaskStub                = NULL;
   7.383 -   newStub->isWaitingForChildTasksToEnd    = FALSE;
   7.384 -   newStub->isWaitingForChildThreadsToEnd  = FALSE;
   7.385 -   newStub->taskID          = NULL;
   7.386 -
   7.387 -   return newStub;
   7.388 - }
   7.389 -
   7.390 -/*Application invokes this when it explicitly creates a thread via the
   7.391 - * "VSs__create_thread()" command.
   7.392 - * 
   7.393 - *The request handlers create new task slaves directly, not via this hdlr.
   7.394 - * 
   7.395 - *Make everything in VSs be a task.  An explicitly created VP is just a
   7.396 - * suspendable task, and the seedVP is also a suspendable task. 
   7.397 - *So, here, create a task Stub. 
   7.398 - * Then, see if there are any extra slaveVPs hanging around, and if not,
   7.399 - * call the helper to make a new one.
   7.400 - * Then, put the task stub into the slave's semantic Data.
   7.401 - *When the slave calls dissipate, have to recycle the task stub.
   7.402 - */
   7.403 -inline void
   7.404 -handleCreate( VMSReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv )
   7.405 - { VSsSemReq  *semReq;
   7.406 -   SlaveVP    *newSlv;
   7.407 -   VSsSemData *semData, *parentSemData;
   7.408 -   
   7.409 -   semReq = VMS_PI__take_sem_reqst_from( req );
   7.410 -
   7.411 -   semEnv->numLiveThreadSlvs += 1;
   7.412 -   
   7.413 -      //Deceptive -- must work when creator is a normal task, or seed,
   7.414 -      // or another thd.. think have valid sem data and task stub for all
   7.415 -      //This hdlr is NOT called when creating the seed slave
   7.416 -   parentSemData = (VSsSemData *)semReq->callingSlv->semanticData;
   7.417 -   parentSemData->taskStub->numLiveChildThreads += 1;
   7.418 -
   7.419 -      //use an idle "extra" slave, if have one
   7.420 -   newSlv = readPrivQ( semEnv->freeExtraTaskSlvQ );
   7.421 -   if( newSlv != NULL ) //got an idle one, so reset it
   7.422 -    { semData = (VSsSemData *)newSlv->semanticData;
   7.423 -      semData->highestTransEntered = -1;
   7.424 -      semData->lastTransEntered    = NULL;
   7.425 -      VMS_int__reset_slaveVP_to_TopLvlFn( newSlv, semReq->fnPtr, 
   7.426 -                                                         semReq->initData );
   7.427 -    }
   7.428 -   else //no idle ones, create a new
   7.429 -    { newSlv = VSs__create_slave_helper( semReq->fnPtr, semReq->initData,
   7.430 -                                         semEnv, semReq->coreToAssignOnto ); 
   7.431 -      semData = (VSsSemData *)newSlv->semanticData;
   7.432 -    }
   7.433 -
   7.434 -      //now, create a new task and assign to the thread
   7.435 -   semData->needsTaskAssigned = FALSE;  //thread has a permanent task
   7.436 -   semData->taskStub = create_thread_task_stub( semReq->initData );
   7.437 -   semData->taskStub->parentTaskStub = parentSemData->taskStub;
   7.438 -   semData->slaveType = ThreadSlv; //this hdlr only creates thread slvs
   7.439 -
   7.440 -         DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d",
   7.441 -                                    requestingSlv->slaveID, newSlv->slaveID)
   7.442 -
   7.443 -   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   7.444 -   Dependency newd;
   7.445 -   newd.from_vp = requestingSlv->slaveID;
   7.446 -   newd.from_task = requestingSlv->assignCount;
   7.447 -   newd.to_vp = newSlv->slaveID;
   7.448 -   newd.to_task = 1;
   7.449 -   addToListOfArrays(Dependency,newd,semEnv->commDependenciesList);   
   7.450 -   #endif
   7.451 -
   7.452 -      //For VSs, caller needs ptr to created thread returned to it
   7.453 -   requestingSlv->dataRetFromReq = newSlv;
   7.454 -   resume_slaveVP(requestingSlv , semEnv );
   7.455 -   resume_slaveVP( newSlv,        semEnv );
   7.456 - }
   7.457 -
   7.458  
   7.459  //=========================== Helper ==============================
   7.460  void
   7.461 @@ -478,6 +182,8 @@
   7.462   {
   7.463        //both suspended tasks and suspended explicit slaves resumed with this
   7.464     writePrivQ( slave, semEnv->slavesReadyToResumeQ );
   7.465 +   if( semEnv->protoSemEnv->hasWork != TRUE ) 
   7.466 +       semEnv->protoSemEnv->hasWork = TRUE;
   7.467     
   7.468     #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
   7.469  /*
   7.470 @@ -487,19 +193,19 @@
   7.471  */
   7.472     #endif
   7.473     #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   7.474 -   slave->assignCount++; //Somewhere here!
   7.475 -   Unit newu;
   7.476 -   newu.vp = slave->slaveID;
   7.477 -   newu.task = slave->assignCount;
   7.478 -   addToListOfArrays(Unit,newu,semEnv->unitList);
   7.479 +   slave->numTimesAssignedToASlot++; //Somewhere here!
   7.480 +   Unit newU;
   7.481 +   newU.vp = slave->slaveID;
   7.482 +   newU.task = slave->numTimesAssignedToASlot;
   7.483 +   addToListOfArrays(Unit,newU,semEnv->unitList);
   7.484     
   7.485 -   if (slave->assignCount > 1){
   7.486 -        Dependency newd;
   7.487 -        newd.from_vp = slave->slaveID;
   7.488 -        newd.from_task = slave->assignCount - 1;
   7.489 -        newd.to_vp = slave->slaveID;
   7.490 -        newd.to_task = slave->assignCount;
   7.491 -        addToListOfArrays(Dependency, newd ,semEnv->ctlDependenciesList);  
   7.492 -   }
   7.493 +   if (slave->numTimesAssignedToASlot > 1)
   7.494 +    { Dependency newD;
   7.495 +      newD.from_vp = slave->slaveID;
   7.496 +      newD.from_task = slave->numTimesAssignedToASlot - 1;
   7.497 +      newD.to_vp = slave->slaveID;
   7.498 +      newD.to_task = slave->numTimesAssignedToASlot;
   7.499 +      addToListOfArrays(Dependency, newD ,semEnv->ctlDependenciesList);  
   7.500 +    }
   7.501     #endif
   7.502   }
     8.1 --- a/VSs_Request_Handlers.c	Mon Sep 03 03:26:12 2012 -0700
     8.2 +++ b/VSs_Request_Handlers.c	Thu Oct 18 02:44:30 2012 -0700
     8.3 @@ -7,7 +7,7 @@
     8.4  #include <stdio.h>
     8.5  #include <stdlib.h>
     8.6  
     8.7 -#include "VMS_impl/VMS.h"
     8.8 +#include "PR_impl/PR.h"
     8.9  #include "Queue_impl/PrivateQueue.h"
    8.10  #include "Hash_impl/PrivateHash.h"
    8.11  #include "VSs.h"
    8.12 @@ -32,7 +32,7 @@
    8.13  cloneReq( VSsSemReq *semReq )
    8.14   { VSsSemReq *clonedReq;
    8.15  
    8.16 -   clonedReq             = VMS_PI__malloc( sizeof(VSsSemReq) );
    8.17 +   clonedReq             = PR_PI__malloc( sizeof(VSsSemReq) );
    8.18     clonedReq->reqType    = semReq->reqType;
    8.19     clonedReq->senderSlv  = semReq->senderSlv;
    8.20     clonedReq->receiverSlv= semReq->receiverSlv;
    8.21 @@ -71,7 +71,7 @@
    8.22  create_pointer_entry( )
    8.23   { VSsPointerEntry *newEntry;
    8.24     
    8.25 -   newEntry = VMS_PI__malloc( sizeof(VSsPointerEntry) );
    8.26 +   newEntry = PR_PI__malloc( sizeof(VSsPointerEntry) );
    8.27     newEntry->hasEnabledNonFinishedWriter = FALSE;
    8.28     newEntry->numEnabledNonDoneReaders    = 0;
    8.29     newEntry->waitersQ                    = makePrivQ();
    8.30 @@ -85,13 +85,12 @@
    8.31  inline VSsTaskStub *
    8.32  create_task_stub( VSsTaskType *taskType, void **args )
    8.33   { void **newArgs;
    8.34 -   VSsTaskStub* newStub = VMS_int__malloc( sizeof(VSsTaskStub) + taskType->sizeOfArgs );
    8.35 +   VSsTaskStub* newStub = PR_int__malloc( sizeof(PRMetaTask) + taskType->sizeOfArgs );
    8.36     newStub->numBlockingProp = taskType->numCtldArgs;
    8.37 -   newStub->slaveAssignedTo = NULL;
    8.38     newStub->taskType   = taskType;
    8.39     newStub->ptrEntries = 
    8.40 -      VMS_int__malloc( taskType->numCtldArgs * sizeof(VSsPointerEntry *) );
    8.41 -   newArgs = (void **)( (uint8 *)newStub + sizeof(VSsTaskStub) );
    8.42 +      PR_int__malloc( taskType->numCtldArgs * sizeof(VSsPointerEntry *) );
    8.43 +   newArgs = (void **)( (uint8 *)newStub + sizeof(PRMetaTask) );
    8.44     newStub->args = newArgs;
    8.45     newStub->numLiveChildTasks   = 0;
    8.46     newStub->numLiveChildThreads = 0;
    8.47 @@ -108,17 +107,189 @@
    8.48  create_task_carrier( VSsTaskStub *taskStub, int32 argNum, int32 rdOrWrite )
    8.49   { VSsTaskStubCarrier *newCarrier;
    8.50   
    8.51 -   newCarrier = VMS_PI__malloc( sizeof(VSsTaskStubCarrier) );
    8.52 +   newCarrier = PR_PI__malloc( sizeof(VSsTaskStubCarrier) );
    8.53     newCarrier->taskStub = taskStub;
    8.54     newCarrier->argNum   = argNum;
    8.55     newCarrier->isReader = rdOrWrite == READER;
    8.56   }
    8.57  
    8.58 +
    8.59 +
    8.60 +//===========================  ==============================
    8.61 +
    8.62 +/*Application invokes this via wrapper library, when it explicitly creates a
    8.63 + * thread with the "VSs__create_thread()" command.
    8.64 + * 
    8.65 + *Slave creation is a special form, so PR does handling before calling this.
    8.66 + * It does creation of the new slave, and hands it to this handler.  
    8.67 + *This handler is registered with PR during VSs__start().
    8.68 + * 
    8.69 + *So, here, create a task Stub that contains a marker stating this is a thread. 
    8.70 + * Then, attach the task stub to the slave's meta Task via a PR command.
    8.71 + * 
    8.72 + *When slave dissipates, PR will call the registered recycler for the task stub.
    8.73 + */
    8.74 +inline void
    8.75 +handleCreateThd( PRReqst *req, SlaveVP *requestingSlv, SlaveVP *newSlv, VSsSemEnv *semEnv )
    8.76 + { VSsSemReq  *semReq;
    8.77 +   VSsTaskStub *taskStub, *parentTaskStub;
    8.78 +   
    8.79 +   semReq = PR_PI__take_sem_reqst_from( req );
    8.80 +
    8.81 +   parentTaskStub = PR_PI__give_lang_meta_task( requestingSlv );
    8.82 +   parentTaskStub->numLiveChildThreads += 1;
    8.83 +   
    8.84 +   taskStub = create_thread_task_stub(); //only used for wait info
    8.85 +   taskStub->parentTaskStub = parentTaskStub;
    8.86 +
    8.87 +      //note, semantic data will be initialized by separate, registered 
    8.88 +      // initializer, at the point it is accessed the first time.   
    8.89 +
    8.90 +   //================= Assign the new thread to a core ===================
    8.91 +   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
    8.92 +   newSlv->coreAnimatedBy = 0;
    8.93 +
    8.94 +   #else
    8.95 +      //Assigning slaves to cores is part of SSR code..
    8.96 +   int32 coreToAssignOnto = semReq->coreToAssignOnto;
    8.97 +   if(coreToAssignOnto < 0 || coreToAssignOnto >= NUM_CORES )
    8.98 +    {    //out-of-range, so round-robin assignment
    8.99 +      newSlv->coreAnimatedBy = semEnv->nextCoreToGetNewSlv;
   8.100 +
   8.101 +      if( semEnv->nextCoreToGetNewSlv >= NUM_CORES - 1 )
   8.102 +          semEnv->nextCoreToGetNewSlv  = 0;
   8.103 +      else
   8.104 +          semEnv->nextCoreToGetNewSlv += 1;
   8.105 +    }
   8.106 +   else //core num in-range, so use it
   8.107 +    { newSlv->coreAnimatedBy = coreToAssignOnto;
   8.108 +    }
   8.109 +   #endif
   8.110 +   //========================================================================
   8.111 +   
   8.112 +   
   8.113 +
   8.114 +         DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d",
   8.115 +                                    requestingSlv->slaveID, newSlv->slaveID)
   8.116 +
   8.117 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   8.118 +   Dependency newD;
   8.119 +   newD.from_vp = requestingSlv->slaveID;
   8.120 +   newD.from_task = requestingSlv->numTimesAssignedToASlot;
   8.121 +   newD.to_vp = newSlv->slaveID;
   8.122 +   newD.to_task = 1;
   8.123 +   addToListOfArrays(Dependency,newD,semEnv->commDependenciesList);   
   8.124 +   #endif
   8.125 +
   8.126 +      //For VSs, caller needs ptr to created thread returned to it
   8.127 +   requestingSlv->dataRetFromReq = newSlv;
   8.128 +   resume_slaveVP(requestingSlv , semEnv );
   8.129 +   resume_slaveVP( newSlv,        semEnv );
   8.130 + }
   8.131 +
   8.132 +/*Initialize semantic data struct..  this initializer doesn't need any input,
   8.133 + * but some languages may need something from inside the request that was sent
   8.134 + * to create a slave..  in that case, just make initializer do the malloc then
   8.135 + * use the PR_PI__give_sem_data  inside the create handler, and fill in the
   8.136 + * semData values there.
   8.137 + */
   8.138 +void * createInitialSemanticData( )
   8.139 + { VSsSemData *semData;
   8.140 + 
   8.141 +   semData = PR_PI__malloc( sizeof(VSsSemData) );
   8.142 +   
   8.143 +   semData->highestTransEntered = -1;
   8.144 +   semData->lastTransEntered    = NULL;
   8.145 +   return semData;
   8.146 + }
   8.147 +
   8.148 +/*SlaveVP dissipate -- this is NOT task-end!, only call this to end explicitly
   8.149 + * created threads
   8.150 + */
   8.151 +inline void
   8.152 +handleDissipate( SlaveVP *requestingSlv, VSsSemEnv *semEnv )
   8.153 + { VSsSemData  *semData;
   8.154 +   VSsTaskStub  *parentTaskStub, *ownTaskStub;
   8.155 + 
   8.156 +         DEBUG__printf1(dbgRqstHdlr,"Dissipate request from processor %d",
   8.157 +                                                     requestingSlv->slaveID)
   8.158 +             
   8.159 +   ownTaskStub    = PR_PI__give_lang_meta_task( requestingSlv, VSs_MAGIC_NUMBER );
   8.160 +   parentTaskStub = ownTaskStub->parentTaskStub;
   8.161 +   parentTaskStub->numLiveChildThreads -= 1;  //parent wasn't freed, even if ended
   8.162 +   
   8.163 +      //if all children ended, then free this task's stub
   8.164 +      // else, keep stub around, and last child will free it (below)
   8.165 +   if( ownTaskStub->numLiveChildTasks   == 0 &&
   8.166 +       ownTaskStub->numLiveChildThreads == 0 )
   8.167 +      free_task_stub( ownTaskStub );
   8.168 +   else
   8.169 +      ownTaskStub->isEnded = TRUE; //for children to see when they end
   8.170 +
   8.171 +      //Now, check on parents waiting on child threads to end
   8.172 +   if( parentTaskStub->isWaitingForChildThreadsToEnd &&
   8.173 +       parentTaskStub->numLiveChildThreads == 0 )
   8.174 +    { parentTaskStub->isWaitingForChildThreadsToEnd = FALSE;
   8.175 +      if( parentTaskStub->isWaitingForChildTasksToEnd )
   8.176 +        return; //still waiting on tasks (should be impossible)
   8.177 +      else //parent free to resume
   8.178 +        resume_slaveVP( PR_PI__give_slave_assigned_to(parentTaskStub), semEnv );
   8.179 +    }
   8.180 +   
   8.181 +      //check if this is last child of ended parent (note, not possible to
   8.182 +      // have more than one level of ancestor waiting to be freed)
   8.183 +   if( parentTaskStub->isEnded &&
   8.184 +       parentTaskStub->numLiveChildTasks   == 0 && 
   8.185 +       parentTaskStub->numLiveChildThreads == 0 )
   8.186 +    { free_task_stub( parentTaskStub ); //just stub, semData already freed
   8.187 +    }
   8.188 +
   8.189 + FreeSlaveStateAndReturn:
   8.190 +      //Used to free the semData and requesting slave's base state, but
   8.191 +      // now PR does those things, so nothing more to do..
   8.192 +//PR handles this:   PR_PI__free( semData );
   8.193 +//PR handles this:   PR_PI__dissipate_slaveVP( requestingSlv );
   8.194 +   return; 
   8.195 + }
   8.196 +
   8.197 +/*Register this with PR, during VSs start
   8.198 + *
   8.199 + *At some point, may change PR so that it recycles semData, in which case this
   8.200 + * only gets called when a process shuts down..  at that point, PR will call
   8.201 + * dissipate on all the slaves it has in the recycle Q.
   8.202 + */
   8.203 +void
   8.204 +freeVSsSemData( void *_semData )
   8.205 + { //
   8.206 +   PR_PI__free( _semData );
   8.207 + }
   8.208 +
   8.209 +void resetVSsSemData( void *_semData ) 
   8.210 + { VSsSemData *semData = (VSsSemData *)_semData;
   8.211 +   
   8.212 +   semData->highestTransEntered = -1;
   8.213 +   semData->lastTransEntered    = NULL;
   8.214 + }
   8.215 +
   8.216  //==========================================================================
   8.217  //
   8.218  //
   8.219  /*Submit Task
   8.220 - * 
   8.221 + *
   8.222 + *PR creates a PRMetaTask and passes it in.  This handler adds language-
   8.223 + * specific stuff to it.  The language-specific stuff is linked to the
   8.224 + * PRMetaTask, but if the task is suspended for any reason, the lang-specific
   8.225 + * part is moved to the semData of the slave that is animating the task.
   8.226 + *So, while the PRMetaTask is inside the creating language's semantic
   8.227 + * env, waiting to be assigned to a slave for animation, the lang-specific
   8.228 + * task info is accessed from the PRMetaTask.  But once the task suspends,
   8.229 + * that lang-specific task info transfers to the slave's semData.  All lang
   8.230 + * constructs that want to access it must get it from the semData.
   8.231 + *However, taskEnd still accesses the lang-specific task info from the 
   8.232 + * PRMetaTask, whether it suspended or not..  and the task code can access
   8.233 + * data to be used within the application behavior via 
   8.234 + * PR__give_task_info( animatingSlave ).
   8.235 + *  
   8.236   *Uses a hash table to match the arg-pointers to each other. So, an
   8.237   * argument-pointer is one-to-one with a hash-table entry.
   8.238   * 
   8.239 @@ -182,79 +353,45 @@
   8.240   * the chain.  (Means no-longer-used pointers accumulate at end of chain,
   8.241   * decide garbage collection of no-longer-used pointers later)
   8.242   *
   8.243 - *  
   8.244 - * ========================== end of task ===========================
   8.245 - * 
   8.246 - *At the end of a task,
   8.247 - *The task's controlled arguments are processed one by one.
   8.248 - *Processing an argument means getting the hash of the pointer.  Then,
   8.249 - * looking up the hash entry (and putting the entry at the start of the
   8.250 - * chain, if there was a chain).
   8.251 - *With the hash entry:
   8.252 - *
   8.253 - *If the arg is a reader, then decrement the enabled and non-finished
   8.254 - * reader-count in the hash-entry. If the count becomes zero, then take
   8.255 - * the next entry from the Q. It should be a writer, or else there's a
   8.256 - * bug in this algorithm.
   8.257 - *Set the hash-entry to have an enabled non-finished writer.  Decrement
   8.258 - * the blocking-propendent-count of the writer's task-stub.  If the count
   8.259 - * has reached zero, then put the task-stub into the readyQ.
   8.260 - * 
   8.261 - *If the arg is a writer, then clear the enabled non-finished writer flag
   8.262 - * of the hash-entry. Take the next entry from the Q. 
   8.263 - *If it is a writer, then turn the flag back on.  Decrement the writer's
   8.264 - * blocking-propendent-count in its task-stub.  If it becomes zero, then
   8.265 - * put the task-stub into the readyQ.
   8.266 - *
   8.267 - *If it is a reader, then increment the hash-entry's count of enabled
   8.268 - * non-finished readers.  Decrement the blocking propendents count of the
   8.269 - * reader's task-stub.  If it reaches zero, then put the task-stub into the
   8.270 - * readyQ.
   8.271 - *Then repeat until encounter a writer -- put that writer back into the Q.
   8.272 - * 
   8.273 - *That should be it -- that should work.
   8.274   */
   8.275 -inline void
   8.276 +inline 
   8.277 +void *
   8.278  handleSubmitTask( VSsSemReq *semReq, VSsSemEnv *semEnv )
   8.279   { uint32           key[3];
   8.280     HashEntry       *rawHashEntry; //has char *, but use with uint32 *
   8.281     VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer
   8.282     void           **args;
   8.283 -   VSsTaskStub     *taskStub;
   8.284 +   VSsTaskStub     *taskStub, *parentTaskStub;
   8.285     VSsTaskType     *taskType;
   8.286     VSsTaskStubCarrier *taskCarrier;
   8.287     
   8.288     HashTable *
   8.289     argPtrHashTbl = semEnv->argPtrHashTbl;
   8.290     
   8.291 -      //suspending a task always makes the slave into an extra slot slave,
   8.292 -      // because it ends up in the resumeQ, even when resumes immediately.
   8.293 -      //Eventually task_end will put the slave into the freeExtraTaskSlvQ
   8.294 -   replaceWithNewSlotSlvIfNeeded( semReq->callingSlv, semEnv );
   8.295   
   8.296     /* ==========================  creation  ========================== 
   8.297 -    * 
   8.298 -    *At creation, make a task-stub.  Set the count of blocking propendents
   8.299 +    *Make a task-stub.  Set the count of blocking propendents
   8.300      * to the number of controlled arguments (a task can have
   8.301      * arguments that are not controlled by the language, like simple integer
   8.302      * inputs from the sequential portion. Note that all controlled arguments
   8.303      * are pointers, and marked as controlled in the application code).
   8.304      */
   8.305     args     = semReq->args;
   8.306 -   taskType = semReq->taskType;
   8.307 +   taskType = semReq->taskType; //this is VSs task type struct
   8.308     taskStub = create_task_stub( taskType, args );//copies arg ptrs
   8.309 +   
   8.310     taskStub->numBlockingProp = taskType->numCtldArgs;
   8.311 -   taskStub->taskID          = semReq->taskID; //may be NULL
   8.312 -   
   8.313 -   VSsSemData* 
   8.314 -   parentSemData = (VSsSemData*) semReq->callingSlv->semanticData;
   8.315 -   taskStub->parentTaskStub = (void*) parentSemData->taskStub;
   8.316 -   parentSemData->taskStub->numLiveChildTasks += 1;
   8.317 +   //PR does this (metaTask contains taskID): taskStub->taskID = semReq->taskID;
   8.318 +      
   8.319 +   parentTaskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task(semReq->callingSlv, VSs_MAGIC_NUMBER);
   8.320 +   taskStub->parentTaskStub = parentTaskStub; 
   8.321 +   parentTaskStub->numLiveChildTasks += 1;
   8.322     
   8.323           //DEBUG__printf3(dbgRqstHdlr,"Submit req from slaveID: %d, from task: %d, for task: %d", semReq->callingSlv->slaveID, parentSemData->taskStub->taskID[1], taskStub->taskID[1])
   8.324           DEBUG__printf2(dbgRqstHdlr,"Submit req from slaveID: %d, for task: %d", semReq->callingSlv->slaveID, taskStub->taskID[1])
   8.325            
   8.326 -   /*The controlled arguments are then processed one by one.
   8.327 +   /*=============== Process args =================
   8.328 +    *The controlled arguments are processed one by one.
   8.329      *Processing an argument means getting the hash of the pointer.  Then,
   8.330      * looking up the hash entry.  (If none, create one).
   8.331      */
   8.332 @@ -295,6 +432,8 @@
   8.333              taskStub->numBlockingProp -= 1;
   8.334              if( taskStub->numBlockingProp == 0 )
   8.335               { writePrivQ( taskStub, semEnv->taskReadyQ );
   8.336 +               if( semEnv->protoSemEnv->hasWork != TRUE ) 
   8.337 +                   semEnv->protoSemEnv->hasWork = TRUE;
   8.338               }
   8.339              ptrEntry->numEnabledNonDoneReaders += 1;
   8.340            }
   8.341 @@ -318,6 +457,8 @@
   8.342              taskStub->numBlockingProp -= 1;
   8.343              if( taskStub->numBlockingProp == 0 )
   8.344               { writePrivQ( taskStub, semEnv->taskReadyQ );
   8.345 +               if( semEnv->protoSemEnv->hasWork != TRUE ) 
   8.346 +                   semEnv->protoSemEnv->hasWork = TRUE;
   8.347               }
   8.348              ptrEntry->hasEnabledNonFinishedWriter = TRUE;
   8.349            }
   8.350 @@ -329,7 +470,7 @@
   8.351         }
   8.352      } //for argNum
   8.353     
   8.354 -   
   8.355 +      //resume the parent, creator
   8.356     resume_slaveVP( semReq->callingSlv, semEnv );
   8.357  
   8.358     return;
   8.359 @@ -372,36 +513,38 @@
   8.360   * and no readers and no writers..
   8.361   */
   8.362  inline void
   8.363 -handleEndTask( VSsSemReq *semReq, VSsSemEnv *semEnv )
   8.364 +handleEndTask( void *langMetaTask, VSsSemReq *semReq, VSsSemEnv *semEnv )
   8.365   { VSsPointerEntry  *ptrEntry; //contents of hash table entry for an arg pointer
   8.366     void            **args;
   8.367     VSsSemData       *endingSlvSemData;
   8.368 -   VSsTaskStub      *endingTaskStub, *waitingTaskStub, *parent;
   8.369 +   VSsTaskStub      *endingTaskStub, *waitingTaskStub, *parentStub;
   8.370     VSsTaskType      *endingTaskType;
   8.371     VSsTaskStubCarrier *waitingTaskCarrier;
   8.372     VSsPointerEntry **ptrEntries;
   8.373           
   8.374   
   8.375 -   endingSlvSemData = (VSsSemData *)semReq->callingSlv->semanticData;
   8.376 -   endingTaskStub   = endingSlvSemData->taskStub;
   8.377 +//   endingTaskStub   = (VSsTaskStub *)PR_PI__give_lang_spec_task_info( semReq->callingSlv );
   8.378 +   
   8.379 +   endingTaskStub   = (VSsTaskStub *)langMetaTask;
   8.380     args             = endingTaskStub->args;
   8.381     endingTaskType   = endingTaskStub->taskType;
   8.382     ptrEntries       = endingTaskStub->ptrEntries; //saved in stub when create
   8.383     
   8.384           DEBUG__printf2(dbgRqstHdlr,"EndTask req from slaveID: %d, task: %d",semReq->callingSlv->slaveID, endingTaskStub->taskID[1])
   8.385            
   8.386 -      //Check if parent was waiting on this task
   8.387 -   parent = (VSsTaskStub *) endingTaskStub->parentTaskStub;
   8.388 -   parent->numLiveChildTasks -= 1;
   8.389 -   if( parent->isWaitingForChildTasksToEnd && parent->numLiveChildTasks == 0)
   8.390 +      //"wait" functionality: Check if parent was waiting on this task
   8.391 +   parentStub = endingTaskStub->parentTaskStub;
   8.392 +   parentStub->numLiveChildTasks -= 1;
   8.393 +   if( parentStub->isWaitingForChildTasksToEnd && 
   8.394 +       parentStub->numLiveChildTasks == 0)
   8.395      {
   8.396 -      parent->isWaitingForChildTasksToEnd = FALSE;
   8.397 -      resume_slaveVP( parent->slaveAssignedTo, semEnv );
   8.398 +      parentStub->isWaitingForChildTasksToEnd = FALSE;
   8.399 +      resume_slaveVP( PR_PI__give_slave_assigned_to(parentStub), semEnv );
   8.400      }
   8.401     
   8.402        //Check if parent ended, and this was last descendent, then free it
   8.403 -   if( parent->isEnded && parent->numLiveChildTasks == 0 )
   8.404 -    { VMS_PI__free( parent );
   8.405 +   if( parentStub->isEnded && parentStub->numLiveChildTasks == 0 )
   8.406 +    { free_task_stub( parentStub );
   8.407      }
   8.408     
   8.409     
   8.410 @@ -411,32 +554,16 @@
   8.411      */
   8.412     int32 argNum;
   8.413     for( argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++ )
   8.414 -    { 
   8.415 -      /* commented out 'cause remembering entry ptr when create stub
   8.416 -      key[0] = 2; //says are 2 32b values in key
   8.417 -      *( (uint64*)&key[1] ) = args[argNum];  //write 64b ptr into two 32b
   8.418 -
   8.419 -       /*If the hash entry was chained, put it at the
   8.420 -       * start of the chain.  (Means no-longer-used pointers accumulate
   8.421 -       * at end of chain, decide garbage collection later) 
   8.422 -       */
   8.423 -      /*NOTE: don't do hash lookups here, instead, have a pointer to the
   8.424 -       * hash entry inside task-stub, put there during task creation.
   8.425 -      rawHashEntry = getEntryFromTable32( key, ptrHashTbl );
   8.426 -      ptrEntry = (VSsPointerEntry *)rawHashEntry->content;
   8.427 -      if( ptrEntry == NULL ) 
   8.428 -          VMS_App__throw_exception("hash entry NULL", NULL, NULL);
   8.429 -      */ 
   8.430 -      
   8.431 +    {       
   8.432        ptrEntry = ptrEntries[argNum];
   8.433 -      /*check if the ending task was reader of this arg*/
   8.434 +      //check if the ending task was reader of this arg
   8.435        if( endingTaskType->argTypes[argNum] == READER )
   8.436 -       { /*then decrement the enabled and non-finished reader-count in
   8.437 -          * the hash-entry. */ 
   8.438 +       { //then decrement the enabled and non-finished reader-count in
   8.439 +         // the hash-entry. 
   8.440           ptrEntry->numEnabledNonDoneReaders -= 1;
   8.441           
   8.442 -         /*If the count becomes zero, then take the next entry from the Q. 
   8.443 -          *It should be a writer, or else there's a bug in this algorithm.*/
   8.444 +         //If the count becomes zero, then take the next entry from the Q. 
   8.445 +         //It should be a writer, or else there's a bug in this algorithm.
   8.446           if( ptrEntry->numEnabledNonDoneReaders == 0 )
   8.447            { waitingTaskCarrier = readPrivQ( ptrEntry->waitersQ );
   8.448              if( waitingTaskCarrier == NULL ) 
   8.449 @@ -444,27 +571,29 @@
   8.450                 continue; //next iter of loop
   8.451               }
   8.452              if( waitingTaskCarrier->isReader ) 
   8.453 -               VMS_App__throw_exception("READER waiting", NULL, NULL);
   8.454 +               PR_App__throw_exception("READER waiting", NULL, NULL);
   8.455                     
   8.456              waitingTaskStub = waitingTaskCarrier->taskStub;
   8.457              
   8.458 -            /*Set the hash-entry to have an enabled non-finished writer.*/
   8.459 +            //Set the hash-entry to have an enabled non-finished writer.
   8.460              ptrEntry->hasEnabledNonFinishedWriter = TRUE;
   8.461              
   8.462 -            /* Decrement the blocking-propendent-count of the writer's
   8.463 -             * task-stub.  If the count has reached zero, then put the
   8.464 -             * task-stub into the readyQ.*/
   8.465 +            // Decrement the blocking-propendent-count of the writer's
   8.466 +            // task-stub.  If the count has reached zero, then put the
   8.467 +            // task-stub into the readyQ.
   8.468              waitingTaskStub->numBlockingProp -= 1;
   8.469              if( waitingTaskStub->numBlockingProp == 0 )
   8.470               { writePrivQ( waitingTaskStub, semEnv->taskReadyQ );
   8.471 +               if( semEnv->protoSemEnv->hasWork != TRUE ) 
   8.472 +                   semEnv->protoSemEnv->hasWork = TRUE;
   8.473               }
   8.474            }
   8.475         }
   8.476 -      else /*the ending task is a writer of this arg*/ 
   8.477 -       { /*clear the enabled non-finished writer flag of the hash-entry.*/
   8.478 +      else //the ending task is a writer of this arg 
   8.479 +       { //clear the enabled non-finished writer flag of the hash-entry.
   8.480           ptrEntry->hasEnabledNonFinishedWriter = FALSE;
   8.481           
   8.482 -         /*Take the next waiter from the hash-entry's Q.*/
   8.483 +         //Take the next waiter from the hash-entry's Q.
   8.484           waitingTaskCarrier = readPrivQ( ptrEntry->waitersQ );
   8.485           if( waitingTaskCarrier == NULL )
   8.486            { //TODO: looks safe to delete ptr entry at this point
   8.487 @@ -472,36 +601,40 @@
   8.488            }
   8.489           waitingTaskStub = waitingTaskCarrier->taskStub;
   8.490           
   8.491 -         /*If task is a writer of this hash-entry's pointer*/
   8.492 +         //If task is a writer of this hash-entry's pointer
   8.493           if( !waitingTaskCarrier->isReader ) 
   8.494 -          { /* then turn the flag back on.*/
   8.495 +          { // then turn the flag back on.
   8.496              ptrEntry->hasEnabledNonFinishedWriter = TRUE;
   8.497 -            /*Decrement the writer's blocking-propendent-count in task-stub
   8.498 -             * If it becomes zero, then put the task-stub into the readyQ.*/
   8.499 +            //Decrement the writer's blocking-propendent-count in task-stub
   8.500 +            // If it becomes zero, then put the task-stub into the readyQ.
   8.501              waitingTaskStub->numBlockingProp -= 1;
   8.502              if( waitingTaskStub->numBlockingProp == 0 )
   8.503               { writePrivQ( waitingTaskStub, semEnv->taskReadyQ );
   8.504 +                if( semEnv->protoSemEnv->hasWork != TRUE ) 
   8.505 +                    semEnv->protoSemEnv->hasWork = TRUE;
   8.506               }
   8.507            }
   8.508           else
   8.509 -          { /*Waiting task is a reader, so do a loop, of all waiting readers
   8.510 -             * until encounter a writer or waitersQ is empty*/
   8.511 -            while( TRUE ) /*The checks guarantee have a waiting reader*/
   8.512 -             { /*Increment the hash-entry's count of enabled non-finished
   8.513 -                * readers.*/
   8.514 +          { //Waiting task is a reader, so do a loop, of all waiting readers
   8.515 +            // until encounter a writer or waitersQ is empty
   8.516 +            while( TRUE ) //The checks guarantee have a waiting reader
   8.517 +             { //Increment the hash-entry's count of enabled non-finished
   8.518 +               // readers.
   8.519                 ptrEntry->numEnabledNonDoneReaders += 1;
   8.520  
   8.521 -               /*Decrement the blocking propendents count of the reader's
   8.522 -                * task-stub.  If it reaches zero, then put the task-stub
   8.523 -                * into the readyQ.*/
   8.524 +               //Decrement the blocking propendents count of the reader's
   8.525 +               // task-stub.  If it reaches zero, then put the task-stub
   8.526 +               // into the readyQ.
   8.527                 waitingTaskStub->numBlockingProp -= 1;
   8.528                 if( waitingTaskStub->numBlockingProp == 0 )
   8.529                  { writePrivQ( waitingTaskStub, semEnv->taskReadyQ );
   8.530 +                   if( semEnv->protoSemEnv->hasWork != TRUE ) 
   8.531 +                       semEnv->protoSemEnv->hasWork = TRUE;
   8.532                  }
   8.533 -               /*Get next waiting task*/
   8.534 +               //Get next waiting task
   8.535                 waitingTaskCarrier = peekPrivQ( ptrEntry->waitersQ );
   8.536 -               if( waitingTaskCarrier == NULL ) break;
   8.537 -               if( !waitingTaskCarrier->isReader ) break;
   8.538 +               if( waitingTaskCarrier == NULL )    break; //no more waiting readers
   8.539 +               if( !waitingTaskCarrier->isReader ) break; //no more waiting readers
   8.540                 waitingTaskCarrier = readPrivQ( ptrEntry->waitersQ );               
   8.541                 waitingTaskStub = waitingTaskCarrier->taskStub;
   8.542               }//while waiter is a reader
   8.543 @@ -510,32 +643,23 @@
   8.544      }//for argnum in ending task
   8.545     
   8.546     
   8.547 -      //done ending the task, now free the stub + args copy
   8.548 -      // if still has live children, then keep stub around
   8.549 +      //done ending the task, if still has live children, then keep stub around
   8.550 +      // else, free the stub and args copy
   8.551     if( endingTaskStub->numLiveChildTasks   == 0 &&
   8.552         endingTaskStub->numLiveChildThreads == 0 )
   8.553      { free_task_stub( endingTaskStub ); 
   8.554      }
   8.555     
   8.556 -   
   8.557 -   endingSlvSemData->needsTaskAssigned = TRUE;
   8.558 -   
   8.559 -      //Check if the slave is an extra task slave, and put into free Q
   8.560 -   if( endingSlvSemData->slaveType == ExtraTaskSlv )
   8.561 -    { writePrivQ( semReq->callingSlv, semEnv->freeExtraTaskSlvQ );
   8.562 -    }
   8.563 -   
   8.564 -      //otherwise, it's a slot slave, so it will get used from matrix
   8.565 -      // so, do nothing with it, just return
   8.566     return; 
   8.567   }
   8.568  
   8.569 +
   8.570  inline void
   8.571  free_task_stub( VSsTaskStub *stubToFree )
   8.572   { if(stubToFree->ptrEntries != NULL ) //a thread stub has NULL entry
   8.573 -    { VMS_PI__free( stubToFree->ptrEntries );
   8.574 +    { PR_PI__free( stubToFree->ptrEntries );
   8.575      }
   8.576 -   VMS_PI__free( stubToFree );
   8.577 +   PR_PI__free( stubToFree );
   8.578   }
   8.579  
   8.580  //========================== Task Comm handlers ===========================
   8.581 @@ -567,14 +691,10 @@
   8.582  
   8.583           DEBUG__printf2(dbgRqstHdlr,"SendType req from sender slaveID: %d, recTask: %d", senderSlv->slaveID, receiverID[1])
   8.584            
   8.585 -      //suspending a task always makes the slave into an extra slot slave,
   8.586 -      // because it ends up in the resumeQ, even when resumes immediately.
   8.587 -      //Eventually task_end will put the slave into the freeExtraTaskSlvQ
   8.588 -   replaceWithNewSlotSlvIfNeeded( senderSlv, semEnv );
   8.589           
   8.590     receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself
   8.591     keySz = receiverIDNumInt * sizeof(int32) + 2 * sizeof(int32);
   8.592 -   key = VMS_PI__malloc( keySz );
   8.593 +   key = PR_PI__malloc( keySz );
   8.594     key[0] = receiverIDNumInt + 1; //loc 0 is num int32 in key
   8.595     memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) );
   8.596     key[ 1 + receiverIDNumInt ] = semReq->msgType; 
   8.597 @@ -604,13 +724,13 @@
   8.598     else
   8.599      {    
   8.600         #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   8.601 -        Dependency newd;
   8.602 -        newd.from_vp = senderID->slaveID;
   8.603 -        newd.from_task = senderID->assignCount;
   8.604 -        newd.to_vp = receiverID->slaveID;
   8.605 -        newd.to_task = receiverID->assignCount +1;
   8.606 -        //(newd,semEnv->commDependenciesList);  
   8.607 -        addToListOfArrays(Dependency,newd,semEnv->dynDependenciesList);  
   8.608 +        Dependency newD;
   8.609 +        newD.from_vp = senderID->slaveID;
   8.610 +        newD.from_task = senderID->numTimesAssignedToASlot;
   8.611 +        newD.to_vp = receiverID->slaveID;
   8.612 +        newD.to_task = receiverID->numTimesAssignedToASlot +1;
   8.613 +        //(newD,semEnv->commDependenciesList);  
   8.614 +        addToListOfArrays(Dependency,newD,semEnv->dynDependenciesList);  
   8.615                  int32 groupId = semReq->msgType;
   8.616          if(semEnv->ntonGroupsInfo->numInArray <= groupId){
   8.617              makeHighestDynArrayIndexBeAtLeast(semEnv->ntonGroupsInfo, groupId);
   8.618 @@ -620,10 +740,10 @@
   8.619          }
   8.620          Unit u;
   8.621          u.vp = senderID->slaveID;
   8.622 -        u.task = senderID->assignCount;
   8.623 +        u.task = senderID->numTimesAssignedToASlot;
   8.624          addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->senders);
   8.625          u.vp = receiverID->slaveID;
   8.626 -        u.task = receiverID->assignCount +1;
   8.627 +        u.task = receiverID->numTimesAssignedToASlot +1;
   8.628          addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->receivers);
   8.629         #endif
   8.630  
   8.631 @@ -633,7 +753,7 @@
   8.632           //waiting request is a receive_type_to, so it pairs to this send
   8.633           //First, remove the waiting receive request from the entry
   8.634        entry->content = waitingReq->nextReqInHashEntry;
   8.635 -      VMS_PI__free( waitingReq ); //Don't use contents -- so free it
   8.636 +      PR_PI__free( waitingReq ); //Don't use contents -- so free it
   8.637        
   8.638        if( entry->content == NULL )
   8.639         {    //TODO: mod hash table to double-link, so can delete entry from
   8.640 @@ -654,7 +774,12 @@
   8.641   }
   8.642  
   8.643  
   8.644 -/*Looks like can make single handler for both sends..
   8.645 +/*If Send or Receive are called within a task, it causes the task to suspend,
   8.646 + * which converts the slave animating it to a free slave and suspends that slave.
   8.647 + *Which means that send and receive operate upon slaves, no matter whether they
   8.648 + * were called from within a task or a slave.
   8.649 + *  
   8.650 + *Looks like can make single handler for both kinds of send..
   8.651   */
   8.652  //TODO: combine both send handlers into single handler
   8.653  inline void
   8.654 @@ -673,15 +798,11 @@
   8.655     senderID    = semReq->senderID;
   8.656     senderSlv   = semReq->senderSlv;
   8.657  
   8.658 -      //suspending a task always makes the slave into an extra slot slave,
   8.659 -      // because it ends up in the resumeQ, even when resumes immediately.
   8.660 -      //Eventually task_end will put the slave into the freeExtraTaskSlvQ
   8.661 -   replaceWithNewSlotSlvIfNeeded( senderSlv, semEnv );
   8.662     
   8.663     receiverIDNumInt = receiverID[0] + 1; //include the count in the key
   8.664     senderIDNumInt   = senderID[0] + 1;
   8.665     keySz = (receiverIDNumInt + senderIDNumInt) * sizeof(int32) + sizeof(int32);
   8.666 -   key   = VMS_PI__malloc( keySz );
   8.667 +   key   = PR_PI__malloc( keySz );
   8.668     key[0] = receiverIDNumInt + senderIDNumInt;
   8.669     memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) );
   8.670     memcpy( &key[1 + receiverIDNumInt], senderID, senderIDNumInt * sizeof(int32) );
   8.671 @@ -700,13 +821,13 @@
   8.672     else
   8.673      {    //waiting request is a receive, so it completes pair with this send
   8.674        #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   8.675 -        Dependency newd;
   8.676 -        newd.from_vp = sendPr->slaveID;
   8.677 -        newd.from_task = sendPr->assignCount;
   8.678 -        newd.to_vp = receivePr->slaveID;
   8.679 -        newd.to_task = receivePr->assignCount +1;
   8.680 -        //addToListOfArraysDependency(newd,semEnv->commDependenciesList);  
   8.681 -        addToListOfArrays(Dependency,newd,semEnv->commDependenciesList);   
   8.682 +        Dependency newD;
   8.683 +        newD.from_vp = sendPr->slaveID;
   8.684 +        newD.from_task = sendPr->numTimesAssignedToASlot;
   8.685 +        newD.to_vp = receivePr->slaveID;
   8.686 +        newD.to_task = receivePr->numTimesAssignedToASlot +1;
   8.687 +        //addToListOfArraysDependency(newD,semEnv->commDependenciesList);  
   8.688 +        addToListOfArrays(Dependency,newD,semEnv->commDependenciesList);   
   8.689        #endif 
   8.690  
   8.691           //set receiver slave, from the waiting request
   8.692 @@ -714,7 +835,7 @@
   8.693         
   8.694           //First, remove the waiting receive request from the entry
   8.695        entry->content = waitingReq->nextReqInHashEntry;
   8.696 -      VMS_PI__free( waitingReq ); //Don't use contents -- so free it
   8.697 +      PR_PI__free( waitingReq ); //Don't use contents -- so free it
   8.698        
   8.699           //can only be one waiting req for "from-to" semantics
   8.700        if( entry->content != NULL )
   8.701 @@ -755,15 +876,11 @@
   8.702     receiverID  = semReq->receiverID; //For "send", know both send & recv procrs
   8.703     receiverSlv = semReq->receiverSlv;
   8.704     
   8.705 -      //suspending a task always makes the slave into an extra slot slave,
   8.706 -      // because it ends up in the resumeQ, even when resumes immediately.
   8.707 -      //Eventually task_end will put the slave into the freeExtraTaskSlvQ
   8.708 -   replaceWithNewSlotSlvIfNeeded( receiverSlv, semEnv );
   8.709  
   8.710        //key is the receiverID plus the type -- have to copy them into key
   8.711     receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself
   8.712     keySz = receiverIDNumInt * sizeof(int32) + 2 * sizeof(int32);
   8.713 -   key = VMS_PI__malloc( keySz );
   8.714 +   key = PR_PI__malloc( keySz );
   8.715     key[0] = receiverIDNumInt + 1; //loc 0 is num int32s in key
   8.716     memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) );
   8.717     key[ 1 + receiverIDNumInt ] = semReq->msgType; 
   8.718 @@ -793,16 +910,16 @@
   8.719        receiverSlv->dataRetFromReq = waitingReq->msg;
   8.720  
   8.721           //bring both processors back from suspend
   8.722 -      VMS_PI__free( waitingReq );
   8.723 +      PR_PI__free( waitingReq );
   8.724  
   8.725         #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   8.726 -        Dependency newd;
   8.727 -        newd.from_vp = sendPr->slaveID;
   8.728 -        newd.from_task = sendPr->assignCount;
   8.729 -        newd.to_vp = receivePr->slaveID;
   8.730 -        newd.to_task = receivePr->assignCount +1;
   8.731 -        //addToListOfArraysDependency(newd,semEnv->commDependenciesList);  
   8.732 -        addToListOfArrays(Dependency,newd,semEnv->dynDependenciesList); 
   8.733 +        Dependency newD;
   8.734 +        newD.from_vp = sendPr->slaveID;
   8.735 +        newD.from_task = sendPr->numTimesAssignedToASlot;
   8.736 +        newD.to_vp = receivePr->slaveID;
   8.737 +        newD.to_task = receivePr->numTimesAssignedToASlot +1;
   8.738 +        //addToListOfArraysDependency(newD,semEnv->commDependenciesList);  
   8.739 +        addToListOfArrays(Dependency,newD,semEnv->dynDependenciesList); 
   8.740          int32 groupId = semReq->msgType;
   8.741          if(semEnv->ntonGroupsInfo->numInArray <= groupId){
   8.742              makeHighestDynArrayIndexBeAtLeast(semEnv->ntonGroupsInfo, groupId);
   8.743 @@ -812,10 +929,10 @@
   8.744          }
   8.745          Unit u;
   8.746          u.vp = sendPr->slaveID;
   8.747 -        u.task = sendPr->assignCount;
   8.748 +        u.task = sendPr->numTimesAssignedToASlot;
   8.749          addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->senders);
   8.750          u.vp = receivePr->slaveID;
   8.751 -        u.task = receivePr->assignCount +1;
   8.752 +        u.task = receivePr->numTimesAssignedToASlot +1;
   8.753          addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->receivers);
   8.754         #endif
   8.755        
   8.756 @@ -845,15 +962,10 @@
   8.757     senderID    = semReq->senderID;
   8.758     receiverSlv = semReq->receiverSlv;
   8.759     
   8.760 -      //suspending a task always makes the slave into an extra slot slave,
   8.761 -      // because it ends up in the resumeQ, even when resumes immediately.
   8.762 -      //Eventually task_end will put the slave into the freeExtraTaskSlvQ
   8.763 -   replaceWithNewSlotSlvIfNeeded( receiverSlv, semEnv );
   8.764 -
   8.765     receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself
   8.766     senderIDNumInt   = senderID[0] + 1;
   8.767     keySz = (receiverIDNumInt + senderIDNumInt) * sizeof(int32) + sizeof(int32);
   8.768 -   key = VMS_PI__malloc( keySz );
   8.769 +   key = PR_PI__malloc( keySz );
   8.770     key[0] = receiverIDNumInt + senderIDNumInt; //loc 0 is num int32s in key
   8.771     memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) );
   8.772     memcpy( &key[1 + receiverIDNumInt], senderID, senderIDNumInt * sizeof(int32));
   8.773 @@ -869,13 +981,13 @@
   8.774     if( waitingReq->reqType == send_from_to )
   8.775      {    //waiting request is a send, so pair it with this receive
   8.776        #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   8.777 -        Dependency newd;
   8.778 -        newd.from_vp = sendPr->slaveID;
   8.779 -        newd.from_task = sendPr->assignCount;
   8.780 -        newd.to_vp = receivePr->slaveID;
   8.781 -        newd.to_task = receivePr->assignCount +1;
   8.782 -        //addToListOfArraysDependency(newd,semEnv->commDependenciesList);  
   8.783 -        addToListOfArrays(Dependency,newd,semEnv->commDependenciesList);    
   8.784 +        Dependency newD;
   8.785 +        newD.from_vp = sendPr->slaveID;
   8.786 +        newD.from_task = sendPr->numTimesAssignedToASlot;
   8.787 +        newD.to_vp = receivePr->slaveID;
   8.788 +        newD.to_task = receivePr->numTimesAssignedToASlot +1;
   8.789 +        //addToListOfArraysDependency(newD,semEnv->commDependenciesList);  
   8.790 +        addToListOfArrays(Dependency,newD,semEnv->commDependenciesList);    
   8.791        #endif
   8.792        
   8.793           //have receiver slave, now set sender slave
   8.794 @@ -891,7 +1003,7 @@
   8.795        receiverSlv->dataRetFromReq = waitingReq->msg;
   8.796  
   8.797           //bring both processors back from suspend
   8.798 -      VMS_PI__free( waitingReq );
   8.799 +      PR_PI__free( waitingReq );
   8.800  
   8.801        resume_slaveVP( senderSlv,   semEnv );
   8.802        resume_slaveVP( receiverSlv, semEnv );
   8.803 @@ -901,66 +1013,26 @@
   8.804     printf("\nLang Impl Error: Should never be two waiting receives!\n");
   8.805   }
   8.806  
   8.807 -//==========================================================================
   8.808 -inline void
   8.809 -replaceWithNewSlotSlvIfNeeded( SlaveVP *requestingSlv, VSsSemEnv *semEnv )
   8.810 - { SlaveVP *newSlotSlv;
   8.811 -   VSsSemData *semData, *reqSemData;
   8.812  
   8.813 -   reqSemData = (VSsSemData *)requestingSlv->semanticData;
   8.814 -   if( reqSemData->slaveType != SlotTaskSlv )
   8.815 -      return; //already replaced, so just return
   8.816 -   
   8.817 -      //get a new slave to be the slot slave
   8.818 -   newSlotSlv     = readPrivQ( semEnv->freeExtraTaskSlvQ );
   8.819 -   if( newSlotSlv == NULL )
   8.820 -    { newSlotSlv  = VSs__create_slave_helper( &idle_fn, NULL, semEnv, 0);
   8.821 -         //just made a new extra task slave, so count it
   8.822 -      semEnv->numLiveExtraTaskSlvs += 1;
   8.823 -    }
   8.824 -   
   8.825 -      //set slave values to make it the slot slave
   8.826 -   semData                        = newSlotSlv->semanticData;
   8.827 -   semData->taskStub              = NULL;
   8.828 -   semData->slaveType             = SlotTaskSlv;
   8.829 -   semData->needsTaskAssigned     = TRUE;
   8.830 -   
   8.831 -      //a slot slave is pinned to a particular slot on a particular core
   8.832 -   newSlotSlv->animSlotAssignedTo = requestingSlv->animSlotAssignedTo;
   8.833 -   newSlotSlv->coreAnimatedBy     = requestingSlv->coreAnimatedBy;
   8.834 -    
   8.835 -      //put it into the slot slave matrix
   8.836 -   int32 slotNum = requestingSlv->animSlotAssignedTo->slotIdx;
   8.837 -   int32 coreNum = requestingSlv->coreAnimatedBy;
   8.838 -   semEnv->slotTaskSlvs[coreNum][slotNum] = newSlotSlv;
   8.839 -
   8.840 -      //Fix up requester, to be an extra slave now (but not a free one)
   8.841 -      // because it's not free, doesn't go into freeExtraTaskSlvQ
   8.842 -   semData = requestingSlv->semanticData;
   8.843 -   semData->slaveType = ExtraTaskSlv;
   8.844 - }
   8.845 -
   8.846 +/*Waits for all tasks that are direct children to end, then resumes calling
   8.847 + * task or thread
   8.848 + */
   8.849  inline void
   8.850  handleTaskwait( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv)
   8.851 - { VSsTaskStub* requestingTaskStub;
   8.852 -   VSsSemData* semData;
   8.853 -         DEBUG__printf1(dbgRqstHdlr,"Taskwait request from processor %d",
   8.854 + { VSsTaskStub* taskStub;
   8.855 + 
   8.856 +            DEBUG__printf1(dbgRqstHdlr,"Taskwait request from processor %d",
   8.857                                                        requestingSlv->slaveID)
   8.858      
   8.859 -   semData = (VSsSemData *)semReq->callingSlv->semanticData;
   8.860 -   requestingTaskStub = semData->taskStub;
   8.861 +   taskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task( requestingSlv, VSs_MAGIC_NUMBER);
   8.862     
   8.863 -   if( semData->taskStub->numLiveChildTasks == 0 )
   8.864 +   if( taskStub->numLiveChildTasks == 0 )
   8.865      {    //nobody to wait for, resume
   8.866        resume_slaveVP( requestingSlv, semEnv );
   8.867      }
   8.868 -   else  //have to wait, replace requester with new slot slv & mark waiting
   8.869 -    { 
   8.870 -       if(semData->slaveType == SlotTaskSlv){
   8.871 -         replaceWithNewSlotSlvIfNeeded( requestingSlv, semEnv );
   8.872 -       }
   8.873 -       
   8.874 -      requestingTaskStub->isWaitingForChildTasksToEnd = TRUE;
   8.875 +   else  //have to wait, mark waiting
   8.876 +    {        
   8.877 +      taskStub->isWaitingForChildTasksToEnd = TRUE;
   8.878      }    
   8.879   }
   8.880  
   8.881 @@ -974,7 +1046,7 @@
   8.882   
   8.883        DEBUG__printf1(dbgRqstHdlr,"Malloc request from processor %d",requestingSlv->slaveID)
   8.884  
   8.885 -   ptr = VMS_PI__malloc( semReq->sizeToMalloc );
   8.886 +   ptr = PR_PI__malloc( semReq->sizeToMalloc );
   8.887     requestingSlv->dataRetFromReq = ptr;
   8.888     resume_slaveVP( requestingSlv, semEnv );
   8.889   }
   8.890 @@ -985,7 +1057,7 @@
   8.891  handleFree( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv )
   8.892   {
   8.893           DEBUG__printf1(dbgRqstHdlr,"Free request from processor %d",requestingSlv->slaveID)
   8.894 -   VMS_PI__free( semReq->ptrToFree );
   8.895 +   PR_PI__free( semReq->ptrToFree );
   8.896     resume_slaveVP( requestingSlv, semEnv );
   8.897   }
   8.898  
   8.899 @@ -1034,8 +1106,8 @@
   8.900  
   8.901           DEBUG__printf1(dbgRqstHdlr,"StartDataSingleton request from processor %d",requestingSlv->slaveID)
   8.902     if( *(semReq->singletonPtrAddr) == NULL )
   8.903 -    { singleton                 = VMS_PI__malloc( sizeof(VSsSingleton) );
   8.904 -      singleton->waitQ          = makeVMSQ();
   8.905 +    { singleton                 = PR_PI__malloc( sizeof(VSsSingleton) );
   8.906 +      singleton->waitQ          = makePRQ();
   8.907        singleton->endInstrAddr   = 0x0;
   8.908        singleton->hasBeenStarted = FALSE;
   8.909        singleton->hasFinished    = FALSE;
   8.910 @@ -1133,13 +1205,13 @@
   8.911        //check ordering of entering transactions is correct
   8.912     semData = requestingSlv->semanticData;
   8.913     if( semData->highestTransEntered > semReq->transID )
   8.914 -    {    //throw VMS exception, which shuts down VMS.
   8.915 -      VMS_PI__throw_exception( "transID smaller than prev", requestingSlv, NULL);
   8.916 +    {    //throw PR exception, which shuts down PR.
   8.917 +      PR_PI__throw_exception( "transID smaller than prev", requestingSlv, NULL);
   8.918      }
   8.919        //add this trans ID to the list of transactions entered -- check when
   8.920        // end a transaction
   8.921     semData->highestTransEntered = semReq->transID;
   8.922 -   nextTransElem = VMS_PI__malloc( sizeof(TransListElem) );
   8.923 +   nextTransElem = PR_PI__malloc( sizeof(TransListElem) );
   8.924     nextTransElem->transID = semReq->transID;
   8.925     nextTransElem->nextTrans = semData->lastTransEntered;
   8.926     semData->lastTransEntered = nextTransElem;
   8.927 @@ -1189,7 +1261,7 @@
   8.928        //make sure transaction ended in same VP as started it.
   8.929     if( transStruc->VPCurrentlyExecuting != requestingSlv )
   8.930      {
   8.931 -      VMS_PI__throw_exception( "trans ended in diff VP", requestingSlv, NULL );
   8.932 +      PR_PI__throw_exception( "trans ended in diff VP", requestingSlv, NULL );
   8.933      }
   8.934  
   8.935        //make sure nesting is correct -- last ID entered should == this ID
   8.936 @@ -1197,7 +1269,7 @@
   8.937     lastTrans = semData->lastTransEntered;
   8.938     if( lastTrans->transID != semReq->transID )
   8.939      {
   8.940 -      VMS_PI__throw_exception( "trans incorrectly nested", requestingSlv, NULL );
   8.941 +      PR_PI__throw_exception( "trans incorrectly nested", requestingSlv, NULL );
   8.942      }
   8.943  
   8.944     semData->lastTransEntered = semData->lastTransEntered->nextTrans;
     9.1 --- a/VSs_Request_Handlers.h	Mon Sep 03 03:26:12 2012 -0700
     9.2 +++ b/VSs_Request_Handlers.h	Thu Oct 18 02:44:30 2012 -0700
     9.3 @@ -53,9 +53,7 @@
     9.4  handleEndDataSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv,
     9.5                      VSsSemEnv *semEnv );
     9.6  inline void
     9.7 -free_task_stub( VSsTaskStub *stubToFree );
     9.8 -inline void
     9.9 -replaceWithNewSlotSlvIfNeeded( SlaveVP *requestingSlv, VSsSemEnv *semEnv );
    9.10 +free_task_stub( PRMetaTask *stubToFree );
    9.11  
    9.12  
    9.13  #endif	/* _VSs_REQ_H */
    10.1 --- a/VSs_singleton_asm.s	Mon Sep 03 03:26:12 2012 -0700
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,21 +0,0 @@
    10.4 -
    10.5 -//Assembly code takes the return addr off the stack and saves
    10.6 -// into the singleton.  The first field in the singleton is the
    10.7 -// "endInstrAddr" field, and the return addr is at 0x4(%ebp)
    10.8 -.globl asm_save_ret_to_singleton
    10.9 -asm_save_ret_to_singleton:
   10.10 -    movq 0x8(%rbp),     %rax   #get ret address, ebp is the same as in the calling function
   10.11 -    movq     %rax,     (%rdi) #write ret addr to endInstrAddr field
   10.12 -    ret
   10.13 -
   10.14 -
   10.15 -//Assembly code changes the return addr on the stack to the one
   10.16 -// saved into the singleton by the end-singleton-fn
   10.17 -//The stack's return addr is at 0x4(%%ebp)
   10.18 -.globl asm_write_ret_from_singleton
   10.19 -asm_write_ret_from_singleton:
   10.20 -    movq    (%rdi),    %rax  #get endInstrAddr field
   10.21 -    movq      %rax,    0x8(%rbp) #write return addr to the stack of the caller
   10.22 -    ret
   10.23 -
   10.24 -