changeset 33:227db52cbd93 dev_expl_VP_and_DKU

VSs working
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 06 Mar 2013 14:32:33 +0100
parents 3787df8b95f9
children 71a20aa9d17a
files VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c
diffstat 4 files changed, 179 insertions(+), 112 deletions(-) [+]
line diff
     1.1 --- a/VSs.c	Fri Feb 01 17:18:57 2013 +0100
     1.2 +++ b/VSs.c	Wed Mar 06 14:32:33 2013 +0100
     1.3 @@ -209,7 +209,7 @@
     1.4     VSs__init_counter_data_structs();
     1.5     #endif
     1.6  
     1.7 -   semanticEnv->shutdownInitiated = FALSE;
     1.8 +   //semanticEnv->shutdownInitiated = FALSE;
     1.9     semanticEnv->coreIsDone = VMS_int__malloc( NUM_CORES * sizeof( bool32 ) );
    1.10     semanticEnv->numCoresDone = 0;
    1.11        //For each animation slot, there is an idle slave, and an initial
    1.12 @@ -245,7 +245,7 @@
    1.13     semanticEnv->freeExtraTaskSlvQ    = makeVMSQ();
    1.14     semanticEnv->taskReadyQ           = makeVMSQ();
    1.15     
    1.16 -   semanticEnv->argPtrHashTbl  = makeHashTable32( 16, &VMS_int__free );
    1.17 +   semanticEnv->argPtrHashTbl  = makeHashTable32( 20, &free_pointer_entry );
    1.18     semanticEnv->commHashTbl    = makeHashTable32( 16, &VMS_int__free );
    1.19     
    1.20     semanticEnv->nextCoreToGetNewSlv = 0;
    1.21 @@ -424,33 +424,39 @@
    1.22  #endif
    1.23      /* It's all allocated inside VMS's big chunk -- that's about to be freed, so
    1.24       *  nothing to do here */
    1.25 -/*
    1.26 +   //_VMSMasterEnv->shutdownInitiated = TRUE;
    1.27      int coreIdx, slotIdx;
    1.28      SlaveVP* slotSlv;
    1.29      for (coreIdx = 0; coreIdx < NUM_CORES; coreIdx++) {
    1.30          for (slotIdx = 0; slotIdx < NUM_ANIM_SLOTS; slotIdx++) {
    1.31              slotSlv = semanticEnv->slotTaskSlvs[coreIdx][slotIdx];
    1.32              VMS_int__free(slotSlv->semanticData);
    1.33 -            VMS_int__free( slotSlv->startOfStack );
    1.34 -            VMS_int__free( slotSlv );
    1.35 +            VMS_int__dissipate_slaveVP(slotSlv);
    1.36  #ifdef IDLE_SLAVES
    1.37              slotSlv = semanticEnv->idleSlv[coreIdx][slotIdx];
    1.38              VMS_int__free(slotSlv->semanticData);
    1.39 -            VMS_int__free( slotSlv->startOfStack );
    1.40 -            VMS_int__free( slotSlv );            
    1.41 +            VMS_int__dissipate_slaveVP(slotSlv);
    1.42  #endif
    1.43          }
    1.44      }
    1.45 +    int i;
    1.46 +    for (i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++) {
    1.47 +        freePrivQ(semanticEnv->fnSingletons[i].waitQ);
    1.48 +        freePrivQ(semanticEnv->transactionStrucs[i].waitingVPQ);
    1.49 +        freePrivQ(semanticEnv->criticalSection[i].waitQ);
    1.50 +    }
    1.51  
    1.52      freePrivQ(semanticEnv->freeExtraTaskSlvQ);
    1.53      freePrivQ(semanticEnv->slavesReadyToResumeQ);
    1.54      freePrivQ(semanticEnv->taskReadyQ);
    1.55 -   freeHashTable( semanticEnv->argPtrHashTbl );
    1.56 -   freeHashTable( semanticEnv->commHashTbl );
    1.57 -   VMS_int__free( _VMSMasterEnv->semanticEnv );
    1.58 - */
    1.59 -   VMS_SS__cleanup_at_end_of_shutdown();
    1.60 - }
    1.61 +    freePrivQ(semanticEnv->deferredSubmitsQ);
    1.62 +    freeHashTable(semanticEnv->argPtrHashTbl);
    1.63 +    freeHashTable(semanticEnv->commHashTbl);
    1.64 +    VMS_int__free(semanticEnv->coreIsDone);
    1.65 +    VMS_int__free(_VMSMasterEnv->semanticEnv);
    1.66 +
    1.67 +    VMS_SS__cleanup_at_end_of_shutdown();
    1.68 +}
    1.69  
    1.70  
    1.71  //===========================================================================
     2.1 --- a/VSs.h	Fri Feb 01 17:18:57 2013 +0100
     2.2 +++ b/VSs.h	Wed Mar 06 14:32:33 2013 +0100
     2.3 @@ -14,6 +14,7 @@
     2.4  #include "VMS_impl/VMS.h"
     2.5  #include "Measurement/dependency.h"
     2.6  
     2.7 +void free_pointer_entry(void* ptrEntry);
     2.8  /* Switch for Nexus support
     2.9   * Note: nexus incompatible with holistic recording (constraints not accessible)
    2.10   * But counter recording still functional, can build constraintless display
    2.11 @@ -78,25 +79,25 @@
    2.12   }
    2.13  VSsPointerEntry;
    2.14  
    2.15 -typedef struct
    2.16 - {
    2.17 -   void       **args; //ctld args must come first, as ptrs
    2.18 -   VSsTaskType *taskType;
    2.19 -   int32       *taskID;
    2.20 -   int32        numBlockingProp;
    2.21 -   SlaveVP     *slaveAssignedTo; //only valid before end task (thread)
    2.22 -   VSsPointerEntry  **ptrEntries;
    2.23 -   void*        parentTaskStub;
    2.24 -   int32        numLiveChildTasks;
    2.25 -   int32        numLiveChildThreads;
    2.26 -   bool32       isWaitingForChildTasksToEnd;
    2.27 -   bool32       isWaitingForChildThreadsToEnd;
    2.28 -   bool32       isEnded;
    2.29 -   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
    2.30 -   Unit parentUnit;
    2.31 -   Unit firstOfTask;
    2.32 -   #endif
    2.33 - }
    2.34 +typedef struct {
    2.35 +    void **args; //ctld args must come first, as ptrs
    2.36 +    VSsTaskType *taskType;
    2.37 +    int32 *taskID;
    2.38 +    int32 numBlockingProp;
    2.39 +    SlaveVP *slaveAssignedTo; //only valid before end task (thread)
    2.40 +    VSsPointerEntry **ptrEntries;
    2.41 +    void* parentTaskStub;
    2.42 +    int32 numLiveChildTasks;
    2.43 +    int32 numLiveChildThreads;
    2.44 +    bool32 isWaitingForChildTasksToEnd;
    2.45 +    bool32 isWaitingForChildThreadsToEnd;
    2.46 +    bool32 isEnded;
    2.47 +    int *argsMask;
    2.48 +#ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
    2.49 +    Unit parentUnit;
    2.50 +    Unit firstOfTask;
    2.51 +#endif
    2.52 +}
    2.53  VSsTaskStub;
    2.54  
    2.55  
    2.56 @@ -253,7 +254,7 @@
    2.57     #ifdef IDLE_SLAVES
    2.58     SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
    2.59     #endif
    2.60 -   int shutdownInitiated;
    2.61 +   //int shutdownInitiated;
    2.62   }
    2.63  VSsSemEnv;
    2.64  
     3.1 --- a/VSs_PluginFns.c	Fri Feb 01 17:18:57 2013 +0100
     3.2 +++ b/VSs_PluginFns.c	Wed Mar 06 14:32:33 2013 +0100
     3.3 @@ -66,7 +66,7 @@
     3.4      slotNum = slot->slotIdx;
     3.5  
     3.6      semEnv = (VSsSemEnv *) _semEnv;
     3.7 -
     3.8 +    
     3.9        //Check for suspended slaves that are ready to resume
    3.10      returnSlv = readPrivQ(semEnv->slavesReadyToResumeQ);
    3.11      if (returnSlv != NULL) //Yes, have a slave, so return it.
    3.12 @@ -130,22 +130,22 @@
    3.13                      semEnv->numCoresDone += 1;
    3.14                      semEnv->coreIsDone[coreNum] = TRUE;
    3.15  #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
    3.16 -                    semEnv->shutdownInitiated = TRUE;
    3.17 +                    _VMSMasterEnv->shutdownInitiated = TRUE;
    3.18                 
    3.19  #else
    3.20                      if (semEnv->numCoresDone == NUM_CORES) { //means no cores have work, and none can generate more
    3.21 -                        semEnv->shutdownInitiated = TRUE;
    3.22 +                        _VMSMasterEnv->shutdownInitiated = TRUE;
    3.23                      }
    3.24  #endif
    3.25                  }
    3.26              } else if (_VMSMasterEnv->numAnimatedSlaves == 0){
    3.27                  DEBUG__printf(TRUE,"Deadlock detected");
    3.28 -                semEnv->shutdownInitiated = TRUE;
    3.29 +                _VMSMasterEnv->shutdownInitiated = TRUE;
    3.30              }
    3.31              //return NULL.. no task and none to resume
    3.32              returnSlv = NULL;
    3.33              //except if shutdown has been initiated by this or other core
    3.34 -            if (semEnv->shutdownInitiated) {
    3.35 +            if (_VMSMasterEnv->shutdownInitiated) {
    3.36                  returnSlv = VMS_SS__create_shutdown_slave();
    3.37              }
    3.38              goto ReturnTheSlv; //don't need, but completes pattern
    3.39 @@ -155,12 +155,14 @@
    3.40  
    3.41  ReturnTheSlv: //Nina, doing gotos to here should help with holistic..
    3.42  
    3.43 -
    3.44 +if(returnSlv){
    3.45 +DEBUG__printf_w_task(dbgRqstHdlr,((VSsSemData*)returnSlv->semanticData)->taskStub,"scheduled"); 
    3.46 +}
    3.47  #ifdef IDLE_SLAVES
    3.48      if (!returnSlv) {
    3.49          returnSlv = semEnv->idlePr[coreNum][slotNum];
    3.50  
    3.51 -        if (semEnv->shutdownInitiated) {
    3.52 +        if (_VMSMasterEnv->shutdownInitiated) {
    3.53              returnSlv = VMS_SS__create_shutdown_slave();
    3.54          }
    3.55      }
    3.56 @@ -283,7 +285,7 @@
    3.57              break;
    3.58          case trans_end: handleTransEnd(semReq, reqSlv, semEnv);
    3.59              break;
    3.60 -        default: VMS_PI__throw_exception("Unknown request type", reqSlv, NULL);
    3.61 +        default: VMS_PI__throw_exception("Unknown request type\n", reqSlv, NULL);
    3.62              break;
    3.63      }
    3.64  }
    3.65 @@ -411,6 +413,7 @@
    3.66      newStub->slaveAssignedTo = NULL; //set later
    3.67      newStub->taskType = IS_A_THREAD;
    3.68      newStub->ptrEntries = NULL;
    3.69 +    newStub->argsMask = NULL;
    3.70      newStub->args = initData;
    3.71      newStub->numLiveChildTasks = 0;
    3.72      newStub->numLiveChildThreads = 0;
    3.73 @@ -419,7 +422,7 @@
    3.74      newStub->isWaitingForChildThreadsToEnd = FALSE;
    3.75      newStub->taskID = NULL;
    3.76      newStub->isEnded = FALSE;
    3.77 -    
    3.78 +
    3.79      return newStub;
    3.80  }
    3.81  
     4.1 --- a/VSs_Request_Handlers.c	Fri Feb 01 17:18:57 2013 +0100
     4.2 +++ b/VSs_Request_Handlers.c	Wed Mar 06 14:32:33 2013 +0100
     4.3 @@ -81,7 +81,12 @@
     4.4      return newEntry;
     4.5  }
     4.6  
     4.7 -void free_pointer_entry(VSsPointerEntry* ptrEntry){
     4.8 +void free_pointer_entry(void* _ptrEntry) {
     4.9 +    VSsPointerEntry* ptrEntry = (VSsPointerEntry*)_ptrEntry;
    4.10 +    int entriesStillInQ = ptrEntry->waitersQ->numWrites - ptrEntry->waitersQ->numReads;
    4.11 +    if (entriesStillInQ) {
    4.12 +        DEBUG__printf(dbgRqstHdlr, "Deleting Queue with %d entries still remaining", entriesStillInQ);
    4.13 +    }
    4.14      freePrivQ(ptrEntry->waitersQ);
    4.15      VMS_int__free(ptrEntry);
    4.16  }
    4.17 @@ -108,6 +113,8 @@
    4.18      newStub->isEnded = FALSE;
    4.19      newStub->taskID = NULL;
    4.20      newStub->parentTaskStub = NULL;
    4.21 +    newStub->argsMask = VMS_int__malloc(sizeof(int) * taskType->numCtldArgs);
    4.22 +    memset(newStub->argsMask, 0, sizeof(int) * taskType->numCtldArgs);
    4.23      //Copy the arg-pointers.. can be more arguments than just the ones 
    4.24      // that StarSs uses to control ordering of task execution.
    4.25      memcpy(newArgs, args, taskType->sizeOfArgs);
    4.26 @@ -128,6 +135,37 @@
    4.27      return newCarrier;
    4.28  }
    4.29  
    4.30 +    //check for identical pointers in args -- mask all but one copy
    4.31 +    //if one of pointers is writer, non-masked arg must be writer
    4.32 +int mask_duplicates(VSsTaskStub *taskStub){
    4.33 +    int argNum, i;
    4.34 +    int numUniqueArgs = 0;
    4.35 +    VSsTaskType* taskType = taskStub->taskType;
    4.36 +    void **args = taskStub->args;
    4.37 +
    4.38 +    for(argNum = 0; argNum < taskType->numCtldArgs; argNum++){
    4.39 +        //if already masked, don't need to check again
    4.40 +        if(taskStub->argsMask[argNum]) continue; 
    4.41 +        
    4.42 +        int unmasked = argNum;
    4.43 +        for(i=argNum+1; i<taskType->numCtldArgs; i++){
    4.44 +            if(args[argNum] == args[i]){
    4.45 +                if(taskType->argTypes[i] == WRITER){
    4.46 +                    taskStub->argsMask[unmasked] = TRUE;
    4.47 +                    unmasked = i;
    4.48 +                } else {
    4.49 +                    taskStub->argsMask[i] = TRUE;
    4.50 +                }
    4.51 +            }
    4.52 +        }
    4.53 +    }
    4.54 +    
    4.55 +    for(i=0; i<taskType->numCtldArgs; i++){
    4.56 +        if(!taskStub->argsMask[i]) numUniqueArgs++;
    4.57 +    }
    4.58 +    return numUniqueArgs;
    4.59 +}
    4.60 +
    4.61  void do_submit(VSsSemReq *semReq, VSsSemEnv *semEnv){
    4.62      uint32 key[5];
    4.63      HashEntry *rawHashEntry; //has char *, but use with uint32 *
    4.64 @@ -140,6 +178,8 @@
    4.65      HashTable *
    4.66              argPtrHashTbl = semEnv->argPtrHashTbl;
    4.67      
    4.68 +    int32 argNum;
    4.69 +    
    4.70      if(!semReq) {
    4.71          DEBUG__printf(dbgRqstHdlr,"***submitted Req is null***\n")
    4.72          return;}
    4.73 @@ -156,7 +196,11 @@
    4.74      args = semReq->args;
    4.75      taskType = semReq->taskType;
    4.76      taskStub = create_task_stub(taskType, args); //copies arg ptrs
    4.77 -    taskStub->numBlockingProp = taskType->numCtldArgs;
    4.78 +    //check for identical pointers in args -- mask all but one copy
    4.79 +    //if one of pointers is writer, non-masked arg must be writer
    4.80 +    int numUniqueArgs = mask_duplicates(taskStub);
    4.81 +    
    4.82 +    taskStub->numBlockingProp = numUniqueArgs;
    4.83      taskStub->taskID = semReq->taskID; //may be NULL
    4.84  
    4.85      VSsSemData*
    4.86 @@ -178,8 +222,11 @@
    4.87       *Processing an argument means getting the hash of the pointer.  Then,
    4.88       * looking up the hash entry.  (If none, create one).
    4.89       */
    4.90 -    int32 argNum;
    4.91 +
    4.92      for (argNum = 0; argNum < taskType->numCtldArgs; argNum++) {
    4.93 +        //only process unmasked args
    4.94 +        if(taskStub->argsMask[argNum]) continue;
    4.95 +        
    4.96          key[0] = 4; //two 32b values in key
    4.97          *((uint64*) & key[1]) = (uint64) args[argNum]; //write 64b into two 32b
    4.98          *((uint64*) & key[3]) = (uint64) taskStub->parentTaskStub ;
    4.99 @@ -210,15 +257,15 @@
   4.100               * task-stub into the readyQ.  At the same time, increment
   4.101               * the hash-entry's count of enabled and non-finished readers.*/
   4.102                  taskStub->numBlockingProp -= 1;
   4.103 -                DEBUG__printf_w_task(dbgRqstHdlr, taskStub, "taking ptrEntry %p (read)", ptrEntry);
   4.104 +                DEBUG__printf_w_task(dbgSS, taskStub, "taking ptrEntry %p (read)", ptrEntry);
   4.105                  if (taskStub->numBlockingProp == 0) {
   4.106                      writePrivQ(taskStub, semEnv->taskReadyQ);
   4.107 -                    DEBUG__printf_w_task(dbgRqstHdlr, taskStub, "ready (dependencies fulfilled)");
   4.108 +                    DEBUG__printf_w_task(dbgSS, taskStub, "ready (dependencies fulfilled)");
   4.109                  }
   4.110                  ptrEntry->numEnabledNonDoneReaders += 1;
   4.111              } else { /*Otherwise, the reader is put into the hash-entry's Q of
   4.112               * waiters*/
   4.113 -                DEBUG__printf_w_task(dbgRqstHdlr, taskStub, "getting in line for ptrEntry %p (read)", ptrEntry);
   4.114 +                DEBUG__printf_w_task(dbgSS, taskStub, "getting in line for ptrEntry %p (read)", ptrEntry);
   4.115                  taskCarrier = create_task_carrier(taskStub, argNum, READER);
   4.116                  writePrivQ(taskCarrier, ptrEntry->waitersQ);
   4.117              }
   4.118 @@ -232,14 +279,14 @@
   4.119                * task-stub. If the count is zero, then put the task-stub
   4.120                * into the readyQ.*/
   4.121                  taskStub->numBlockingProp -= 1;
   4.122 -                DEBUG__printf_w_task(dbgRqstHdlr,taskStub,"taking ptrEntry %p (write)",ptrEntry);
   4.123 +                DEBUG__printf_w_task(dbgSS,taskStub,"taking ptrEntry %p (write)",ptrEntry);
   4.124                  if (taskStub->numBlockingProp == 0) {
   4.125 -                    DEBUG__printf_w_task(dbgRqstHdlr, taskStub, "ready (dependencies fulfilled)");
   4.126 +                    DEBUG__printf_w_task(dbgSS, taskStub, "ready (dependencies fulfilled)");
   4.127                      writePrivQ(taskStub, semEnv->taskReadyQ);
   4.128                  }
   4.129                  ptrEntry->hasEnabledNonFinishedWriter = TRUE;
   4.130              } else {/*Otherwise, put the writer into the entry's Q of waiters.*/
   4.131 -                DEBUG__printf_w_task(dbgRqstHdlr,taskStub,"getting in line for ptrEntry %p (write)",ptrEntry);
   4.132 +                DEBUG__printf_w_task(dbgSS,taskStub,"getting in line for ptrEntry %p (write)",ptrEntry);
   4.133                  taskCarrier = create_task_carrier(taskStub, argNum, WRITER);
   4.134                  writePrivQ(taskCarrier, ptrEntry->waitersQ);
   4.135              }
   4.136 @@ -360,6 +407,7 @@
   4.137      //Eventually task_end will put the slave into the freeExtraTaskSlvQ
   4.138      replaceWithNewSlotSlvIfNeeded(semReq->callingSlv, semEnv);
   4.139  
   4.140 +    DEBUG__printf_w_task(dbgRqstHdlr, ((VSsSemData*)semReq->callingSlv->semanticData)->taskStub, "submit req for ");
   4.141  #ifdef DEBUG__TURN_ON_DEBUG_PRINT
   4.142      if (dbgRqstHdlr) {
   4.143          if (semReq->taskID) {
   4.144 @@ -374,7 +422,6 @@
   4.145          }
   4.146      }
   4.147  #endif
   4.148 -    DEBUG__printf(dbgRqstHdlr, "submit req from slaveID %d", semReq->callingSlv->slaveID);
   4.149      
   4.150      // Throttle if too many tasks
   4.151      
   4.152 @@ -487,28 +534,16 @@
   4.153       */
   4.154      int32 argNum;
   4.155      for (argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++) {
   4.156 -        /* commented out 'cause remembering entry ptr when create stub
   4.157 -        key[0] = 2; //says are 2 32b values in key
   4.158 -         *( (uint64*)&key[1] ) = args[argNum];  //write 64b ptr into two 32b
   4.159 -
   4.160 -         /*If the hash entry was chained, put it at the
   4.161 -         * start of the chain.  (Means no-longer-used pointers accumulate
   4.162 -         * at end of chain, decide garbage collection later) 
   4.163 -         */
   4.164 -        /*NOTE: don't do hash lookups here, instead, have a pointer to the
   4.165 -         * hash entry inside task-stub, put there during task creation.
   4.166 -        rawHashEntry = getEntryFromTable32( key, ptrHashTbl );
   4.167 -        ptrEntry = (VSsPointerEntry *)rawHashEntry->content;
   4.168 -        if( ptrEntry == NULL ) 
   4.169 -            VMS_App__throw_exception("hash entry NULL", NULL, NULL);
   4.170 -         */
   4.171 +        //only process unmasked args
   4.172 +        if(endingTaskStub->argsMask[argNum]) continue;
   4.173 +        
   4.174  
   4.175          ptrEntry = ptrEntries[argNum];
   4.176          /*check if the ending task was reader of this arg*/
   4.177          if (endingTaskType->argTypes[argNum] == READER) { /*then decrement the enabled and non-finished reader-count in
   4.178            * the hash-entry. */
   4.179              ptrEntry->numEnabledNonDoneReaders -= 1;
   4.180 -            DEBUG__printf(dbgRqstHdlr,"Releasing read on ptrEntry %p",ptrEntry)
   4.181 +            DEBUG__printf(dbgSS,"Releasing read on ptrEntry %p",ptrEntry)
   4.182          #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   4.183              Unit u;
   4.184              u.vp = semReq->callingSlv->slaveID;
   4.185 @@ -526,11 +561,17 @@
   4.186              /*If the count becomes zero, then take the next entry from the Q. 
   4.187               *It should be a writer, or else there's a bug in this algorithm.*/
   4.188              if (ptrEntry->numEnabledNonDoneReaders == 0) {
   4.189 -                DEBUG__printf(dbgRqstHdlr,"ptrEntry %p now free",ptrEntry)
   4.190 +                DEBUG__printf(dbgSS,"ptrEntry %p now free",ptrEntry)
   4.191                  waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ);
   4.192                  if (waitingTaskCarrier == NULL) { //TODO: looks safe to delete the ptr entry at this point
   4.193 -                    DEBUG__printf(dbgRqstHdlr,"no waiting writer found for ptrEntry %p\n",ptrEntry)
   4.194 -                    //free_pointer_entry(ptrEntry);
   4.195 +/*
   4.196 +                    uint32 key[5];
   4.197 +                    key[0] = 4; //two 32b values in key
   4.198 +                    *((uint64*) & key[1]) = (uint64) args[argNum]; //write 64b into two 32b
   4.199 +                    *((uint64*) & key[3]) = (uint64) endingTaskStub->parentTaskStub;
   4.200 +                    deleteEntryFromTable32(key, semEnv->argPtrHashTbl);
   4.201 +                    free_pointer_entry(ptrEntry);
   4.202 +*/
   4.203                      continue; //next iter of loop
   4.204                  }
   4.205                  if (waitingTaskCarrier->isReader)
   4.206 @@ -545,12 +586,12 @@
   4.207                   * task-stub.  If the count has reached zero, then put the
   4.208                   * task-stub into the readyQ.*/
   4.209                  waitingTaskStub->numBlockingProp -= 1;
   4.210 -                DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"taking ptrEntry %p (write)",ptrEntry);
   4.211 +                DEBUG__printf_w_task(dbgSS,waitingTaskStub,"taking ptrEntry %p (write)",ptrEntry);
   4.212                  if (waitingTaskStub->numBlockingProp == 0) {
   4.213 -                    DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"ready (dependencies fulfilled)");
   4.214 +                    DEBUG__printf_w_task(dbgSS,waitingTaskStub,"ready (dependencies fulfilled)");
   4.215                      writePrivQ(waitingTaskStub, semEnv->taskReadyQ);
   4.216                  } else {
   4.217 -                    DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"still blocked on %d args",waitingTaskStub->numBlockingProp); 
   4.218 +                    DEBUG__printf_w_task(dbgSS,waitingTaskStub,"still blocked on %d args",waitingTaskStub->numBlockingProp); 
   4.219                  }
   4.220                  
   4.221              }
   4.222 @@ -590,29 +631,34 @@
   4.223              ptrEntry->lastWriter.task = semReq->callingSlv->assignCount;
   4.224          #endif
   4.225  
   4.226 -            DEBUG__printf(dbgRqstHdlr,"Releasing write on ptrEntry %p; ",ptrEntry)
   4.227 +            DEBUG__printf(dbgSS,"Releasing write on ptrEntry %p; ",ptrEntry)
   4.228              /*Take the next waiter from the hash-entry's Q.*/
   4.229              waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ);
   4.230              if (waitingTaskCarrier == NULL) { //TODO: looks safe to delete ptr entry at this point
   4.231 -                DEBUG__printf(dbgRqstHdlr,"no waiting task on ptrEntry %p; deleting",ptrEntry);
   4.232 -                //free_pointer_entry(ptrEntry);
   4.233 -                //NOPE, still tasks around that kept the pointer...
   4.234 +/*
   4.235 +                uint32 key[5];
   4.236 +                key[0] = 4; //two 32b values in key
   4.237 +                *((uint64*) & key[1]) = (uint64) args[argNum]; //write 64b into two 32b
   4.238 +                *((uint64*) & key[3]) = (uint64) endingTaskStub->parentTaskStub;
   4.239 +                deleteEntryFromTable32(key, semEnv->argPtrHashTbl);
   4.240 +                free_pointer_entry(ptrEntry);
   4.241 +*/
   4.242                  continue; //go to next iter of loop, done here.
   4.243              }
   4.244              waitingTaskStub = waitingTaskCarrier->taskStub;
   4.245  
   4.246              /*If task is a writer of this hash-entry's pointer*/
   4.247              if (!waitingTaskCarrier->isReader) { /* then turn the flag back on.*/
   4.248 -                DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"taking ptrEntry %p (write)",ptrEntry);
   4.249 +                DEBUG__printf_w_task(dbgSS,waitingTaskStub,"taking ptrEntry %p (write)",ptrEntry);
   4.250                  ptrEntry->hasEnabledNonFinishedWriter = TRUE;
   4.251                  /*Decrement the writer's blocking-propendent-count in task-stub
   4.252                   * If it becomes zero, then put the task-stub into the readyQ.*/
   4.253                  waitingTaskStub->numBlockingProp -= 1;
   4.254                  if (waitingTaskStub->numBlockingProp == 0) {
   4.255 -                    DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"ready (dependencies fulfilled)");
   4.256 +                    DEBUG__printf_w_task(dbgSS,waitingTaskStub,"ready (dependencies fulfilled)");
   4.257                      writePrivQ(waitingTaskStub, semEnv->taskReadyQ);
   4.258                  } else {
   4.259 -                    DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"still blocked on %d args; ",waitingTaskStub->numBlockingProp); 
   4.260 +                    DEBUG__printf_w_task(dbgSS,waitingTaskStub,"still blocked on %d args; ",waitingTaskStub->numBlockingProp); 
   4.261                  }
   4.262                  VMS_PI__free(waitingTaskCarrier);
   4.263              } else { /*Waiting task is a reader, so do a loop, of all waiting readers
   4.264 @@ -621,12 +667,12 @@
   4.265                  * readers.*/
   4.266                      //deal with tasks suspended by taskwait_on here - these don't count as a dependency but are otherwise treated like readers
   4.267                      if(waitingTaskCarrier->isSuspended){
   4.268 -                        DEBUG__printf_w_task(dbgRqstHdlr, waitingTaskStub, "taskwaiting on ptr %p resumed; ", ptrEntry);
   4.269 +                        DEBUG__printf_w_task(dbgSS, waitingTaskStub, "taskwaiting on ptr %p resumed; ", ptrEntry);
   4.270                          resume_slaveVP(waitingTaskStub->slaveAssignedTo, semEnv);
   4.271                      } else {
   4.272  
   4.273                          ptrEntry->numEnabledNonDoneReaders += 1;
   4.274 -                        DEBUG__printf_w_task(dbgRqstHdlr, waitingTaskStub, "now on ptrEntry %p (read)",ptrEntry);
   4.275 +                        DEBUG__printf_w_task(dbgSS, waitingTaskStub, "now on ptrEntry %p (read)",ptrEntry);
   4.276                          //if(waitingTaskStub->taskID) {  DEBUG__printf2(dbgRqstHdlr,"Reader %d now on ptrEntry %p; ",waitingTaskStub->taskID[1],ptrEntry) }
   4.277                          //else {DEBUG__printf2(dbgRqstHdlr,"Reader %p now on ptrEntry %p; ",waitingTaskStub,ptrEntry)}
   4.278                          /*Decrement the blocking propendents count of the reader's
   4.279 @@ -635,10 +681,10 @@
   4.280                          waitingTaskStub->numBlockingProp -= 1;
   4.281                          
   4.282                          if (waitingTaskStub->numBlockingProp == 0) {
   4.283 -                            DEBUG__printf_w_task(dbgRqstHdlr, waitingTaskStub, "ready (dependencies fulfilled)");
   4.284 +                            DEBUG__printf_w_task(dbgSS, waitingTaskStub, "ready (dependencies fulfilled)");
   4.285                              writePrivQ(waitingTaskStub, semEnv->taskReadyQ);
   4.286                          } else {
   4.287 -                            DEBUG__printf_w_task(dbgRqstHdlr,waitingTaskStub,"still blocked on %d args",waitingTaskStub->numBlockingProp); 
   4.288 +                            DEBUG__printf_w_task(dbgSS,waitingTaskStub,"still blocked on %d args",waitingTaskStub->numBlockingProp); 
   4.289                          }
   4.290                      } //if-else, suspended or normal reader
   4.291                      //discard carrier
   4.292 @@ -684,11 +730,18 @@
   4.293  }
   4.294  
   4.295  void
   4.296 -free_task_stub(VSsTaskStub *stubToFree) 
   4.297 - { if(stubToFree->ptrEntries != NULL ) //a thread stub has NULL entry
   4.298 -    { VMS_PI__free( stubToFree->ptrEntries );
   4.299 +free_task_stub(VSsTaskStub *stubToFree) {
   4.300 +    if (stubToFree->ptrEntries != NULL) //a thread stub has NULL entry
   4.301 +    {
   4.302 +        VMS_PI__free(stubToFree->ptrEntries);
   4.303      }
   4.304 -   VMS_PI__free( stubToFree );
   4.305 +    if (stubToFree->argsMask != NULL) {
   4.306 +        VMS_PI__free(stubToFree->argsMask);
   4.307 +    }
   4.308 +    if(stubToFree->taskID != NULL) { //TaskID is handed from user most of the time, not sure if overreaching (but why would you want to keep it?)
   4.309 +        VMS_PI__free(stubToFree->taskID);
   4.310 +    }
   4.311 +    VMS_PI__free(stubToFree);
   4.312  }
   4.313  
   4.314  //========================== Task Comm handlers ===========================
   4.315 @@ -1093,8 +1146,7 @@
   4.316      semData->slaveType = ExtraTaskSlv;
   4.317  }
   4.318  
   4.319 -void
   4.320 -handleTaskwait(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.321 +void handleTaskwait(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.322      VSsTaskStub* requestingTaskStub;
   4.323      VSsSemData* semData;
   4.324      DEBUG__printf1(dbgRqstHdlr, "Taskwait request from processor %d",
   4.325 @@ -1103,14 +1155,12 @@
   4.326              semData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.327      requestingTaskStub = semData->taskStub;
   4.328  
   4.329 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.330 +
   4.331      if (semData->taskStub->numLiveChildTasks == 0) { //nobody to wait for, resume
   4.332          resume_slaveVP(requestingSlv, semEnv);
   4.333      } else //have to wait, replace requester with new slot slv & mark waiting
   4.334      {
   4.335 -        if (semData->slaveType == SlotTaskSlv) {
   4.336 -         replaceWithNewSlotSlvIfNeeded( requestingSlv, semEnv );
   4.337 -        }
   4.338 -
   4.339          requestingTaskStub->isWaitingForChildTasksToEnd = TRUE;
   4.340      }
   4.341  }
   4.342 @@ -1128,6 +1178,7 @@
   4.343      semData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.344      requestingTaskStub = semData->taskStub;
   4.345  
   4.346 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.347      
   4.348      void* ptr = semReq->args;
   4.349  
   4.350 @@ -1163,16 +1214,18 @@
   4.351      }
   4.352  }
   4.353  
   4.354 -void handleCriticalStart(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv){
   4.355 +void handleCriticalStart(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.356      VSsSemData* semData;
   4.357      int32 criticalID;
   4.358      DEBUG__printf1(dbgRqstHdlr, "CriticalStart request from processor %d",
   4.359 -            requestingSlv->slaveID)
   4.360 +            requestingSlv->slaveID);
   4.361 +
   4.362 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.363  
   4.364      semData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.365 -    
   4.366 +
   4.367      criticalID = semReq->criticalID;
   4.368 -    if(!semEnv->criticalSection[criticalID].isOccupied){
   4.369 +    if (!semEnv->criticalSection[criticalID].isOccupied) {
   4.370          semEnv->criticalSection[criticalID].isOccupied = TRUE;
   4.371          resume_slaveVP(requestingSlv, semEnv);
   4.372      } else {
   4.373 @@ -1185,7 +1238,9 @@
   4.374      SlaveVP *waitingSlv;
   4.375      int32 criticalID;
   4.376      DEBUG__printf1(dbgRqstHdlr, "CriticalEnd request from processor %d",
   4.377 -            requestingSlv->slaveID)
   4.378 +            requestingSlv->slaveID);
   4.379 +    
   4.380 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.381  
   4.382      semData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.383      
   4.384 @@ -1202,22 +1257,22 @@
   4.385  
   4.386  /*
   4.387   */
   4.388 -void
   4.389 -handleMalloc(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.390 +void handleMalloc(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.391      void *ptr;
   4.392  
   4.393 -    DEBUG__printf1(dbgRqstHdlr, "Malloc request from processor %d", requestingSlv->slaveID)
   4.394 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.395 +
   4.396 +    DEBUG__printf1(dbgRqstHdlr, "Malloc request from processor %d", requestingSlv->slaveID);
   4.397  
   4.398      ptr = VMS_PI__malloc(semReq->sizeToMalloc);
   4.399      requestingSlv->dataRetFromReq = ptr;
   4.400      resume_slaveVP(requestingSlv, semEnv);
   4.401  }
   4.402 -
   4.403  /*
   4.404   */
   4.405 -void
   4.406 -handleFree(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.407 -    DEBUG__printf1(dbgRqstHdlr, "Free request from processor %d", requestingSlv->slaveID)
   4.408 +void handleFree(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.409 +    DEBUG__printf1(dbgRqstHdlr, "Free request from processor %d", requestingSlv->slaveID);
   4.410 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.411      VMS_PI__free(semReq->ptrToFree);
   4.412      resume_slaveVP(requestingSlv, semEnv);
   4.413  }
   4.414 @@ -1232,6 +1287,7 @@
   4.415  void 
   4.416  handleStartSingleton_helper(VSsSingleton *singleton, SlaveVP *reqstingSlv,
   4.417          VSsSemEnv *semEnv) {
   4.418 +    replaceWithNewSlotSlvIfNeeded(reqstingSlv, semEnv);
   4.419      if (singleton->hasFinished) { //the code that sets the flag to true first sets the end instr addr
   4.420          reqstingSlv->dataRetFromReq = singleton->endInstrAddr;
   4.421  #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   4.422 @@ -1294,7 +1350,7 @@
   4.423          // so if this is true, is an error
   4.424          ERROR("singleton code ran twice");
   4.425      }
   4.426 -
   4.427 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.428      singleton->hasFinished = TRUE;
   4.429  #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   4.430      singleton->executingUnit.vp = requestingSlv->slaveID;
   4.431 @@ -1347,7 +1403,8 @@
   4.432   */
   4.433  void
   4.434  handleAtomic(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.435 -    DEBUG__printf1(dbgRqstHdlr, "Atomic request from processor %d", requestingSlv->slaveID)
   4.436 +    DEBUG__printf1(dbgRqstHdlr, "Atomic request from processor %d", requestingSlv->slaveID);
   4.437 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.438      semReq->fnToExecInMaster(semReq->dataForFn);
   4.439      resume_slaveVP(requestingSlv, semEnv);
   4.440  }
   4.441 @@ -1372,8 +1429,8 @@
   4.442      VSsSemData *semData;
   4.443      TransListElem *nextTransElem;
   4.444  
   4.445 -    DEBUG__printf1(dbgRqstHdlr, "TransStart request from processor %d", requestingSlv->slaveID)
   4.446 -
   4.447 +    DEBUG__printf1(dbgRqstHdlr, "TransStart request from processor %d", requestingSlv->slaveID);
   4.448 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.449      //check ordering of entering transactions is correct
   4.450      semData = requestingSlv->semanticData;
   4.451      if (semData->highestTransEntered > semReq->transID) { //throw VMS exception, which shuts down VMS.
   4.452 @@ -1420,7 +1477,7 @@
   4.453      SlaveVP *waitingSlv;
   4.454      VSsTrans *transStruc;
   4.455      TransListElem *lastTrans;
   4.456 -
   4.457 +    replaceWithNewSlotSlvIfNeeded(requestingSlv, semEnv);
   4.458      DEBUG__printf1(dbgRqstHdlr, "TransEnd request from processor %d", requestingSlv->slaveID)
   4.459  
   4.460      transStruc = &(semEnv->transactionStrucs[ semReq->transID ]);