# HG changeset patch # User Nina Engelhardt # Date 1342193749 -7200 # Node ID 8188c5b4bfd7cedb1e8c3dad7ab66ab23c781ac9 # Parent 13af59ed7ea5db5e7a3af4f581bf78d71966e929 implemented taskwait diff -r 13af59ed7ea5 -r 8188c5b4bfd7 VSs.c --- a/VSs.c Thu Jun 14 18:44:47 2012 -0700 +++ b/VSs.c Fri Jul 13 17:35:49 2012 +0200 @@ -501,6 +501,19 @@ } +void +VSs__taskwait(SlaveVP *animSlv) +{ + VSsSemReq reqData; + + reqData.reqType = taskwait; + reqData.callingSlv = animSlv; + + VMS_WL__send_sem_request( &reqData, animSlv ); +} + + + //========================== send and receive ============================ // diff -r 13af59ed7ea5 -r 8188c5b4bfd7 VSs.h --- a/VSs.h Thu Jun 14 18:44:47 2012 -0700 +++ b/VSs.h Fri Jul 13 17:35:49 2012 +0200 @@ -61,7 +61,9 @@ } VSsPointerEntry; -typedef struct +typedef struct _VSsTaskStub VSsTaskStub; + +struct _VSsTaskStub { void **args; //ctld args must come first, as ptrs VSsTaskType *taskType; @@ -69,8 +71,20 @@ int32 numBlockingProp; SlaveVP *slaveAssignedTo; VSsPointerEntry **ptrEntries; + void* parent; + bool32 parentIsTask; + int32 numChildTasks; + bool32 isWaiting; } -VSsTaskStub; +; + +typedef struct { + void* parent; + bool32 parentIsTask; + int32 numChildTasks; + bool32 isWaiting; + SlaveVP *slaveAssignedTo; +} VSsThreadInfo; typedef struct { @@ -123,6 +137,7 @@ send_from_to, receive_from_to, //=============================== + taskwait, malloc_req, free_req, singleton_fn_start, @@ -213,12 +228,15 @@ }; //TransListElem + + typedef struct { int32 highestTransEntered; TransListElem *lastTransEntered; bool32 needsTaskAssigned; VSsTaskStub *taskStub; + VSsThreadInfo *threadInfo; } VSsSemData; @@ -285,6 +303,9 @@ VSs__end_task( SlaveVP *animSlv ); //========================= +void +VSs__taskwait(SlaveVP *animSlv); + inline int32 * VSs__give_self_taskID( SlaveVP *animSlv ); diff -r 13af59ed7ea5 -r 8188c5b4bfd7 VSs_PluginFns.c --- a/VSs_PluginFns.c Thu Jun 14 18:44:47 2012 -0700 +++ b/VSs_PluginFns.c Fri Jul 13 17:35:49 2012 +0200 @@ -227,6 +227,8 @@ break; //==================================================================== + case taskwait: handleTaskwait(semReq, reqSlv, semEnv); + break; case malloc_req: handleMalloc( semReq, reqSlv, semEnv); break; case free_req: handleFree( semReq, reqSlv, semEnv); @@ -282,6 +284,13 @@ semData->lastTransEntered = NULL; semData->needsTaskAssigned = TRUE; + semData->threadInfo = VMS_PI__malloc( sizeof(VSsThreadInfo) ); + semData->threadInfo->isWaiting = FALSE; + semData->threadInfo->numChildTasks = 0; + semData->threadInfo->parent = NULL; + semData->threadInfo->parentIsTask = FALSE; + semData->threadInfo->slaveAssignedTo = newSlv; + newSlv->semanticData = semData; //=================== Assign new processor to a core ===================== @@ -321,6 +330,8 @@ newSlv = VSs__create_slave_helper( semReq->fnPtr, semReq->initData, semEnv, semReq->coreToAssignOnto ); + ((VSsSemData*)newSlv->semanticData)->threadInfo->parent = requestingSlv; + DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", requestingSlv->slaveID, newSlv->slaveID) #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC diff -r 13af59ed7ea5 -r 8188c5b4bfd7 VSs_Request_Handlers.c --- a/VSs_Request_Handlers.c Thu Jun 14 18:44:47 2012 -0700 +++ b/VSs_Request_Handlers.c Fri Jul 13 17:35:49 2012 +0200 @@ -93,7 +93,8 @@ VMS_int__malloc( taskType->numCtldArgs * sizeof(VSsPointerEntry *) ); newArgs = (void **)( (uint8 *)newStub + sizeof(VSsTaskStub) ); newStub->args = newArgs; - + newStub->numChildTasks = 0; + newStub->parent = NULL; //Copy the arg-pointers.. can be more arguments than just the ones // that StarSs uses to control ordering of task execution. memcpy( newArgs, args, taskType->sizeOfArgs ); @@ -224,7 +225,7 @@ HashTable * argPtrHashTbl = semEnv->argPtrHashTbl; - DEBUG__printf1(dbgRqstHdlr,"SendType request from processor %d",semReq->callingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"Submit request from processor %d",semReq->callingSlv->slaveID) /* ========================== creation ========================== * @@ -239,6 +240,19 @@ taskStub = create_task_stub( taskType, args );//copies arg ptrs taskStub->numBlockingProp = taskType->numCtldArgs; taskStub->taskID = semReq->taskID; //may be NULL + taskStub->numChildTasks = 0; + + VSsSemData* parentSemData = (VSsSemData*) semReq->callingSlv->semanticData; + if(parentSemData->taskStub != NULL){ //calling is task + taskStub->parentIsTask = TRUE; + taskStub->parent = (void*) parentSemData->taskStub; + parentSemData->taskStub->numChildTasks++; + } else { + taskStub->parentIsTask = FALSE; + taskStub->parent = (void*) parentSemData->threadInfo; + parentSemData->threadInfo->numChildTasks++; + } + /*The controlled arguments are then processed one by one. *Processing an argument means getting the hash of the pointer. Then, @@ -376,7 +390,7 @@ HashTable * ptrHashTbl = semEnv->argPtrHashTbl; - DEBUG__printf1(dbgRqstHdlr,"SendType request from processor %d",semReq->callingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"EndTask request from processor %d",semReq->callingSlv->slaveID) /* ========================== end of task =========================== *At the end of a task, the task-stub is sent in the request. @@ -387,6 +401,23 @@ endingTaskType = endingTaskStub->taskType; ptrEntries = endingTaskStub->ptrEntries; //saved in stub when create + /* Check if parent was waiting on this task */ + if(endingTaskStub->parentIsTask){ + VSsTaskStub* parent = (VSsTaskStub*) endingTaskStub->parent; + parent->numChildTasks--; + if(parent->isWaiting && parent->numChildTasks == 0){ + parent->isWaiting = FALSE; + resume_slaveVP( parent->slaveAssignedTo, semEnv ); + } + } else { + VSsThreadInfo* parent = (VSsThreadInfo*) endingTaskStub->parent; + parent->numChildTasks--; + if(parent->isWaiting && parent->numChildTasks == 0){ + parent->isWaiting = FALSE; + resume_slaveVP( parent->slaveAssignedTo, semEnv ); + } + } + /*The task's controlled arguments are processed one by one. *Processing an argument means getting arg-pointer's entry. */ @@ -527,7 +558,7 @@ HashEntry *entry; HashTable *commHashTbl = semEnv->commHashTbl; - DEBUG__printf1(dbgRqstHdlr,"SendType request from processor %d",semReq->sendPr->slaveID) + DEBUG__printf1(dbgRqstHdlr,"SendType request from processor %d",semReq->senderSlv->slaveID) receiverID = semReq->receiverID; //For "send", know both send & recv procrs senderSlv = semReq->senderSlv; @@ -623,7 +654,7 @@ HashEntry *entry; HashTable *commHashTbl = semEnv->commHashTbl; - DEBUG__printf2(dbgRqstHdlr,"SendFromTo request from processor %d to %d",semReq->sendPr->slaveID,semReq->receivePr->slaveID) + DEBUG__printf2(dbgRqstHdlr,"SendFromTo request from processor %d to %d",semReq->senderID,semReq->receiverID) receiverID = semReq->receiverID; //For "send", know both send & recv procrs senderID = semReq->senderID; @@ -699,7 +730,7 @@ HashEntry *entry; HashTable *commHashTbl = semEnv->commHashTbl; - DEBUG__printf1(dbgRqstHdlr,"SendType request from processor %d",semReq->sendPr->slaveID) + DEBUG__printf1(dbgRqstHdlr,"SendType request to %d",semReq->receiverID) receiverID = semReq->receiverID; //For "send", know both send & recv procrs receiverSlv = semReq->receiverSlv; @@ -781,7 +812,7 @@ HashEntry *entry; HashTable *commHashTbl = semEnv->commHashTbl; - DEBUG__printf2(dbgRqstHdlr,"SendFromTo request from processor %d to %d",semReq->sendPr->slaveID,semReq->receivePr->slaveID) + DEBUG__printf2(dbgRqstHdlr,"SendFromTo request from %d to %d",semReq->senderID,semReq->receiverID) receiverID = semReq->receiverID; //For "send", know both send & recv procrs senderID = semReq->senderID; @@ -835,6 +866,35 @@ printf("\nLang Impl Error: Should never be two waiting receives!\n"); } +//========================================================================== +void +handleTaskwait( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv ) + { + VSsTaskStub* requestingTaskStub; + + DEBUG__printf1(dbgRqstHdlr,"Taskwait request from processor %d",requestingSlv->slaveID) + + VSsSemData* semData = ((VSsSemData *)semReq->callingSlv->semanticData); + + requestingTaskStub = semData->taskStub; + + if(requestingTaskStub == NULL){ //calling VP is hosting a thread + if(semData->threadInfo->numChildTasks == 0){ //nobody to wait for, proceed + resume_slaveVP( requestingSlv, semEnv ); + } else { //have to wait + semData->threadInfo->isWaiting = TRUE; + return; + } + } else { //calling VP is executing a task + if(requestingTaskStub->numChildTasks == 0){ + resume_slaveVP( requestingSlv, semEnv ); + } else { //have to wait + requestingTaskStub->isWaiting = TRUE; + return; + } + } + +} //==========================================================================