# HG changeset patch # User Sean Halle # Date 1345248770 25200 # Node ID b13fbd445e0aa3c0db97e2532979941c5ed1f17d # Parent 832bc715fbf26945a9b2de7f9dbf89e47508b870 Compiles and some bugs corrected.. still does double free of taskStub diff -r 832bc715fbf2 -r b13fbd445e0a VSs.c --- a/VSs.c Mon Aug 06 01:14:41 2012 -0700 +++ b/VSs.c Fri Aug 17 17:12:50 2012 -0700 @@ -185,6 +185,7 @@ VSs__init_Helper() { VSsSemEnv *semanticEnv; int32 i, coreNum, slotNum; + VSsSemData *semData; //Hook up the semantic layer's plug-ins to the Master virt procr _VMSMasterEnv->requestHandler = &VSs__Request_Handler; @@ -206,22 +207,26 @@ semanticEnv->coreIsDone = VMS_int__malloc( NUM_CORES * sizeof( bool32 ) ); //For each animation slot, there is an idle slave, and an initial // slave assigned as the current-task-slave. Create them here. - SlaveVP *idleSlv, *currTaskSlv; + SlaveVP *idleSlv, *slotTaskSlv; for( coreNum = 0; coreNum < NUM_CORES; coreNum++ ) { semanticEnv->coreIsDone[coreNum] = FALSE; //use during shutdown for( slotNum = 0; slotNum < NUM_ANIM_SLOTS; ++slotNum ) - { idleSlv = VMS_int__create_slaveVP(&idle_fn,NULL); + { idleSlv = VSs__create_slave_helper( &idle_fn, NULL, semanticEnv, 0); idleSlv->coreAnimatedBy = coreNum; idleSlv->animSlotAssignedTo = _VMSMasterEnv->allAnimSlots[coreNum][slotNum]; semanticEnv->idleSlv[coreNum][slotNum] = idleSlv; - currTaskSlv = VMS_int__create_slaveVP( &idle_fn, NULL ); - currTaskSlv->coreAnimatedBy = coreNum; - currTaskSlv->animSlotAssignedTo = + slotTaskSlv = VSs__create_slave_helper( &idle_fn, NULL, semanticEnv, 0); + slotTaskSlv->coreAnimatedBy = coreNum; + slotTaskSlv->animSlotAssignedTo = _VMSMasterEnv->allAnimSlots[coreNum][slotNum]; - semanticEnv->currTaskSlvs[coreNum][slotNum] = currTaskSlv; + + semData = slotTaskSlv->semanticData; + semData->needsTaskAssigned = TRUE; + semData->slaveType = SlotTaskSlv; + semanticEnv->slotTaskSlvs[coreNum][slotNum] = slotTaskSlv; } } @@ -419,34 +424,22 @@ return creatingThd->dataRetFromReq; } -/*This is always the last thing done in the code animated by a thread. +/*This is always the last thing done in the code animated by a thread VP. * Normally, this would be the last line of the thread's top level function. * But, if the thread exits from any point, it has to do so by calling * this. - * - *This must update the count of active sub-tasks (sub-threads) of parents, - * and the semantic data and task stub must stay. + * + *It simply sends a dissipate request, which handles all the state cleanup. */ void VSs__end_thread( SlaveVP *thdToEnd ) { VSsSemData *semData; - - //check whether all sub-tasks have ended.. if not, don't free the - // semantic data nor task stub of this thread. - semData = (VSsSemData *)thdToEnd->semanticData; - if( semData->taskStub->numLiveChildTasks != 0 ) - { - fix_me(); - } - - //Update the count of live sub-tasks in parent. If parent was a - // thread and has already ended, then if this was the last sub-task, - // free the semantic data and task stub of the parent. VMS_WL__send_dissipate_req( thdToEnd ); } + //=========================================================================== diff -r 832bc715fbf2 -r b13fbd445e0a VSs.h --- a/VSs.h Mon Aug 06 01:14:41 2012 -0700 +++ b/VSs.h Fri Aug 17 17:12:50 2012 -0700 @@ -71,8 +71,9 @@ VSsTaskType *taskType; int32 *taskID; int32 numBlockingProp; - SlaveVP *slaveAssignedTo; + SlaveVP *slaveAssignedTo; //only valid before end task (thread) VSsPointerEntry **ptrEntries; + void* parentTasksStub; int32 numLiveChildTasks; int32 numLiveChildThreads; @@ -185,7 +186,7 @@ PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) PrivQueueStruc *freeExtraTaskSlvQ; //Shared PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) - SlaveVP *currTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; + SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; HashTable *argPtrHashTbl; HashTable *commHashTbl; int32 numLiveExtraTaskSlvs; @@ -229,9 +230,9 @@ //TransListElem enum VSsSlvType - { extraTaskSlv = 1, - slotTaskSlv, - threadSlv + { ExtraTaskSlv = 1, + SlotTaskSlv, + ThreadSlv }; typedef struct diff -r 832bc715fbf2 -r b13fbd445e0a VSs_PluginFns.c --- a/VSs_PluginFns.c Mon Aug 06 01:14:41 2012 -0700 +++ b/VSs_PluginFns.c Fri Aug 17 17:12:50 2012 -0700 @@ -62,9 +62,9 @@ semEnv = (VSsSemEnv *)_semEnv; - //Speculatively set the return slave to the current taskSlave + //Speculatively set the return slave to the slot taskSlave //TODO: false sharing ? Always read.. - returnSlv = semEnv->currTaskSlvs[coreNum][slotNum]; + returnSlv = semEnv->slotTaskSlvs[coreNum][slotNum]; semData = (VSsSemData *)returnSlv->semanticData; @@ -276,21 +276,22 @@ requestingSlv->slaveID) semData = (VSsSemData *)requestingSlv->semanticData; - if( semData->slaveType == extraTaskSlv ) + if( semData->slaveType == ExtraTaskSlv ) { semEnv->numLiveExtraTaskSlvs -= 1; //for detecting shutdown condition //Has no task assigned, so no parents and no children, so free self goto FreeSlaveStateAndReturn; } - if( semData->slaveType == slotTaskSlv ) + if( semData->slaveType == SlotTaskSlv ) { //should never call dissipate on a slot assigned slave VMS_PI__throw_exception( "dissipate a slot-assigned slave", requestingSlv, NULL ); } - //if make it to here, then is a thread slave + //if make it to here, then is a thread slave ending semEnv->numLiveThreadSlvs -= 1; //for detecting shutdown condition ownTaskStub = semData->taskStub; parentTaskStub = ownTaskStub->parentTasksStub; + parentTaskStub->numLiveChildThreads -= 1; //not freed, even if ended //if all children ended, then free this task's stub // else, keep stub around, and last child will free it (below) @@ -300,26 +301,24 @@ else ownTaskStub->isEnded = TRUE; //for children to see when they end - //check if this is last child of ended parent - parentTaskStub->numLiveChildThreads -= 1; //parent stub cannot be NULL + //Now, check on parents waiting on child threads to end + if( parentTaskStub->isWaitingForChildThreadsToEnd && + parentTaskStub->numLiveChildThreads == 0 ) + { parentTaskStub->isWaitingForChildThreadsToEnd = FALSE; + if( parentTaskStub->isWaitingForChildTasksToEnd ) + return; //still waiting on tasks (should be impossible) + else //parent free to resume + resume_slaveVP( parentTaskStub->slaveAssignedTo, semEnv ); + } + + //check if this is last child of ended parent (note, not possible to + // have more than one level of ancestor waiting to be freed) if( parentTaskStub->isEnded ) { if( parentTaskStub->numLiveChildTasks == 0 && parentTaskStub->numLiveChildThreads == 0 ) free_task_stub( parentTaskStub ); //just stub, semData already freed } - - //Now, check on waiting parents -- could be waiting on just tasks or - // just threads or both. Handle each case. - if( parentTaskStub->isWaitingForChildThreadsToEnd ) - { if( parentTaskStub->numLiveChildThreads == 0 ) - { parentTaskStub->isWaitingForChildThreadsToEnd = FALSE; - if( parentTaskStub->isWaitingForChildTasksToEnd ) - return; //still waiting on tasks, nothing to do - else //parent free to resume - resume_slaveVP( parentTaskStub->slaveAssignedTo, semEnv ); - } - } - + //Free the semData and requesting slave's base state for all cases FreeSlaveStateAndReturn: VMS_PI__free( semData ); @@ -327,6 +326,8 @@ return; } + + /*Re-use this in the entry-point fn */ inline SlaveVP * @@ -440,7 +441,7 @@ semData->needsTaskAssigned = FALSE; //thread has a permanent task semData->taskStub = create_thread_task_stub( semReq->initData ); semData->taskStub->parentTasksStub = parentSemData->taskStub; - semData->slaveType = threadSlv; //this hdlr only creates thread slvs + semData->slaveType = ThreadSlv; //this hdlr only creates thread slvs DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", requestingSlv->slaveID, newSlv->slaveID) diff -r 832bc715fbf2 -r b13fbd445e0a VSs_Request_Handlers.c --- a/VSs_Request_Handlers.c Mon Aug 06 01:14:41 2012 -0700 +++ b/VSs_Request_Handlers.c Fri Aug 17 17:12:50 2012 -0700 @@ -514,7 +514,7 @@ endingSlvSemData->needsTaskAssigned = TRUE; //Check if the slave is an extra task slave, and put into free Q - if( endingSlvSemData->slaveType == extraTaskSlv ) + if( endingSlvSemData->slaveType == ExtraTaskSlv ) { writePrivQ( semReq->callingSlv, semEnv->freeExtraTaskSlvQ ); } @@ -570,7 +570,7 @@ // it with a new slave (causes it to become an extraTaskSlv) //Once the waiting slave resumes and gets to task_end, the task_end // puts the slave into the freeExtraTaskSlvQ - replaceWithNewSlotSlv( receiverSlv, semEnv ); + replaceWithNewSlotSlv( senderSlv, semEnv ); return; } @@ -661,7 +661,6 @@ receiverID = semReq->receiverID; //For "send", know both send & recv procrs senderID = semReq->senderID; - //receiverSlv = semReq->receiverSlv; senderSlv = semReq->senderSlv; receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself @@ -677,7 +676,7 @@ // it with a new slave (causes it to become an extraTaskSlv) //Once the waiting slave resumes and gets to task_end, the task_end // puts the slave into the freeExtraTaskSlvQ - replaceWithNewSlotSlv( receiverSlv, semEnv ); + replaceWithNewSlotSlv( senderSlv, semEnv ); return; } @@ -899,13 +898,13 @@ //get a new slave to be the slot slave newSlotSlv = readPrivQ( semEnv->freeExtraTaskSlvQ ); if( newSlotSlv == NULL ) - { newSlotSlv = VMS_int__create_slaveVP( &idle_fn, NULL ); + { newSlotSlv = VSs__create_slave_helper( &idle_fn, NULL, semEnv, 0); } //set slave values to make it the slot slave semData = newSlotSlv->semanticData; semData->taskStub = NULL; - semData->slaveType = slotTaskSlv; + semData->slaveType = SlotTaskSlv; semData->needsTaskAssigned = TRUE; newSlotSlv->animSlotAssignedTo = requestingSlv->animSlotAssignedTo; newSlotSlv->coreAnimatedBy = requestingSlv->coreAnimatedBy; @@ -913,12 +912,12 @@ //put it into the slot slave matrix int32 slotNum = requestingSlv->animSlotAssignedTo->slotIdx; int32 coreNum = requestingSlv->coreAnimatedBy; - semEnv->currTaskSlvs[coreNum][slotNum] = newSlotSlv; + semEnv->slotTaskSlvs[coreNum][slotNum] = newSlotSlv; //Fix up requester, to be an extra slave now (but not a free one) // because it's not free, doesn't go into freeExtraTaskSlvQ semData = requestingSlv->semanticData; - semData->slaveType = extraTaskSlv; + semData->slaveType = ExtraTaskSlv; } inline void