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