changeset 39:0715109abb08 dev_expl_VP_and_DKU

make wrapper lib for linking against files produced by mercurium (ompss preprocessor) -- ! separates args and dependencies
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Mon, 03 Jun 2013 18:34:56 +0200
parents a951b38d2cfc
children df464a215387
files VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c
diffstat 4 files changed, 156 insertions(+), 98 deletions(-) [+]
line diff
     1.1 --- a/VSs.c	Fri May 17 17:49:49 2013 +0200
     1.2 +++ b/VSs.c	Mon Jun 03 18:34:56 2013 +0200
     1.3 @@ -94,7 +94,7 @@
     1.4        // the parent be already ended, and have one child (the seed).  This
     1.5        // will make the dissipate handler do the right thing when the seed
     1.6        // is dissipated.
     1.7 -   threadTaskStub = create_thread_task_stub( initData );
     1.8 +   threadTaskStub = create_thread_task_stub( initData);
     1.9     parentTaskStub = create_thread_task_stub( NULL );
    1.10     parentTaskStub->isEnded = TRUE;
    1.11     parentTaskStub->numLiveChildThreads = 1; //so dissipate works for seed
    1.12 @@ -248,6 +248,7 @@
    1.13     
    1.14     semanticEnv->argPtrHashTbl  = makeHashTable32( 20, &free_pointer_entry );
    1.15     semanticEnv->commHashTbl    = makeHashTable32( 16, &VMS_int__free );
    1.16 +   semanticEnv->criticalHashTbl = makeHashTable32( 16, &VMS_int__free );
    1.17     
    1.18     semanticEnv->nextCoreToGetNewSlv = 0;
    1.19     
    1.20 @@ -266,12 +267,6 @@
    1.21        semanticEnv->fnSingletons[i].hasFinished       = FALSE;
    1.22        semanticEnv->fnSingletons[i].waitQ             = makeVMSQ();
    1.23        semanticEnv->transactionStrucs[i].waitingVPQ   = makeVMSQ();
    1.24 -      semanticEnv->criticalSection[i].isOccupied     = FALSE;
    1.25 -      semanticEnv->criticalSection[i].waitQ          = makeVMSQ();
    1.26 -#ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
    1.27 -      semanticEnv->criticalSection[i].previous.vp    = 0;
    1.28 -      semanticEnv->criticalSection[i].previous.task  = 0;
    1.29 -#endif
    1.30      }
    1.31  
    1.32     semanticEnv->numLiveExtraTaskSlvs   = 0; //must be last
    1.33 @@ -444,7 +439,6 @@
    1.34      for (i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++) {
    1.35          freePrivQ(semanticEnv->fnSingletons[i].waitQ);
    1.36          freePrivQ(semanticEnv->transactionStrucs[i].waitingVPQ);
    1.37 -        freePrivQ(semanticEnv->criticalSection[i].waitQ);
    1.38      }
    1.39  
    1.40      freePrivQ(semanticEnv->freeExtraTaskSlvQ);
    1.41 @@ -453,6 +447,7 @@
    1.42      freePrivQ(semanticEnv->deferredSubmitsQ);
    1.43      freeHashTable(semanticEnv->argPtrHashTbl);
    1.44      freeHashTable(semanticEnv->commHashTbl);
    1.45 +    freeHashTable(semanticEnv->criticalHashTbl);
    1.46      VMS_int__free(semanticEnv->coreIsDone);
    1.47      VMS_int__free(_VMSMasterEnv->semanticEnv);
    1.48  
    1.49 @@ -503,22 +498,23 @@
    1.50  
    1.51  
    1.52  //======================= task submit and end ==============================
    1.53 +
    1.54  /*
    1.55   */
    1.56 -void
    1.57 -VSs__submit_task( VSsTaskType *taskType, void *args)
    1.58 - { VSsSemReq  reqData;
    1.59 +void VSs__submit_task(VSsTaskType *taskType, void *args, void* deps) {
    1.60 +    VSsSemReq reqData;
    1.61  
    1.62 -   reqData.reqType    = submit_task;
    1.63 -   
    1.64 -   reqData.taskType   = taskType;
    1.65 -   reqData.args       = args;
    1.66 -   reqData.callingSlv = currVP;
    1.67 -  
    1.68 -   reqData.taskID     = NULL;
    1.69 - 
    1.70 -   VMS_WL__send_sem_request( &reqData, currVP );
    1.71 - }
    1.72 +    reqData.reqType = submit_task;
    1.73 +
    1.74 +    reqData.taskType = taskType;
    1.75 +    reqData.args = args;
    1.76 +    reqData.deps = deps;
    1.77 +    reqData.callingSlv = currVP;
    1.78 +
    1.79 +    reqData.taskID = NULL;
    1.80 +
    1.81 +    VMS_WL__send_sem_request(&reqData, currVP);
    1.82 +}
    1.83  
    1.84  int32 *
    1.85  VSs__create_taskID_of_size( int32 numInts)
    1.86 @@ -527,21 +523,21 @@
    1.87     taskID    = VMS_WL__malloc( sizeof(int32) + numInts * sizeof(int32) );
    1.88     taskID[0] = numInts;
    1.89     return taskID;
    1.90 - }
    1.91 +}
    1.92  
    1.93 -void
    1.94 -VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID)
    1.95 - { VSsSemReq  reqData;
    1.96 +void VSs__submit_task_with_ID(VSsTaskType *taskType, void *args, void* deps, int32 *taskID) {
    1.97 +    VSsSemReq reqData;
    1.98  
    1.99 -   reqData.reqType    = submit_task;
   1.100 -   
   1.101 -   reqData.taskType   = taskType;
   1.102 -   reqData.args       = args;
   1.103 -   reqData.taskID     = taskID;
   1.104 -   reqData.callingSlv = currVP;
   1.105 - 
   1.106 -   VMS_WL__send_sem_request( &reqData, currVP );
   1.107 - }
   1.108 +    reqData.reqType = submit_task;
   1.109 +
   1.110 +    reqData.taskType = taskType;
   1.111 +    reqData.args = args;
   1.112 +    reqData.deps = deps;
   1.113 +    reqData.taskID = taskID;
   1.114 +    reqData.callingSlv = currVP;
   1.115 +
   1.116 +    VMS_WL__send_sem_request(&reqData, currVP);
   1.117 +}
   1.118  
   1.119  
   1.120  /*This call is the last to happen in every task.  It causes the slave to
   1.121 @@ -600,25 +596,25 @@
   1.122  }
   1.123  
   1.124  void
   1.125 -VSs__start_critical(int32 name){
   1.126 +VSs__start_critical(void* lock){
   1.127      VSsSemReq  reqData;
   1.128  
   1.129     reqData.reqType      = critical_start;
   1.130     reqData.callingSlv   = currVP;
   1.131     
   1.132 -   reqData.criticalID = name;
   1.133 +   reqData.criticalID = lock;
   1.134     
   1.135     VMS_WL__send_sem_request( &reqData, currVP );
   1.136  }
   1.137  
   1.138  void
   1.139 -VSs__end_critical(int32 name){
   1.140 +VSs__end_critical(void* lock){
   1.141      VSsSemReq  reqData;
   1.142  
   1.143     reqData.reqType      = critical_end;
   1.144     reqData.callingSlv   = currVP;
   1.145     
   1.146 -   reqData.criticalID = name;
   1.147 +   reqData.criticalID = lock;
   1.148     
   1.149     VMS_WL__send_sem_request( &reqData, currVP );
   1.150  }
     2.1 --- a/VSs.h	Fri May 17 17:49:49 2013 +0200
     2.2 +++ b/VSs.h	Mon Jun 03 18:34:56 2013 +0200
     2.3 @@ -58,10 +58,9 @@
     2.4  typedef struct
     2.5   {
     2.6     VSsTaskFnPtr fn;
     2.7 -   int32  numTotalArgs;//the number of inputs to function
     2.8 -   int32  numCtldArgs;//how many of args have dependencies
     2.9 -   int32 *argTypes;   //says reader, writer, or non-ctld
    2.10 -   int32 *argSizes;   //for detecting overlap
    2.11 +   int32  numDeps;//how many of args have dependencies
    2.12 +   int32 *depsTypes;   //says reader, writer, or non-ctld
    2.13 +   size_t *depsSizes;   //for detecting overlap
    2.14     int32  sizeOfArgs; //for memcpy of args struct
    2.15   }
    2.16  VSsTaskType;
    2.17 @@ -80,7 +79,8 @@
    2.18  VSsPointerEntry;
    2.19  
    2.20  typedef struct {
    2.21 -    void **args; //ctld args must come first, as ptrs
    2.22 +    void **args; //for calling only, can contain values
    2.23 +    void** depsAddrs; //pointers only 
    2.24      VSsTaskType *taskType;
    2.25      int32 *taskID;
    2.26      int32 numBlockingProp;
    2.27 @@ -92,7 +92,7 @@
    2.28      bool32 isWaitingForChildTasksToEnd;
    2.29      bool32 isWaitingForChildThreadsToEnd;
    2.30      bool32 isEnded;
    2.31 -    int *argsMask;
    2.32 +    int *depsMask;
    2.33  #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
    2.34      Unit parentUnit;
    2.35      Unit firstOfTask;
    2.36 @@ -179,6 +179,7 @@
    2.37     SlaveVP           *callingSlv;
    2.38     VSsTaskType       *taskType;
    2.39     void              *args;
    2.40 +   void              *deps;
    2.41     VSsTaskStub       *taskStub;
    2.42     
    2.43     SlaveVP           *senderSlv;
    2.44 @@ -204,7 +205,7 @@
    2.45     void              *dataForFn;
    2.46  
    2.47     int32              transID;
    2.48 -   int32              criticalID;
    2.49 +   void*              criticalID;
    2.50   }
    2.51  /* VSsSemReq */;
    2.52  
    2.53 @@ -217,6 +218,7 @@
    2.54     SlaveVP         *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
    2.55     HashTable       *argPtrHashTbl;
    2.56     HashTable       *commHashTbl;
    2.57 +   HashTable       *criticalHashTbl;
    2.58     int32            numLiveExtraTaskSlvs;
    2.59     int32            numLiveThreadSlvs;
    2.60     int32            nextCoreToGetNewSlv;
    2.61 @@ -225,7 +227,7 @@
    2.62                         //fix limit on num with dynArray
    2.63     VSsSingleton     fnSingletons[NUM_STRUCS_IN_SEM_ENV];
    2.64     VSsTrans         transactionStrucs[NUM_STRUCS_IN_SEM_ENV];
    2.65 -   VSsCritical      criticalSection[NUM_STRUCS_IN_SEM_ENV];
    2.66 +
    2.67  
    2.68     bool32          *coreIsDone;
    2.69     int32            numCoresDone;
    2.70 @@ -331,13 +333,13 @@
    2.71  
    2.72  //=======================
    2.73  void
    2.74 -VSs__submit_task( VSsTaskType *taskType, void *args);
    2.75 +VSs__submit_task( VSsTaskType *taskType, void *args, void* deps);
    2.76  
    2.77  int32 *
    2.78  VSs__create_taskID_of_size( int32 numInts);
    2.79  
    2.80  void
    2.81 -VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID);
    2.82 +VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, void* deps, int32 *taskID);
    2.83  
    2.84  void VSs__run_task(TopLevelFnPtr fnPtr, void *initData);
    2.85  
    2.86 @@ -352,10 +354,10 @@
    2.87  VSs__taskwait_on(void* ptr);
    2.88  
    2.89  void
    2.90 -VSs__start_critical(int32 name);
    2.91 +VSs__start_critical(void* name);
    2.92  
    2.93  void
    2.94 -VSs__end_critical(int32 name);
    2.95 +VSs__end_critical(void* name);
    2.96  
    2.97  int32 *
    2.98  VSs__give_self_taskID();
     3.1 --- a/VSs_PluginFns.c	Fri May 17 17:49:49 2013 +0200
     3.2 +++ b/VSs_PluginFns.c	Mon Jun 03 18:34:56 2013 +0200
     3.3 @@ -413,8 +413,9 @@
     3.4      newStub->slaveAssignedTo = NULL; //set later
     3.5      newStub->taskType = IS_A_THREAD;
     3.6      newStub->ptrEntries = NULL;
     3.7 -    newStub->argsMask = NULL;
     3.8 +    newStub->depsMask = NULL;
     3.9      newStub->args = initData;
    3.10 +    newStub->depsAddrs = NULL;
    3.11      newStub->numLiveChildTasks = 0;
    3.12      newStub->numLiveChildThreads = 0;
    3.13      newStub->parentTaskStub = NULL;
     4.1 --- a/VSs_Request_Handlers.c	Fri May 17 17:49:49 2013 +0200
     4.2 +++ b/VSs_Request_Handlers.c	Mon Jun 03 18:34:56 2013 +0200
     4.3 @@ -98,16 +98,17 @@
     4.4   * to new space
     4.5   */
     4.6  VSsTaskStub *
     4.7 -create_task_stub(VSsTaskType *taskType, void **args) {
     4.8 +create_task_stub(VSsTaskType *taskType, void** deps, void **args) {
     4.9      void **newArgs;
    4.10      VSsTaskStub* newStub = VMS_int__malloc(sizeof (VSsTaskStub) + taskType->sizeOfArgs);
    4.11 -    newStub->numBlockingProp = taskType->numCtldArgs;
    4.12 +    newStub->numBlockingProp = taskType->numDeps;
    4.13      newStub->slaveAssignedTo = NULL;
    4.14      newStub->taskType = taskType;
    4.15      newStub->ptrEntries =
    4.16 -            VMS_int__malloc(taskType->numCtldArgs * sizeof (VSsPointerEntry *));
    4.17 +            VMS_int__malloc(taskType->numDeps * sizeof (VSsPointerEntry *));
    4.18      newArgs = (void **) ((uint8 *) newStub + sizeof (VSsTaskStub));
    4.19      newStub->args = newArgs;
    4.20 +    newStub->depsAddrs = deps;
    4.21      newStub->numLiveChildTasks = 0;
    4.22      newStub->numLiveChildThreads = 0;
    4.23      newStub->isWaitingForChildTasksToEnd = FALSE;
    4.24 @@ -115,8 +116,8 @@
    4.25      newStub->isEnded = FALSE;
    4.26      newStub->taskID = NULL;
    4.27      newStub->parentTaskStub = NULL;
    4.28 -    newStub->argsMask = VMS_int__malloc(sizeof(int) * taskType->numCtldArgs);
    4.29 -    memset(newStub->argsMask, 0, sizeof(int) * taskType->numCtldArgs);
    4.30 +    newStub->depsMask = VMS_int__malloc(sizeof(int) * taskType->numDeps);
    4.31 +    memset(newStub->depsMask, 0, sizeof(int) * taskType->numDeps);
    4.32      //Copy the arg-pointers.. can be more arguments than just the ones 
    4.33      // that StarSs uses to control ordering of task execution.
    4.34      memcpy(newArgs, args, taskType->sizeOfArgs);
    4.35 @@ -140,39 +141,39 @@
    4.36      //check for identical pointers in args -- mask all but one copy
    4.37      //if one of pointers is writer, non-masked arg must be writer
    4.38  int mask_duplicates(VSsTaskStub *taskStub){
    4.39 -    int argNum, i;
    4.40 -    int numUniqueArgs = 0;
    4.41 +    int depNum, i;
    4.42 +    int numUniqueDeps = 0;
    4.43      VSsTaskType* taskType = taskStub->taskType;
    4.44 -    void **args = taskStub->args;
    4.45 +    void **deps = taskStub->depsAddrs;
    4.46  
    4.47 -    for(argNum = 0; argNum < taskType->numCtldArgs; argNum++){
    4.48 +    for(depNum = 0; depNum < taskType->numDeps; depNum++){
    4.49          //if already masked, don't need to check again
    4.50 -        if(taskStub->argsMask[argNum]) continue; 
    4.51 +        if(taskStub->depsMask[depNum]) continue; 
    4.52          
    4.53 -        int unmasked = argNum;
    4.54 -        for(i=argNum+1; i<taskType->numCtldArgs; i++){
    4.55 -            if(args[argNum] == args[i]){
    4.56 -                if(taskType->argTypes[i] == WRITER){
    4.57 -                    taskStub->argsMask[unmasked] = TRUE;
    4.58 +        int unmasked = depNum;
    4.59 +        for(i=depNum+1; i<taskType->numDeps; i++){
    4.60 +            if(deps[depNum] == deps[i]){
    4.61 +                if(taskType->depsTypes[i] == WRITER){
    4.62 +                    taskStub->depsMask[unmasked] = TRUE;
    4.63                      unmasked = i;
    4.64                  } else {
    4.65 -                    taskStub->argsMask[i] = TRUE;
    4.66 +                    taskStub->depsMask[i] = TRUE;
    4.67                  }
    4.68              }
    4.69          }
    4.70      }
    4.71      
    4.72 -    for(i=0; i<taskType->numCtldArgs; i++){
    4.73 -        if(!taskStub->argsMask[i]) numUniqueArgs++;
    4.74 +    for(i=0; i<taskType->numDeps; i++){
    4.75 +        if(!taskStub->depsMask[i]) numUniqueDeps++;
    4.76      }
    4.77 -    return numUniqueArgs;
    4.78 +    return numUniqueDeps;
    4.79  }
    4.80  
    4.81  void do_submit(VSsSemReq *semReq, VSsSemEnv *semEnv){
    4.82      uint32 key[5];
    4.83      HashEntry *rawHashEntry; //has char *, but use with uint32 *
    4.84      VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer
    4.85 -    void **args;
    4.86 +    void **depsAddrs;
    4.87      VSsTaskStub *taskStub;
    4.88      VSsTaskType *taskType;
    4.89      VSsTaskStubCarrier *taskCarrier;
    4.90 @@ -180,7 +181,7 @@
    4.91      HashTable *
    4.92              argPtrHashTbl = semEnv->argPtrHashTbl;
    4.93      
    4.94 -    int32 argNum;
    4.95 +    int32 depNum;
    4.96      
    4.97      if(!semReq) {
    4.98          DEBUG__printf(dbgRqstHdlr,"***submitted Req is null***\n")
    4.99 @@ -195,9 +196,9 @@
   4.100       * inputs from the sequential portion. Note that all controlled arguments
   4.101       * are pointers, and marked as controlled in the application code).
   4.102       */
   4.103 -    args = semReq->args;
   4.104 +    depsAddrs = semReq->deps;
   4.105      taskType = semReq->taskType;
   4.106 -    taskStub = create_task_stub(taskType, args); //copies arg ptrs
   4.107 +    taskStub = create_task_stub(taskType, depsAddrs, semReq->args); //copies arg ptrs
   4.108      //check for identical pointers in args -- mask all but one copy
   4.109      //if one of pointers is writer, non-masked arg must be writer
   4.110      int numUniqueArgs = mask_duplicates(taskStub);
   4.111 @@ -225,12 +226,12 @@
   4.112       * looking up the hash entry.  (If none, create one).
   4.113       */
   4.114  
   4.115 -    for (argNum = 0; argNum < taskType->numCtldArgs; argNum++) {
   4.116 +    for (depNum = 0; depNum < taskType->numDeps; depNum++) {
   4.117          //only process unmasked args
   4.118 -        if(taskStub->argsMask[argNum]) continue;
   4.119 +        if(taskStub->depsMask[depNum]) continue;
   4.120          
   4.121          key[0] = 4; //two 32b values in key
   4.122 -        *((uint64*) & key[1]) = (uint64) args[argNum]; //write 64b into two 32b
   4.123 +        *((uint64*) & key[1]) = (uint64) depsAddrs[depNum]; //write 64b into two 32b
   4.124          *((uint64*) & key[3]) = (uint64) taskStub->parentTaskStub ;
   4.125          
   4.126          /*If the hash entry was chained, put it at the
   4.127 @@ -247,12 +248,12 @@
   4.128                  rawHashEntry = addValueIntoTable32(key, ptrEntry, argPtrHashTbl);
   4.129              }
   4.130          }
   4.131 -        taskStub->ptrEntries[argNum] = ptrEntry;
   4.132 +        taskStub->ptrEntries[depNum] = ptrEntry;
   4.133  
   4.134          /*Have the hash entry.
   4.135           *If the arg is a reader and the entry does not have an enabled
   4.136           * non-finished writer, and the queue is empty. */
   4.137 -        if (taskType->argTypes[argNum] == READER) {
   4.138 +        if (taskType->depsTypes[depNum] == READER) {
   4.139              if (!ptrEntry->hasEnabledNonFinishedWriter &&
   4.140                      isEmptyPrivQ(ptrEntry->waitersQ)) { /*The reader is free.  So, decrement the blocking-propendent
   4.141               * count in the task-stub. If the count is zero, then put the
   4.142 @@ -268,7 +269,7 @@
   4.143              } else { /*Otherwise, the reader is put into the hash-entry's Q of
   4.144               * waiters*/
   4.145                  DEBUG__printf_w_task(dbgSS, taskStub, "getting in line for ptrEntry %p (read)", ptrEntry);
   4.146 -                taskCarrier = create_task_carrier(taskStub, argNum, READER);
   4.147 +                taskCarrier = create_task_carrier(taskStub, depNum, READER);
   4.148                  writePrivQ(taskCarrier, ptrEntry->waitersQ);
   4.149              }
   4.150          } else //arg is a writer
   4.151 @@ -289,7 +290,7 @@
   4.152                  ptrEntry->hasEnabledNonFinishedWriter = TRUE;
   4.153              } else {/*Otherwise, put the writer into the entry's Q of waiters.*/
   4.154                  DEBUG__printf_w_task(dbgSS,taskStub,"getting in line for ptrEntry %p (write)",ptrEntry);
   4.155 -                taskCarrier = create_task_carrier(taskStub, argNum, WRITER);
   4.156 +                taskCarrier = create_task_carrier(taskStub, depNum, WRITER);
   4.157                  writePrivQ(taskCarrier, ptrEntry->waitersQ);
   4.158              }
   4.159          }
   4.160 @@ -484,7 +485,7 @@
   4.161  void
   4.162  handleEndTask(VSsSemReq *semReq, VSsSemEnv *semEnv) {
   4.163      VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer
   4.164 -    void **args;
   4.165 +    void **depsAddrs;
   4.166      VSsSemData *endingSlvSemData;
   4.167      VSsTaskStub *endingTaskStub, *waitingTaskStub, *parent;
   4.168      VSsTaskType *endingTaskType;
   4.169 @@ -495,7 +496,7 @@
   4.170      
   4.171      endingSlvSemData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.172      endingTaskStub = endingSlvSemData->taskStub;
   4.173 -    args = endingTaskStub->args;
   4.174 +    depsAddrs = endingTaskStub->depsAddrs;
   4.175      endingTaskType = endingTaskStub->taskType;
   4.176      ptrEntries = endingTaskStub->ptrEntries; //saved in stub when create
   4.177  
   4.178 @@ -534,15 +535,15 @@
   4.179      /*The task's controlled arguments are processed one by one.
   4.180       *Processing an argument means getting arg-pointer's entry.
   4.181       */
   4.182 -    int32 argNum;
   4.183 -    for (argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++) {
   4.184 +    int32 depNum;
   4.185 +    for (depNum = 0; depNum < endingTaskType->numDeps; depNum++) {
   4.186          //only process unmasked args
   4.187 -        if(endingTaskStub->argsMask[argNum]) continue;
   4.188 +        if(endingTaskStub->depsMask[depNum]) continue;
   4.189          
   4.190  
   4.191 -        ptrEntry = ptrEntries[argNum];
   4.192 +        ptrEntry = ptrEntries[depNum];
   4.193          /*check if the ending task was reader of this arg*/
   4.194 -        if (endingTaskType->argTypes[argNum] == READER) { /*then decrement the enabled and non-finished reader-count in
   4.195 +        if (endingTaskType->depsTypes[depNum] == READER) { /*then decrement the enabled and non-finished reader-count in
   4.196            * the hash-entry. */
   4.197              ptrEntry->numEnabledNonDoneReaders -= 1;
   4.198              DEBUG__printf(dbgSS,"Releasing read on ptrEntry %p",ptrEntry)
   4.199 @@ -737,8 +738,8 @@
   4.200      {
   4.201          VMS_PI__free(stubToFree->ptrEntries);
   4.202      }
   4.203 -    if (stubToFree->argsMask != NULL) {
   4.204 -        VMS_PI__free(stubToFree->argsMask);
   4.205 +    if (stubToFree->depsMask != NULL) {
   4.206 +        VMS_PI__free(stubToFree->depsMask);
   4.207      }
   4.208      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.209          VMS_PI__free(stubToFree->taskID);
   4.210 @@ -1216,9 +1217,23 @@
   4.211      }
   4.212  }
   4.213  
   4.214 +VSsCritical* create_critical_section(){
   4.215 +    VSsCritical* criticalSection = (VSsCritical*) malloc(sizeof(VSsCritical));
   4.216 +    
   4.217 +    criticalSection->isOccupied = FALSE;
   4.218 +    criticalSection->previous.vp = 0;
   4.219 +    criticalSection->previous.task = 0;
   4.220 +    criticalSection->waitQ = makeVMSQ();
   4.221 +    
   4.222 +    return criticalSection;
   4.223 +}
   4.224 +
   4.225  void handleCriticalStart(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) {
   4.226      VSsSemData* semData;
   4.227 -    int32 criticalID;
   4.228 +    void* criticalID;
   4.229 +    VSsCritical* criticalSection;
   4.230 +    HashEntry *rawHashEntry; //has char *, but use with uint32 *
   4.231 +    uint32 key[3];
   4.232      DEBUG__printf1(dbgRqstHdlr, "CriticalStart request from processor %d",
   4.233              requestingSlv->slaveID);
   4.234  
   4.235 @@ -1227,18 +1242,40 @@
   4.236      semData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.237  
   4.238      criticalID = semReq->criticalID;
   4.239 -    if (!semEnv->criticalSection[criticalID].isOccupied) {
   4.240 -        semEnv->criticalSection[criticalID].isOccupied = TRUE;
   4.241 +     
   4.242 +    key[0] = 2; //two 32b values in key
   4.243 +        *((uint64*) & key[1]) = (uint64) criticalID; //write 64b into two 32b
   4.244 +        
   4.245 +        /*If the hash entry was chained, put it at the
   4.246 +         * start of the chain.  (Means no-longer-used pointers accumulate
   4.247 +         * at end of chain, decide garbage collection later) */
   4.248 +        rawHashEntry = getEntryFromTable32(key, semEnv->criticalHashTbl);
   4.249 +        if (rawHashEntry == NULL) { //adding a value auto-creates the hash-entry
   4.250 +            criticalSection = create_critical_section();
   4.251 +            rawHashEntry = addValueIntoTable32(key, criticalSection, semEnv->criticalHashTbl);
   4.252 +        } else {
   4.253 +            criticalSection = (VSsCritical *) rawHashEntry->content;
   4.254 +            if (criticalSection == NULL) {
   4.255 +                criticalSection = create_critical_section();
   4.256 +                rawHashEntry = addValueIntoTable32(key, criticalSection, semEnv->criticalHashTbl);
   4.257 +            }
   4.258 +        }
   4.259 +     
   4.260 +    if (criticalSection->isOccupied) {
   4.261 +        criticalSection->isOccupied = TRUE;
   4.262          resume_slaveVP(requestingSlv, semEnv);
   4.263      } else {
   4.264 -        writePrivQ(requestingSlv, semEnv->criticalSection[criticalID].waitQ);
   4.265 +        writePrivQ(requestingSlv, criticalSection->waitQ);
   4.266      }
   4.267  }
   4.268  
   4.269  void handleCriticalEnd(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv){
   4.270      VSsSemData* semData;
   4.271      SlaveVP *waitingSlv;
   4.272 -    int32 criticalID;
   4.273 +    void* criticalID;
   4.274 +    VSsCritical* criticalSection;
   4.275 +    HashEntry *rawHashEntry; //has char *, but use with uint32 *
   4.276 +    uint32 key[3];
   4.277      DEBUG__printf1(dbgRqstHdlr, "CriticalEnd request from processor %d",
   4.278              requestingSlv->slaveID);
   4.279      
   4.280 @@ -1247,10 +1284,32 @@
   4.281      semData = (VSsSemData *) semReq->callingSlv->semanticData;
   4.282      
   4.283      criticalID = semReq->criticalID;
   4.284 -    semEnv->criticalSection[criticalID].isOccupied = FALSE;
   4.285 -    waitingSlv = readPrivQ(semEnv->criticalSection[criticalID].waitQ);
   4.286 +    
   4.287 +         
   4.288 +    key[0] = 2; //two 32b values in key
   4.289 +        *((uint64*) & key[1]) = (uint64) criticalID; //write 64b into two 32b
   4.290 +        
   4.291 +        /*If the hash entry was chained, put it at the
   4.292 +         * start of the chain.  (Means no-longer-used pointers accumulate
   4.293 +         * at end of chain, decide garbage collection later) */
   4.294 +        rawHashEntry = getEntryFromTable32(key, semEnv->criticalHashTbl);
   4.295 +        if (rawHashEntry == NULL) { //adding a value auto-creates the hash-entry
   4.296 +            criticalSection = create_critical_section();
   4.297 +            rawHashEntry = addValueIntoTable32(key, criticalSection, semEnv->criticalHashTbl);
   4.298 +        } else {
   4.299 +            criticalSection = (VSsCritical *) rawHashEntry->content;
   4.300 +            if (criticalSection == NULL) {
   4.301 +                criticalSection = create_critical_section();
   4.302 +                rawHashEntry = addValueIntoTable32(key, criticalSection, semEnv->criticalHashTbl);
   4.303 +            }
   4.304 +        }
   4.305 +     
   4.306 +    
   4.307 +    
   4.308 +    criticalSection->isOccupied = FALSE;
   4.309 +    waitingSlv = readPrivQ(criticalSection->waitQ);
   4.310      if(waitingSlv!=NULL){
   4.311 -        semEnv->criticalSection[criticalID].isOccupied = TRUE;
   4.312 +        criticalSection->isOccupied = TRUE;
   4.313          resume_slaveVP(waitingSlv, semEnv);
   4.314      }
   4.315      resume_slaveVP(requestingSlv, semEnv);