Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
changeset 12:f56e3beac86b dev_expl_VP_and_DKU
wasn't a double free, some tasks have 0 args -> ptrEntries=NULL
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Mon, 20 Aug 2012 13:42:19 +0200 |
| parents | ed268fc7376a b13fbd445e0a |
| children | 2bf83f932705 |
| files | VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c |
| diffstat | 4 files changed, 57 insertions(+), 54 deletions(-) [+] |
line diff
1.1 --- a/VSs.c Wed Aug 15 17:05:02 2012 +0200 1.2 +++ b/VSs.c Mon Aug 20 13:42:19 2012 +0200 1.3 @@ -185,6 +185,7 @@ 1.4 VSs__init_Helper() 1.5 { VSsSemEnv *semanticEnv; 1.6 int32 i, coreNum, slotNum; 1.7 + VSsSemData *semData; 1.8 1.9 //Hook up the semantic layer's plug-ins to the Master virt procr 1.10 _VMSMasterEnv->requestHandler = &VSs__Request_Handler; 1.11 @@ -206,22 +207,26 @@ 1.12 semanticEnv->coreIsDone = VMS_int__malloc( NUM_CORES * sizeof( bool32 ) ); 1.13 //For each animation slot, there is an idle slave, and an initial 1.14 // slave assigned as the current-task-slave. Create them here. 1.15 - SlaveVP *idleSlv, *currTaskSlv; 1.16 + SlaveVP *idleSlv, *slotTaskSlv; 1.17 for( coreNum = 0; coreNum < NUM_CORES; coreNum++ ) 1.18 { semanticEnv->coreIsDone[coreNum] = FALSE; //use during shutdown 1.19 1.20 for( slotNum = 0; slotNum < NUM_ANIM_SLOTS; ++slotNum ) 1.21 - { idleSlv = VMS_int__create_slaveVP(&idle_fn,NULL); 1.22 + { idleSlv = VSs__create_slave_helper( &idle_fn, NULL, semanticEnv, 0); 1.23 idleSlv->coreAnimatedBy = coreNum; 1.24 idleSlv->animSlotAssignedTo = 1.25 _VMSMasterEnv->allAnimSlots[coreNum][slotNum]; 1.26 semanticEnv->idleSlv[coreNum][slotNum] = idleSlv; 1.27 1.28 - currTaskSlv = VMS_int__create_slaveVP( &idle_fn, NULL ); 1.29 - currTaskSlv->coreAnimatedBy = coreNum; 1.30 - currTaskSlv->animSlotAssignedTo = 1.31 + slotTaskSlv = VSs__create_slave_helper( &idle_fn, NULL, semanticEnv, 0); 1.32 + slotTaskSlv->coreAnimatedBy = coreNum; 1.33 + slotTaskSlv->animSlotAssignedTo = 1.34 _VMSMasterEnv->allAnimSlots[coreNum][slotNum]; 1.35 - semanticEnv->currTaskSlvs[coreNum][slotNum] = currTaskSlv; 1.36 + 1.37 + semData = slotTaskSlv->semanticData; 1.38 + semData->needsTaskAssigned = TRUE; 1.39 + semData->slaveType = SlotTaskSlv; 1.40 + semanticEnv->slotTaskSlvs[coreNum][slotNum] = slotTaskSlv; 1.41 } 1.42 } 1.43 1.44 @@ -419,27 +424,22 @@ 1.45 return creatingThd->dataRetFromReq; 1.46 } 1.47 1.48 -/*This is always the last thing done in the code animated by a thread. 1.49 +/*This is always the last thing done in the code animated by a thread VP. 1.50 * Normally, this would be the last line of the thread's top level function. 1.51 * But, if the thread exits from any point, it has to do so by calling 1.52 * this. 1.53 - * 1.54 - *This must update the count of active sub-tasks (sub-threads) of parents, 1.55 - * and the semantic data and task stub must stay. 1.56 + * 1.57 + *It simply sends a dissipate request, which handles all the state cleanup. 1.58 */ 1.59 void 1.60 VSs__end_thread( SlaveVP *thdToEnd ) 1.61 { VSsSemData *semData; 1.62 - 1.63 - 1.64 - //Update the count of live sub-tasks in parent. If parent was a 1.65 - // thread and has already ended, then if this was the last sub-task, 1.66 - // free the semantic data and task stub of the parent. 1.67 1.68 VMS_WL__send_dissipate_req( thdToEnd ); 1.69 } 1.70 1.71 1.72 + 1.73 //=========================================================================== 1.74 1.75
2.1 --- a/VSs.h Wed Aug 15 17:05:02 2012 +0200 2.2 +++ b/VSs.h Mon Aug 20 13:42:19 2012 +0200 2.3 @@ -71,7 +71,7 @@ 2.4 VSsTaskType *taskType; 2.5 int32 *taskID; 2.6 int32 numBlockingProp; 2.7 - SlaveVP *slaveAssignedTo; 2.8 + SlaveVP *slaveAssignedTo; //only valid before end task (thread) 2.9 VSsPointerEntry **ptrEntries; 2.10 void* parentTaskStub; 2.11 int32 numLiveChildTasks; 2.12 @@ -185,7 +185,7 @@ 2.13 PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) 2.14 PrivQueueStruc *freeExtraTaskSlvQ; //Shared 2.15 PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) 2.16 - SlaveVP *currTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; 2.17 + SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; 2.18 HashTable *argPtrHashTbl; 2.19 HashTable *commHashTbl; 2.20 int32 numLiveExtraTaskSlvs; 2.21 @@ -229,9 +229,9 @@ 2.22 //TransListElem 2.23 2.24 enum VSsSlvType 2.25 - { extraTaskSlv = 1, 2.26 - slotTaskSlv, 2.27 - threadSlv 2.28 + { ExtraTaskSlv = 1, 2.29 + SlotTaskSlv, 2.30 + ThreadSlv 2.31 }; 2.32 2.33 typedef struct
3.1 --- a/VSs_PluginFns.c Wed Aug 15 17:05:02 2012 +0200 3.2 +++ b/VSs_PluginFns.c Mon Aug 20 13:42:19 2012 +0200 3.3 @@ -62,9 +62,9 @@ 3.4 3.5 semEnv = (VSsSemEnv *)_semEnv; 3.6 3.7 - //Speculatively set the return slave to the current taskSlave 3.8 + //Speculatively set the return slave to the slot taskSlave 3.9 //TODO: false sharing ? Always read.. 3.10 - returnSlv = semEnv->currTaskSlvs[coreNum][slotNum]; 3.11 + returnSlv = semEnv->slotTaskSlvs[coreNum][slotNum]; 3.12 3.13 semData = (VSsSemData *)returnSlv->semanticData; 3.14 3.15 @@ -276,21 +276,22 @@ 3.16 requestingSlv->slaveID) 3.17 semData = (VSsSemData *)requestingSlv->semanticData; 3.18 3.19 - if( semData->slaveType == extraTaskSlv ) 3.20 + if( semData->slaveType == ExtraTaskSlv ) 3.21 { semEnv->numLiveExtraTaskSlvs -= 1; //for detecting shutdown condition 3.22 //Has no task assigned, so no parents and no children, so free self 3.23 goto FreeSlaveStateAndReturn; 3.24 } 3.25 3.26 - if( semData->slaveType == slotTaskSlv ) 3.27 + if( semData->slaveType == SlotTaskSlv ) 3.28 { //should never call dissipate on a slot assigned slave 3.29 VMS_PI__throw_exception( "dissipate a slot-assigned slave", requestingSlv, NULL ); 3.30 } 3.31 3.32 - //if make it to here, then is a thread slave 3.33 + //if make it to here, then is a thread slave ending 3.34 semEnv->numLiveThreadSlvs -= 1; //for detecting shutdown condition 3.35 ownTaskStub = semData->taskStub; 3.36 parentTaskStub = ownTaskStub->parentTaskStub; 3.37 + parentTaskStub->numLiveChildThreads -= 1; //not freed, even if ended 3.38 3.39 //if all children ended, then free this task's stub 3.40 // else, keep stub around, and last child will free it (below) 3.41 @@ -300,26 +301,24 @@ 3.42 else 3.43 ownTaskStub->isEnded = TRUE; //for children to see when they end 3.44 3.45 - //check if this is last child of ended parent 3.46 - parentTaskStub->numLiveChildThreads -= 1; //parent stub cannot be NULL 3.47 + //Now, check on parents waiting on child threads to end 3.48 + if( parentTaskStub->isWaitingForChildThreadsToEnd && 3.49 + parentTaskStub->numLiveChildThreads == 0 ) 3.50 + { parentTaskStub->isWaitingForChildThreadsToEnd = FALSE; 3.51 + if( parentTaskStub->isWaitingForChildTasksToEnd ) 3.52 + return; //still waiting on tasks (should be impossible) 3.53 + else //parent free to resume 3.54 + resume_slaveVP( parentTaskStub->slaveAssignedTo, semEnv ); 3.55 + } 3.56 + 3.57 + //check if this is last child of ended parent (note, not possible to 3.58 + // have more than one level of ancestor waiting to be freed) 3.59 if( parentTaskStub->isEnded ) 3.60 { if( parentTaskStub->numLiveChildTasks == 0 && 3.61 parentTaskStub->numLiveChildThreads == 0 ) 3.62 free_task_stub( parentTaskStub ); //just stub, semData already freed 3.63 } 3.64 - 3.65 - //Now, check on waiting parents -- could be waiting on just tasks or 3.66 - // just threads or both. Handle each case. 3.67 - if( parentTaskStub->isWaitingForChildThreadsToEnd ) 3.68 - { if( parentTaskStub->numLiveChildThreads == 0 ) 3.69 - { parentTaskStub->isWaitingForChildThreadsToEnd = FALSE; 3.70 - if( parentTaskStub->isWaitingForChildTasksToEnd ) 3.71 - return; //still waiting on tasks, nothing to do 3.72 - else //parent free to resume 3.73 - resume_slaveVP( parentTaskStub->slaveAssignedTo, semEnv ); 3.74 - } 3.75 - } 3.76 - 3.77 + 3.78 //Free the semData and requesting slave's base state for all cases 3.79 FreeSlaveStateAndReturn: 3.80 VMS_PI__free( semData ); 3.81 @@ -327,6 +326,8 @@ 3.82 return; 3.83 } 3.84 3.85 + 3.86 + 3.87 /*Re-use this in the entry-point fn 3.88 */ 3.89 inline SlaveVP * 3.90 @@ -345,6 +346,7 @@ 3.91 semData->highestTransEntered = -1; 3.92 semData->lastTransEntered = NULL; 3.93 semData->needsTaskAssigned = TRUE; 3.94 + semData->taskStub =NULL; 3.95 3.96 newSlv->semanticData = semData; 3.97 3.98 @@ -440,7 +442,7 @@ 3.99 semData->needsTaskAssigned = FALSE; //thread has a permanent task 3.100 semData->taskStub = create_thread_task_stub( semReq->initData ); 3.101 semData->taskStub->parentTaskStub = parentSemData->taskStub; 3.102 - semData->slaveType = threadSlv; //this hdlr only creates thread slvs 3.103 + semData->slaveType = ThreadSlv; //this hdlr only creates thread slvs 3.104 3.105 DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", 3.106 requestingSlv->slaveID, newSlv->slaveID)
4.1 --- a/VSs_Request_Handlers.c Wed Aug 15 17:05:02 2012 +0200 4.2 +++ b/VSs_Request_Handlers.c Mon Aug 20 13:42:19 2012 +0200 4.3 @@ -85,8 +85,7 @@ 4.4 inline VSsTaskStub * 4.5 create_task_stub( VSsTaskType *taskType, void **args ) 4.6 { void **newArgs; 4.7 - VSsTaskStub * 4.8 - newStub = VMS_int__malloc( sizeof(VSsTaskStub) + taskType->sizeOfArgs ); 4.9 + VSsTaskStub* newStub = VMS_int__malloc( sizeof(VSsTaskStub) + taskType->sizeOfArgs ); 4.10 newStub->numBlockingProp = taskType->numCtldArgs; 4.11 newStub->slaveAssignedTo = NULL; 4.12 newStub->taskType = taskType; 4.13 @@ -514,7 +513,7 @@ 4.14 endingSlvSemData->needsTaskAssigned = TRUE; 4.15 4.16 //Check if the slave is an extra task slave, and put into free Q 4.17 - if( endingSlvSemData->slaveType == extraTaskSlv ) 4.18 + if( endingSlvSemData->slaveType == ExtraTaskSlv ) 4.19 { writePrivQ( semReq->callingSlv, semEnv->freeExtraTaskSlvQ ); 4.20 } 4.21 4.22 @@ -525,8 +524,11 @@ 4.23 4.24 inline void 4.25 free_task_stub( VSsTaskStub *stubToFree ) 4.26 - { VMS_PI__free( stubToFree->ptrEntries ); 4.27 - VMS_PI__free( stubToFree ); 4.28 +{ 4.29 + if(stubToFree->ptrEntries){ 4.30 + VMS_PI__free( stubToFree->ptrEntries ); 4.31 + } 4.32 + VMS_PI__free( stubToFree ); 4.33 } 4.34 4.35 //========================== Task Comm handlers =========================== 4.36 @@ -570,7 +572,7 @@ 4.37 // it with a new slave (causes it to become an extraTaskSlv) 4.38 //Once the waiting slave resumes and gets to task_end, the task_end 4.39 // puts the slave into the freeExtraTaskSlvQ 4.40 - replaceWithNewSlotSlv( receiverSlv, semEnv ); 4.41 + replaceWithNewSlotSlv( senderSlv, semEnv ); 4.42 return; 4.43 } 4.44 4.45 @@ -661,7 +663,6 @@ 4.46 4.47 receiverID = semReq->receiverID; //For "send", know both send & recv procrs 4.48 senderID = semReq->senderID; 4.49 - //receiverSlv = semReq->receiverSlv; 4.50 senderSlv = semReq->senderSlv; 4.51 4.52 receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself 4.53 @@ -677,7 +678,7 @@ 4.54 // it with a new slave (causes it to become an extraTaskSlv) 4.55 //Once the waiting slave resumes and gets to task_end, the task_end 4.56 // puts the slave into the freeExtraTaskSlvQ 4.57 - replaceWithNewSlotSlv( receiverSlv, semEnv ); 4.58 + replaceWithNewSlotSlv( senderSlv, semEnv ); 4.59 return; 4.60 } 4.61 4.62 @@ -899,13 +900,13 @@ 4.63 //get a new slave to be the slot slave 4.64 newSlotSlv = readPrivQ( semEnv->freeExtraTaskSlvQ ); 4.65 if( newSlotSlv == NULL ) 4.66 - { newSlotSlv = VMS_int__create_slaveVP( &idle_fn, NULL ); 4.67 + { newSlotSlv = VSs__create_slave_helper( &idle_fn, NULL, semEnv, 0); 4.68 } 4.69 4.70 //set slave values to make it the slot slave 4.71 semData = newSlotSlv->semanticData; 4.72 semData->taskStub = NULL; 4.73 - semData->slaveType = slotTaskSlv; 4.74 + semData->slaveType = SlotTaskSlv; 4.75 semData->needsTaskAssigned = TRUE; 4.76 newSlotSlv->animSlotAssignedTo = requestingSlv->animSlotAssignedTo; 4.77 newSlotSlv->coreAnimatedBy = requestingSlv->coreAnimatedBy; 4.78 @@ -913,12 +914,12 @@ 4.79 //put it into the slot slave matrix 4.80 int32 slotNum = requestingSlv->animSlotAssignedTo->slotIdx; 4.81 int32 coreNum = requestingSlv->coreAnimatedBy; 4.82 - semEnv->currTaskSlvs[coreNum][slotNum] = newSlotSlv; 4.83 + semEnv->slotTaskSlvs[coreNum][slotNum] = newSlotSlv; 4.84 4.85 //Fix up requester, to be an extra slave now (but not a free one) 4.86 // because it's not free, doesn't go into freeExtraTaskSlvQ 4.87 semData = requestingSlv->semanticData; 4.88 - semData->slaveType = extraTaskSlv; 4.89 + semData->slaveType = ExtraTaskSlv; 4.90 } 4.91 4.92 inline void 4.93 @@ -937,7 +938,7 @@ 4.94 } 4.95 else //have to wait, replace requester with new slot slv & mark waiting 4.96 { 4.97 - if(semData->slaveType == slotTaskSlv || semData->slaveType == extraTaskSlv){ 4.98 + if(semData->slaveType == SlotTaskSlv || semData->slaveType == ExtraTaskSlv){ 4.99 replaceWithNewSlotSlv( requestingSlv, semEnv ); 4.100 } 4.101
