Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
changeset 10:b13fbd445e0a dev_expl_VP_and_DKU
Compiles and some bugs corrected.. still does double free of taskStub
author | Sean Halle <seanhalle@yahoo.com> |
---|---|
date | Fri, 17 Aug 2012 17:12:50 -0700 |
parents | 832bc715fbf2 |
children | f56e3beac86b |
files | VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c |
diffstat | 4 files changed, 50 insertions(+), 56 deletions(-) [+] |
line diff
1.1 --- a/VSs.c Mon Aug 06 01:14:41 2012 -0700 1.2 +++ b/VSs.c Fri Aug 17 17:12:50 2012 -0700 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,34 +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 - //check whether all sub-tasks have ended.. if not, don't free the 1.64 - // semantic data nor task stub of this thread. 1.65 - semData = (VSsSemData *)thdToEnd->semanticData; 1.66 - if( semData->taskStub->numLiveChildTasks != 0 ) 1.67 - { 1.68 - fix_me(); 1.69 - } 1.70 - 1.71 - //Update the count of live sub-tasks in parent. If parent was a 1.72 - // thread and has already ended, then if this was the last sub-task, 1.73 - // free the semantic data and task stub of the parent. 1.74 1.75 VMS_WL__send_dissipate_req( thdToEnd ); 1.76 } 1.77 1.78 1.79 + 1.80 //=========================================================================== 1.81 1.82
2.1 --- a/VSs.h Mon Aug 06 01:14:41 2012 -0700 2.2 +++ b/VSs.h Fri Aug 17 17:12:50 2012 -0700 2.3 @@ -71,8 +71,9 @@ 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 + 2.11 void* parentTasksStub; 2.12 int32 numLiveChildTasks; 2.13 int32 numLiveChildThreads; 2.14 @@ -185,7 +186,7 @@ 2.15 PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) 2.16 PrivQueueStruc *freeExtraTaskSlvQ; //Shared 2.17 PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) 2.18 - SlaveVP *currTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; 2.19 + SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; 2.20 HashTable *argPtrHashTbl; 2.21 HashTable *commHashTbl; 2.22 int32 numLiveExtraTaskSlvs; 2.23 @@ -229,9 +230,9 @@ 2.24 //TransListElem 2.25 2.26 enum VSsSlvType 2.27 - { extraTaskSlv = 1, 2.28 - slotTaskSlv, 2.29 - threadSlv 2.30 + { ExtraTaskSlv = 1, 2.31 + SlotTaskSlv, 2.32 + ThreadSlv 2.33 }; 2.34 2.35 typedef struct
3.1 --- a/VSs_PluginFns.c Mon Aug 06 01:14:41 2012 -0700 3.2 +++ b/VSs_PluginFns.c Fri Aug 17 17:12:50 2012 -0700 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->parentTasksStub; 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 @@ -440,7 +441,7 @@ 3.91 semData->needsTaskAssigned = FALSE; //thread has a permanent task 3.92 semData->taskStub = create_thread_task_stub( semReq->initData ); 3.93 semData->taskStub->parentTasksStub = parentSemData->taskStub; 3.94 - semData->slaveType = threadSlv; //this hdlr only creates thread slvs 3.95 + semData->slaveType = ThreadSlv; //this hdlr only creates thread slvs 3.96 3.97 DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", 3.98 requestingSlv->slaveID, newSlv->slaveID)
4.1 --- a/VSs_Request_Handlers.c Mon Aug 06 01:14:41 2012 -0700 4.2 +++ b/VSs_Request_Handlers.c Fri Aug 17 17:12:50 2012 -0700 4.3 @@ -514,7 +514,7 @@ 4.4 endingSlvSemData->needsTaskAssigned = TRUE; 4.5 4.6 //Check if the slave is an extra task slave, and put into free Q 4.7 - if( endingSlvSemData->slaveType == extraTaskSlv ) 4.8 + if( endingSlvSemData->slaveType == ExtraTaskSlv ) 4.9 { writePrivQ( semReq->callingSlv, semEnv->freeExtraTaskSlvQ ); 4.10 } 4.11 4.12 @@ -570,7 +570,7 @@ 4.13 // it with a new slave (causes it to become an extraTaskSlv) 4.14 //Once the waiting slave resumes and gets to task_end, the task_end 4.15 // puts the slave into the freeExtraTaskSlvQ 4.16 - replaceWithNewSlotSlv( receiverSlv, semEnv ); 4.17 + replaceWithNewSlotSlv( senderSlv, semEnv ); 4.18 return; 4.19 } 4.20 4.21 @@ -661,7 +661,6 @@ 4.22 4.23 receiverID = semReq->receiverID; //For "send", know both send & recv procrs 4.24 senderID = semReq->senderID; 4.25 - //receiverSlv = semReq->receiverSlv; 4.26 senderSlv = semReq->senderSlv; 4.27 4.28 receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself 4.29 @@ -677,7 +676,7 @@ 4.30 // it with a new slave (causes it to become an extraTaskSlv) 4.31 //Once the waiting slave resumes and gets to task_end, the task_end 4.32 // puts the slave into the freeExtraTaskSlvQ 4.33 - replaceWithNewSlotSlv( receiverSlv, semEnv ); 4.34 + replaceWithNewSlotSlv( senderSlv, semEnv ); 4.35 return; 4.36 } 4.37 4.38 @@ -899,13 +898,13 @@ 4.39 //get a new slave to be the slot slave 4.40 newSlotSlv = readPrivQ( semEnv->freeExtraTaskSlvQ ); 4.41 if( newSlotSlv == NULL ) 4.42 - { newSlotSlv = VMS_int__create_slaveVP( &idle_fn, NULL ); 4.43 + { newSlotSlv = VSs__create_slave_helper( &idle_fn, NULL, semEnv, 0); 4.44 } 4.45 4.46 //set slave values to make it the slot slave 4.47 semData = newSlotSlv->semanticData; 4.48 semData->taskStub = NULL; 4.49 - semData->slaveType = slotTaskSlv; 4.50 + semData->slaveType = SlotTaskSlv; 4.51 semData->needsTaskAssigned = TRUE; 4.52 newSlotSlv->animSlotAssignedTo = requestingSlv->animSlotAssignedTo; 4.53 newSlotSlv->coreAnimatedBy = requestingSlv->coreAnimatedBy; 4.54 @@ -913,12 +912,12 @@ 4.55 //put it into the slot slave matrix 4.56 int32 slotNum = requestingSlv->animSlotAssignedTo->slotIdx; 4.57 int32 coreNum = requestingSlv->coreAnimatedBy; 4.58 - semEnv->currTaskSlvs[coreNum][slotNum] = newSlotSlv; 4.59 + semEnv->slotTaskSlvs[coreNum][slotNum] = newSlotSlv; 4.60 4.61 //Fix up requester, to be an extra slave now (but not a free one) 4.62 // because it's not free, doesn't go into freeExtraTaskSlvQ 4.63 semData = requestingSlv->semanticData; 4.64 - semData->slaveType = extraTaskSlv; 4.65 + semData->slaveType = ExtraTaskSlv; 4.66 } 4.67 4.68 inline void