Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
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);