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