# HG changeset patch # User Sean Halle # Date 1358019111 28800 # Node ID 3b30da4643d1796a11a8693a8d611d92fe64d8b9 # Parent a60399b62614793bda94bccb529e47615066b5a8 Update2.. in middle of changes.. made request handler ptr be sent w/req struct diff -r a60399b62614 -r 3b30da4643d1 Measurement/VSs_Counter_Recording.c --- a/Measurement/VSs_Counter_Recording.c Thu Oct 18 02:44:30 2012 -0700 +++ b/Measurement/VSs_Counter_Recording.c Sat Jan 12 11:31:51 2013 -0800 @@ -11,11 +11,11 @@ void VSs__init_counter_data_structs( SlaveVP *slave ) { - VSsSemEnv *semanticEnv = - (VSsSemEnv *)PR_SS__give_sem_env_for( slave, VSs_MAGIC_NUMBER ); + VSsLangEnv *langEnv = + (VSsLangEnv *)PR_SS__give_lang_env_for_slave( slave, VSs_MAGIC_NUMBER ); int i; for(i=0;icounterList[i] = makeListOfArrays(sizeof(CounterEvent), 128); + { langEnv->counterList[i] = makeListOfArrays(sizeof(CounterEvent), 128); } } @@ -38,7 +38,7 @@ return; } - VSsSemEnv *semanticEnv = _PRMasterEnv->semanticEnv; + VSsLangEnv *langEnv = _PRTopEnv->protoLangEnv; CounterEvent e; e.event_type = evt_type; @@ -61,9 +61,9 @@ if(pr) corenum = pr->coreAnimatedBy; else return; if(evt_type==Work_start || evt_type==Work_end || evt_type==AppResponderInvocation_start){ - addToListOfArrays_ext(CounterEvent,e,semanticEnv->counterList[corenum]); + addToListOfArrays_ext(CounterEvent,e,langEnv->counterList[corenum]); } else { - addToListOfArraysCounterEvent(e,semanticEnv->counterList[corenum]); + addToListOfArraysCounterEvent(e,langEnv->counterList[corenum]); } } diff -r a60399b62614 -r 3b30da4643d1 Measurement/VSs_Measurement.h --- a/Measurement/VSs_Measurement.h Thu Oct 18 02:44:30 2012 -0700 +++ b/Measurement/VSs_Measurement.h Sat Jan 12 11:31:51 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2009 OpenSourceStewardshipFoundation.org + * Copyright 2009 OpenSourceResearchInstitute.org * Licensed under GNU General Public License version 2 * * Author: seanhalle@yahoo.com @@ -26,8 +26,8 @@ #define ReceiveOfTypeHistIdx 4 #define MEAS__Make_Meas_Hists_for_Language \ - _PRMasterEnv->measHistsInfo = \ - makePrivDynArrayOfSize( (void***)&(_PRMasterEnv->measHists), 200); \ + _PRTopEnv->measHistsInfo = \ + makePrivDynArrayOfSize( (void***)&(_PRTopEnv->measHists), 200); \ makeAMeasHist( SendFromToHistIdx, "SendFromTo", 50, 0, 100 ) \ makeAMeasHist( SendOfTypeHistIdx, "SendOfType", 50, 0, 100 ) \ makeAMeasHist( ReceiveFromToHistIdx,"ReceiveFromTo", 50, 0, 100 ) \ @@ -40,7 +40,7 @@ #define Meas_endSendFromTo \ saveLowTimeStampCountInto( endStamp ); \ addIntervalToHist( startStamp, endStamp, \ - _PRMasterEnv->measHists[ SendFromToHistIdx ] ); + _PRTopEnv->measHists[ SendFromToHistIdx ] ); #define Meas_startSendOfType \ int32 startStamp, endStamp; \ @@ -49,7 +49,7 @@ #define Meas_endSendOfType \ saveLowTimeStampCountInto( endStamp ); \ addIntervalToHist( startStamp, endStamp, \ - _PRMasterEnv->measHists[ SendOfTypeHistIdx ] ); + _PRTopEnv->measHists[ SendOfTypeHistIdx ] ); #define Meas_startReceiveFromTo \ int32 startStamp, endStamp; \ @@ -58,7 +58,7 @@ #define Meas_endReceiveFromTo \ saveLowTimeStampCountInto( endStamp ); \ addIntervalToHist( startStamp, endStamp, \ - _PRMasterEnv->measHists[ ReceiveFromToHistIdx ] ); + _PRTopEnv->measHists[ ReceiveFromToHistIdx ] ); #define Meas_startReceiveOfType \ int32 startStamp, endStamp; \ @@ -67,7 +67,7 @@ #define Meas_endReceiveOfType \ saveLowTimeStampCountInto( endStamp ); \ addIntervalToHist( startStamp, endStamp, \ - _PRMasterEnv->measHists[ReceiveOfTypeHistIdx ] ); + _PRTopEnv->measHists[ReceiveOfTypeHistIdx ] ); #else //===================== turned off ========================== diff -r a60399b62614 -r 3b30da4643d1 VSs.c --- a/VSs.c Thu Oct 18 02:44:30 2012 -0700 +++ b/VSs.c Sat Jan 12 11:31:51 2013 -0800 @@ -15,6 +15,12 @@ #include "Measurement/VSs_Counter_Recording.h" //========================================================================== +void +VSs__init_Helper(); + +SlaveVP * +VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData, + int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd ); //========================================================================== @@ -75,12 +81,12 @@ * saves jump point, and second jumps back several times to get reliable time */ void -VSs__begin_primitive() - { VSsSemData *semData; +VSs__begin_primitive( SlaveVP *animSlv ) + { VSsLangData *langData; - semData = (VSsSemData *)PR_WL__give_sem_data( animSlv, VSs_MAGIC_NUMBER); + langData = (VSsLangData *)PR_WL__give_lang_data( animSlv, VSs_MAGIC_NUMBER); - saveLowTimeStampCountInto( semData->primitiveStartTime ); + saveLowTimeStampCountInto( langData->primitiveStartTime ); } /*Just quick and dirty for now -- make reliable later @@ -89,22 +95,18 @@ * also to throw out any "weird" values due to OS interrupt or TSC rollover */ int32 -VSs__end_primitive_and_give_cycles( SlaveVP animSlv ) +VSs__end_primitive_and_give_cycles( SlaveVP *animSlv ) { int32 endTime, startTime; - VSsSemData *semData; + VSsLangData *langData; //TODO: fix by repeating time-measurement saveLowTimeStampCountInto( endTime ); - semData = (VSsSemData *)PR_WL__give_sem_data( animSlv, VSs_MAGIC_NUMBER); - startTime = semData->primitiveStartTime; + langData = (VSsLangData *)PR_WL__give_lang_data( animSlv, VSs_MAGIC_NUMBER); + startTime = langData->primitiveStartTime; return (endTime - startTime); } -//=========================================================================== - - - //=========================================================================== @@ -124,21 +126,44 @@ ANY_CORE, creatingThd ); } +/* old version -- looks safe to delete +SlaveVP * +VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, + SlaveVP *creatingSlv, int32 coreToAssignOnto ) + { VSsLangReq reqData; + + //the lang request data is on the stack and disappears when this + // call returns -- it's guaranteed to remain in the VP's stack for as + // long as the VP is suspended. + reqData.reqType = create_slave_w_aff; //not used, May 2012 + reqData.coreToAssignOnto = coreToAssignOnto; + reqData.fnPtr = fnPtr; + reqData.initData = initData; + reqData.callingSlv = creatingSlv; + + PR_WL__send_create_slaveVP_req( &reqData, creatingSlv, VSs_MAGIC_NUMBER ); + + return creatingSlv->dataRetFromReq; + } +*/ + SlaveVP * VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData, int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd ) - { VSsSemReq reqData; + { VSsLangReq reqData; - //the semantic request data is on the stack and disappears when this + //the lang request data is on the stack and disappears when this // call returns -- it's guaranteed to remain in the VP's stack for as // long as the VP is suspended. - reqData.reqType = create_slave; //know type because in a PR create req - reqData.coreToAssignOnto = coreToAssignOnto; + reqData.reqType = create_slave; //know type because in a PR create req + reqData.coreToAssignOnto = coreToAssignOnto; + reqData.fnPtr = fnPtr; + reqData.initData = initData; - PR_WL__send_create_slaveVP_req( &reqData, fnPtr, initData, thdID, + PR_WL__send_create_slaveVP_req( &reqData, thdID, &handleCreateThd, creatingThd, VSs_MAGIC_NUMBER ); - return creatingThd->dataRetFromReq; + return (SlaveVP *)creatingThd->dataRetFromReq; } /*This is always the last thing done in the code animated by a thread VP. @@ -151,7 +176,8 @@ void VSs__end_thread( SlaveVP *thdToEnd ) { - PR_WL__send_dissipate_req( thdToEnd, VSs_MAGIC_NUMBER ); + //the lang request is null for VSs version of end slave + PR_WL__send_end_slave_req( NULL, &handleDissipate, thdToEnd, VSs_MAGIC_NUMBER ); } @@ -164,7 +190,7 @@ */ void VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv) - { VSsSemReq reqData; + { VSsLangReq reqData; reqData.reqType = submit_task; @@ -175,13 +201,14 @@ //Create task is a special form, so have to pass as parameters, the // top-level-fn of task and the data for that fn, plus lang's req, // animating slave, and lang's magic number - PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID, + &handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); } void VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, - SlaveVP *animSlv) - { VSsSemReq reqData; + SlaveVP *animSlv ) + { VSsLangReq reqData; reqData.reqType = submit_task; @@ -189,7 +216,8 @@ reqData.args = args; reqData.callingSlv = animSlv; - PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID, + &handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); } @@ -212,12 +240,10 @@ */ void VSs__end_task( SlaveVP *animSlv ) - { VSsSemReq reqData; - - reqData.reqType = end_task; - reqData.callingSlv = animSlv; + { VSsLangReq reqData; - PR_WL__send_end_task_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + //VSs has nothing extra to communicate to end task handler, so lang req is NULL + PR_WL__send_end_task_request( NULL, &handleEndTask, animSlv, VSs_MAGIC_NUMBER ); } @@ -227,12 +253,12 @@ void VSs__taskwait(SlaveVP *animSlv) { - VSsSemReq reqData; + VSsLangReq reqData; reqData.reqType = taskwait; reqData.callingSlv = animSlv; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleTaskwait, animSlv, VSs_MAGIC_NUMBER ); } @@ -243,7 +269,7 @@ inline int32 * VSs__give_self_taskID( SlaveVP *animSlv ) { - return PR__give_task_ID( animSlv, VSs_MAGIC_NUMBER ); + return PR__give_ID_from_slave( animSlv, VSs_MAGIC_NUMBER ); } //================================ send =================================== @@ -251,7 +277,7 @@ void VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID, SlaveVP *senderSlv ) - { VSsSemReq reqData; + { VSsLangReq reqData; reqData.reqType = send_type_to; @@ -262,14 +288,14 @@ reqData.nextReqInHashEntry = NULL; - PR_WL__send_sem_request( &reqData, senderSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleSendTypeTo, senderSlv, VSs_MAGIC_NUMBER ); //When come back from suspend, no longer own data reachable from msg } void VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ) - { VSsSemReq reqData; + { VSsLangReq reqData; reqData.reqType = send_from_to; @@ -280,7 +306,7 @@ reqData.nextReqInHashEntry = NULL; - PR_WL__send_sem_request( &reqData, senderSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleSendFromTo, senderSlv, VSs_MAGIC_NUMBER ); } @@ -295,7 +321,7 @@ void * VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ) { DEBUG__printf1(dbgRqstHdlr,"WL: receive type to %d",receiverID[1] ); - VSsSemReq reqData; + VSsLangReq reqData; reqData.reqType = receive_type_to; @@ -305,7 +331,7 @@ reqData.nextReqInHashEntry = NULL; - PR_WL__send_sem_request( &reqData, receiverSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleReceiveTypeTo, receiverSlv, VSs_MAGIC_NUMBER ); return receiverSlv->dataRetFromReq; } @@ -319,7 +345,7 @@ void * VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; reqData.reqType = receive_from_to; @@ -330,7 +356,7 @@ reqData.nextReqInHashEntry = NULL; DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]); - PR_WL__send_sem_request( &reqData, receiverSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleReceiveFromTo, receiverSlv, VSs_MAGIC_NUMBER ); return receiverSlv->dataRetFromReq; } @@ -355,22 +381,23 @@ void asm_write_ret_from_singleton(VSsSingleton *singletonPtrAddr); /*Fn singleton uses ID as index into array of singleton structs held in the - * semantic environment. + * language environment. */ void VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; // reqData.reqType = singleton_fn_start; reqData.singletonID = singletonID; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleStartFnSingleton, animSlv, VSs_MAGIC_NUMBER ); if( animSlv->dataRetFromReq ) //will be 0 or addr of label in end singleton { - VSsSemEnv *semEnv = PR_WL__give_sem_env_for( animSlv, VSs_MAGIC_NUMBER ); - asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID])); + VSsLangEnv *langEnv = + PR_int__give_lang_env_for_slave__ML( animSlv, VSs_MAGIC_NUMBER ); + asm_write_ret_from_singleton(&(langEnv->fnSingletons[ singletonID])); } } @@ -381,7 +408,7 @@ void VSs__start_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; if( *singletonAddr && (*singletonAddr)->hasFinished ) goto JmpToEndSingleton; @@ -389,7 +416,7 @@ reqData.reqType = singleton_data_start; reqData.singletonPtrAddr = singletonAddr; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleStartDataSingleton, animSlv, VSs_MAGIC_NUMBER ); if( animSlv->dataRetFromReq ) //either 0 or end singleton's return addr { //Assembly code changes the return addr on the stack to the one // saved into the singleton by the end-singleton-fn @@ -410,17 +437,19 @@ void VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; //don't need this addr until after at least one singleton has reached // this function - VSsSemEnv *semEnv = PR_WL__give_sem_env_for( animSlv, VSs_MAGIC_NUMBER ); - asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID])); + VSsLangEnv * + langEnv = PR_int__give_lang_env_for_slave__ML( animSlv, VSs_MAGIC_NUMBER ); + + asm_write_ret_from_singleton(&(langEnv->fnSingletons[ singletonID])); reqData.reqType = singleton_fn_end; reqData.singletonID = singletonID; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleEndFnSingleton, animSlv, VSs_MAGIC_NUMBER ); EndSingletonInstrAddr: return; @@ -429,7 +458,7 @@ void VSs__end_data_singleton( VSsSingleton **singletonPtrAddr, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; //don't need this addr until after singleton struct has reached // this function for first time @@ -442,7 +471,7 @@ reqData.reqType = singleton_data_end; reqData.singletonPtrAddr = singletonPtrAddr; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleEndDataSingleton, animSlv, VSs_MAGIC_NUMBER ); } /*This executes the function in the masterVP, so it executes in isolation @@ -459,14 +488,14 @@ VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, void *data, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; // reqData.reqType = atomic; reqData.fnToExecInMaster = ptrToFnToExecInMaster; reqData.dataForFn = data; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleAtomic, animSlv, VSs_MAGIC_NUMBER ); } @@ -486,14 +515,14 @@ void VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; // reqData.callingSlv = animSlv; reqData.reqType = trans_start; reqData.transID = transactionID; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleTransStart, animSlv, VSs_MAGIC_NUMBER ); } /*This suspends to the master, then uses transactionID as index into an @@ -508,36 +537,15 @@ void VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ) { - VSsSemReq reqData; + VSsLangReq reqData; // reqData.callingSlv = animSlv; reqData.reqType = trans_end; reqData.transID = transactionID; - PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); + PR_WL__send_lang_request( &reqData, &handleTransEnd, animSlv, VSs_MAGIC_NUMBER ); } //======================== Internal ================================== -/* - */ -SlaveVP * -VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, - SlaveVP *creatingSlv, int32 coreToAssignOnto ) - { VSsSemReq reqData; - - //the semantic request data is on the stack and disappears when this - // call returns -- it's guaranteed to remain in the VP's stack for as - // long as the VP is suspended. - reqData.reqType = create_slave_w_aff; //not used, May 2012 - reqData.coreToAssignOnto = coreToAssignOnto; - reqData.fnPtr = fnPtr; - reqData.initData = initData; - reqData.callingSlv = creatingSlv; - - PR_WL__send_create_slaveVP_req( &reqData, creatingSlv, VSs_MAGIC_NUMBER ); - - return creatingSlv->dataRetFromReq; - } - diff -r a60399b62614 -r 3b30da4643d1 VSs.h --- a/VSs.h Thu Oct 18 02:44:30 2012 -0700 +++ b/VSs.h Sat Jan 12 11:31:51 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2009 OpenSourceStewardshipFoundation.org + * Copyright 2009 OpenSourceResearchInstitute.org * Licensed under GNU General Public License version 2 * * Author: seanhalle@yahoo.com @@ -19,7 +19,7 @@ //uniquely identifies VSs -- should be a jenkins char-hash of "VSs" to int32 #define VSs_MAGIC_NUMBER 0000000001 -#define NUM_STRUCS_IN_SEM_ENV 1000 +#define NUM_STRUCS_IN_LANG_ENV 1000 //This is hardware dependent -- it's the number of cycles of scheduling // overhead -- if a work unit is fewer than this, it is better being @@ -31,7 +31,7 @@ //=========================================================================== /*This header defines everything specific to the VSs semantic plug-in */ -typedef struct _VSsSemReq VSsSemReq; +typedef struct _VSsLangReq VSsLangReq; typedef struct _VSsTaskStub VSsTaskStub; typedef void (*VSsTaskFnPtr ) ( void *, SlaveVP *); typedef void (*PtrToAtomicFn ) ( void * ); //executed atomically in master @@ -73,11 +73,13 @@ } VSsPointerEntry; -/*This is placed into semData, used for dependencies and wait construct*/ +/*This is placed into langData, used for dependencies and wait construct*/ struct _VSsTaskStub { + //====== The first fields must match PRLangMetaTask fields ====== int32 langMagicNumber; //magic num must be 1st field of langMetaTask PRMetaTask *protoMetaTask; //back-link must always be 2nd field + //====== end PRLangMetaTask fields ========= void **args; //ctld args must be the first ones (as ptrs) VSsPointerEntry **ptrEntries; int32 numBlockingProp; @@ -149,7 +151,7 @@ trans_end }; -struct _VSsSemReq +struct _VSsLangReq { enum VSsReqType reqType; SlaveVP *callingSlv; VSsTaskType *taskType; @@ -162,7 +164,7 @@ int32 *receiverID; int32 msgType; void *msg; - VSsSemReq *nextReqInHashEntry; + VSsLangReq *nextReqInHashEntry; //In PRReq: int32 *taskID; TopLevelFnPtr fnPtr; @@ -181,31 +183,22 @@ int32 transID; } -/* VSsSemReq */; +/* VSsLangReq */; typedef struct - { PRSemEnv *protoSemEnv; + { PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) - PrivQueueStruc *freeTaskSlvRecycleQ; //Shared PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) -// SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; + HashTable *argPtrHashTbl; HashTable *commHashTbl; -// int32 numLiveFreeTaskSlvs; -// int32 numLiveThreadSlvs; int32 nextCoreToGetNewSlv; int32 primitiveStartTime; //fix limit on num with dynArray - VSsSingleton fnSingletons[NUM_STRUCS_IN_SEM_ENV]; - VSsTrans transactionStrucs[NUM_STRUCS_IN_SEM_ENV]; - -// bool32 *coreIsDone; -// int32 numCoresDone; - -// SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS]; -// int shutdownInitiated; + VSsSingleton fnSingletons[NUM_STRUCS_IN_LANG_ENV]; + VSsTrans transactionStrucs[NUM_STRUCS_IN_LANG_ENV]; #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC ListOfArrays* unitList; @@ -222,7 +215,7 @@ ListOfArrays* counterList[NUM_CORES]; #endif } -VSsSemEnv; +VSsLangEnv; typedef struct _TransListElem TransListElem; @@ -248,7 +241,7 @@ int32 primitiveStartTime; // VSsTaskStub *taskStub; //get from slave via PR accessor } -VSsSemData; +VSsLangData; //=========================================================================== @@ -355,18 +348,14 @@ //========================= Internal use only ============================= void -VSs__Request_Handler( SlaveVP *requestingSlv, void *_semEnv ); +VSs__Request_Handler( SlaveVP *requestingSlv, void *_langEnv ); SlaveVP * -VSs__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot ); +VSs__assign_work_to_slot( void *_langEnv, AnimSlot *slot ); SlaveVP* VSs__create_slave_helper( TopLevelFnPtr fnPtr, void *initData, - VSsSemEnv *semEnv, int32 coreToAssignOnto ); - -PRMetaTask * -PR_int__create_generic_slave_meta_task( void *initData ); - + VSsLangEnv *langEnv, int32 coreToAssignOnto ); SlaveVP * VSs__create_slave_with( TopLevelFnPtr fnPtr, void *initData, @@ -376,6 +365,15 @@ VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, SlaveVP *creatingSlv, int32 coreToAssignOnto); +//===================== ===================== +inline +void * +handleSubmitTask( VSsLangReq *langReq, VSsLangEnv *langEnv ); +inline +void +handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); + + //===================== Measurement of Lang Overheads ===================== #include "Measurement/VSs_Measurement.h" diff -r a60399b62614 -r 3b30da4643d1 VSs_PluginFns.c --- a/VSs_PluginFns.c Thu Oct 18 02:44:30 2012 -0700 +++ b/VSs_PluginFns.c Sat Jan 12 11:31:51 2013 -0800 @@ -13,16 +13,16 @@ //=========================== Local Fn Prototypes =========================== void -resume_slaveVP( SlaveVP *slave, VSsSemEnv *semEnv ); +resume_slaveVP( SlaveVP *slave, VSsLangEnv *langEnv ); inline void -handleSemReq( PRReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv ); +handleLangReq( PRReqst *req, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); inline void -handleDissipate( SlaveVP *requestingSlv, VSsSemEnv *semEnv ); +handleDissipate( SlaveVP *requestingSlv, VSsLangEnv *langEnv ); inline void -handleCreate( PRReqst *req, SlaveVP *requestingSlv, VSsSemEnv *semEnv ); +handleCreate( PRReqst *req, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); //============================== Assigner ================================== // @@ -52,28 +52,31 @@ * the junk tasks are allowed to leave behind. */ SlaveVP * -VSs__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot ) +VSs__assign_work_to_slot( void *_langEnv, AnimSlot *slot ) { SlaveVP *returnSlv; - VSsSemEnv *semEnv; + VSsLangEnv *langEnv; int32 coreNum, slotNum; - PRMetaTask *returnMetaTask = NULL, *newTaskStub; + PRMetaTask *returnMetaTask = NULL; + VSsTaskStub *newTaskStub; coreNum = slot->coreSlotIsOn; slotNum = slot->slotIdx; - semEnv = (VSsSemEnv *)_semEnv; + langEnv = (VSsLangEnv *)_langEnv; //Check for suspended slaves that are ready to resume - returnSlv = readPrivQ( semEnv->slavesReadyToResumeQ ); + returnSlv = readPrivQ( langEnv->slavesReadyToResumeQ ); if( returnSlv != NULL ) //Yes, have a slave, so return it. { returnSlv->coreAnimatedBy = coreNum; - returnMetaTask = returnSlv->metaTask; + //returnMetaTask = returnSlv->metaTask; + fixme; //use PR_int__put_slave_into_slot( SlaveVP *slave, AnimSlot *slot ) goto ReturnTheMetaTask; } - newTaskStub = readPrivQ( semEnv->taskReadyQ ); + newTaskStub = readPrivQ( langEnv->taskReadyQ ); if( newTaskStub != NULL ) - { returnMetaTask = newTaskStub->protoMetaTask; + { //returnMetaTask = newTaskStub->protoMetaTask; + fixme; //use PR_int__put_task_into_slot( SlaveVP *slave, AnimSlot *slot ) goto ReturnTheMetaTask; } @@ -84,44 +87,48 @@ //This assumes the task has already been assigned to a slave, which happens // inside Master.. if( returnMetaTask == NULL ) - { returnSlv = semEnv->process->idleSlv[coreNum][slotNum]; + { returnSlv = langEnv->process->idleSlv[coreNum][slotNum]; //things that would normally happen in resume(), but these VPs // never go there returnSlv->numTimesAssignedToASlot++; Unit newU; - newU.vp = returnSlv->slaveID; + newU.vp = returnSlv->slaveNum; newU.task = returnSlv->numTimesAssignedToASlot; - addToListOfArrays(Unit,newU,semEnv->unitList); + addToListOfArrays(Unit,newU,langEnv->unitList); if (returnSlv->numTimesAssignedToASlot > 1) { Dependency newD; - newD.from_vp = returnSlv->slaveID; + newD.from_vp = returnSlv->slaveNum; newD.from_task = returnSlv->numTimesAssignedToASlot - 1; - newD.to_vp = returnSlv->slaveID; + newD.to_vp = returnSlv->slaveNum; newD.to_task = returnSlv->numTimesAssignedToASlot; - addToListOfArrays(Dependency, newD, semEnv->ctlDependenciesList); + addToListOfArrays(Dependency, newD, langEnv->ctlDependenciesList); } returnMetaTask = returnSlv->metaTask; } else //returnSlv != NULL { //assignSlv->numTimesAssigned++; Unit prev_in_slot = - semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum]; + langEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum]; if(prev_in_slot.vp != 0) { Dependency newD; newD.from_vp = prev_in_slot.vp; newD.from_task = prev_in_slot.task; - newD.to_vp = returnSlv->slaveID; + newD.to_vp = returnSlv->slaveNum; newD.to_task = returnSlv->numTimesAssignedToASlot; - addToListOfArrays(Dependency,newD,semEnv->hwArcs); + addToListOfArrays(Dependency,newD,langEnv->hwArcs); } - prev_in_slot.vp = returnSlv->slaveID; + prev_in_slot.vp = returnSlv->slaveNum; prev_in_slot.task = returnSlv->numTimesAssignedToASlot; - semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] = + langEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] = prev_in_slot; } #endif + if( isEmptyPrivQ(langEnv->slavesReadyToResumeQ) && + isEmptyPrivQ(langEnv->taskReadyQ) ) + PR_int__clear_work_in_lang_env(langEnv); + return( returnMetaTask ); } @@ -133,42 +140,43 @@ */ void -handleSemReq( PRReqst *req, SlaveVP *reqSlv, VSsSemEnv *semEnv ) - { VSsSemReq *semReq; +handleLangReq( void *_langReq, SlaveVP *reqSlv, VSsLangEnv *langEnv ) + { VSsLangReq *langReq; - semReq = PR_PI__take_sem_reqst_from(req); - if( semReq == NULL ) return; - switch( semReq->reqType ) //sem handlers are all in other file + langReq = (VSsLangReq *)_langReq; + if( langReq == NULL ) return; + + switch( langReq->reqType ) //lang handlers are all in other file { - case send_type_to: handleSendTypeTo( semReq, semEnv); + case send_type_to: handleSendTypeTo( langReq, langEnv); break; - case send_from_to: handleSendFromTo( semReq, semEnv); + case send_from_to: handleSendFromTo( langReq, langEnv); break; - case receive_type_to: handleReceiveTypeTo(semReq, semEnv); + case receive_type_to: handleReceiveTypeTo(langReq, langEnv); break; - case receive_from_to: handleReceiveFromTo(semReq, semEnv); + case receive_from_to: handleReceiveFromTo(langReq, langEnv); break; - case taskwait: handleTaskwait( semReq, reqSlv, semEnv); + case taskwait: handleTaskwait( langReq, reqSlv, langEnv); break; //==================================================================== - case malloc_req: handleMalloc( semReq, reqSlv, semEnv); + case malloc_req: handleMalloc( langReq, reqSlv, langEnv); break; - case free_req: handleFree( semReq, reqSlv, semEnv); + case free_req: handleFree( langReq, reqSlv, langEnv); break; - case singleton_fn_start: handleStartFnSingleton(semReq, reqSlv, semEnv); + case singleton_fn_start: handleStartFnSingleton(langReq, reqSlv, langEnv); break; - case singleton_fn_end: handleEndFnSingleton( semReq, reqSlv, semEnv); + case singleton_fn_end: handleEndFnSingleton( langReq, reqSlv, langEnv); break; - case singleton_data_start:handleStartDataSingleton(semReq,reqSlv,semEnv); + case singleton_data_start:handleStartDataSingleton(langReq,reqSlv,langEnv); break; - case singleton_data_end: handleEndDataSingleton(semReq, reqSlv, semEnv); + case singleton_data_end: handleEndDataSingleton(langReq, reqSlv, langEnv); break; - case atomic: handleAtomic( semReq, reqSlv, semEnv); + case atomic: handleAtomic( langReq, reqSlv, langEnv); break; - case trans_start: handleTransStart( semReq, reqSlv, semEnv); + case trans_start: handleTransStart( langReq, reqSlv, langEnv); break; - case trans_end: handleTransEnd( semReq, reqSlv, semEnv); + case trans_end: handleTransEnd( langReq, reqSlv, langEnv); break; } } @@ -178,12 +186,11 @@ //=========================== Helper ============================== void -resume_slaveVP( SlaveVP *slave, VSsSemEnv *semEnv ) +resume_slaveVP( SlaveVP *slave, VSsLangEnv *langEnv ) { //both suspended tasks and suspended explicit slaves resumed with this - writePrivQ( slave, semEnv->slavesReadyToResumeQ ); - if( semEnv->protoSemEnv->hasWork != TRUE ) - semEnv->protoSemEnv->hasWork = TRUE; + writePrivQ( slave, langEnv->slavesReadyToResumeQ ); + PR_int__set_work_in_lang_env(langEnv); #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS /* @@ -195,17 +202,17 @@ #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC slave->numTimesAssignedToASlot++; //Somewhere here! Unit newU; - newU.vp = slave->slaveID; + newU.vp = slave->slaveNum; newU.task = slave->numTimesAssignedToASlot; - addToListOfArrays(Unit,newU,semEnv->unitList); + addToListOfArrays(Unit,newU,langEnv->unitList); if (slave->numTimesAssignedToASlot > 1) { Dependency newD; - newD.from_vp = slave->slaveID; + newD.from_vp = slave->slaveNum; newD.from_task = slave->numTimesAssignedToASlot - 1; - newD.to_vp = slave->slaveID; + newD.to_vp = slave->slaveNum; newD.to_task = slave->numTimesAssignedToASlot; - addToListOfArrays(Dependency, newD ,semEnv->ctlDependenciesList); + addToListOfArrays(Dependency, newD ,langEnv->ctlDependenciesList); } #endif } diff -r a60399b62614 -r 3b30da4643d1 VSs_Request_Handlers.c --- a/VSs_Request_Handlers.c Thu Oct 18 02:44:30 2012 -0700 +++ b/VSs_Request_Handlers.c Sat Jan 12 11:31:51 2013 -0800 @@ -18,7 +18,7 @@ //=========================== Local Fn Prototypes =========================== void -resume_slaveVP( SlaveVP *slave, VSsSemEnv *semEnv ); +resume_slaveVP( SlaveVP *slave, VSsLangEnv *langEnv ); @@ -28,15 +28,15 @@ /*Only clone the elements of req used in these reqst handlers */ -VSsSemReq * -cloneReq( VSsSemReq *semReq ) - { VSsSemReq *clonedReq; +VSsLangReq * +cloneReq( VSsLangReq *langReq ) + { VSsLangReq *clonedReq; - clonedReq = PR_PI__malloc( sizeof(VSsSemReq) ); - clonedReq->reqType = semReq->reqType; - clonedReq->senderSlv = semReq->senderSlv; - clonedReq->receiverSlv= semReq->receiverSlv; - clonedReq->msg = semReq->msg; + clonedReq = PR_PI__malloc( sizeof(VSsLangReq) ); + clonedReq->reqType = langReq->reqType; + clonedReq->senderSlv = langReq->senderSlv; + clonedReq->receiverSlv= langReq->receiverSlv; + clonedReq->msg = langReq->msg; clonedReq->nextReqInHashEntry = NULL; return clonedReq; @@ -45,29 +45,30 @@ HashEntry * -giveEntryElseInsertReqst32( int32 *key, VSsSemReq *semReq, +giveEntryElseInsertReqst32( int32 *key, VSsLangReq *langReq, HashTable *commHashTbl ) { HashEntry *entry; - VSsSemReq *waitingReq; + VSsLangReq *waitingReq; entry = getEntryFromTable32( key, commHashTbl ); if( entry == NULL ) { //no waiting sends or receives, so add this request and exit // note: have to clone the request because it's on stack of sender - addValueIntoTable32( key, cloneReq( semReq ), commHashTbl ); + addValueIntoTable32( key, cloneReq( langReq ), commHashTbl ); return NULL; } - waitingReq = (VSsSemReq *)entry->content; + waitingReq = (VSsLangReq *)entry->content; if( waitingReq == NULL ) //might happen when last waiting gets paired { //no waiting sends or receives, so add this request and exit - entry->content = semReq; + entry->content = langReq; return NULL; } return entry; } -inline VSsPointerEntry * +inline +VSsPointerEntry * create_pointer_entry( ) { VSsPointerEntry *newEntry; @@ -82,28 +83,55 @@ /*malloc's space and initializes fields -- and COPIES the arg values * to new space */ -inline VSsTaskStub * +inline +VSsTaskStub * create_task_stub( VSsTaskType *taskType, void **args ) { void **newArgs; - VSsTaskStub* newStub = PR_int__malloc( sizeof(PRMetaTask) + taskType->sizeOfArgs ); - newStub->numBlockingProp = taskType->numCtldArgs; - newStub->taskType = taskType; + VSsTaskStub* newStub; + + //Create a new task stub, with enough room at end to copy args there + newStub = (VSsTaskStub *)PR_int__create_lang_meta_task__ML( + sizeof(VSsTaskStub) + taskType->sizeOfArgs, VSs_MAGIC_NUMBER ); + + newStub->numBlockingProp = taskType->numCtldArgs; + newStub->taskType = taskType; newStub->ptrEntries = PR_int__malloc( taskType->numCtldArgs * sizeof(VSsPointerEntry *) ); - newArgs = (void **)( (uint8 *)newStub + sizeof(PRMetaTask) ); - newStub->args = newArgs; + + //Skip over the task stub, to get ptr to space alloc'd for args copy + newArgs = (void **)( (uint8 *)newStub + sizeof(VSsTaskStub) ); + newStub->args = newArgs; newStub->numLiveChildTasks = 0; newStub->numLiveChildThreads = 0; - newStub->isEnded = FALSE; + newStub->isEnded = FALSE; - //Copy the arg-pointers.. can be more arguments than just the ones + //Copy the args.. can be more arguments than just the ones // that StarSs uses to control ordering of task execution. memcpy( newArgs, args, taskType->sizeOfArgs ); return newStub; } -inline VSsTaskStubCarrier * + +VSsTaskStub * +VSs__create_generic_slave_task_stub_in_slave( SlaveVP *slave ) + { VSsTaskStub *newStub; + + newStub = (VSsTaskStub *)PR_int__create_lang_meta_task_in_slave__ML( + sizeof(VSsTaskStub), slave, VSs_MAGIC_NUMBER ); + newStub->numBlockingProp = 0; + newStub->taskType = NULL; + newStub->ptrEntries = NULL; + newStub->args = NULL; + newStub->numLiveChildTasks = 0; + newStub->numLiveChildThreads = 0; + newStub->isEnded = FALSE; + + return newStub; + } + +inline +VSsTaskStubCarrier * create_task_carrier( VSsTaskStub *taskStub, int32 argNum, int32 rdOrWrite ) { VSsTaskStubCarrier *newCarrier; @@ -129,17 +157,23 @@ * *When slave dissipates, PR will call the registered recycler for the task stub. */ -inline void -handleCreateThd( PRReqst *req, SlaveVP *requestingSlv, SlaveVP *newSlv, VSsSemEnv *semEnv ) - { VSsSemReq *semReq; +//inline +SlaveVP * +handleCreateThd( void *_langReq, SlaveVP *requestingSlv, void *_langEnv ) + { VSsLangReq *langReq; VSsTaskStub *taskStub, *parentTaskStub; + SlaveVP *newSlv; + VSsLangEnv *langEnv; + + langReq = (VSsLangReq *) _langReq; + langEnv = (VSsLangEnv *) _langEnv; - semReq = PR_PI__take_sem_reqst_from( req ); - - parentTaskStub = PR_PI__give_lang_meta_task( requestingSlv ); + newSlv = PR_int__create_slave( langReq->fnPtr, langReq->initData ); + + parentTaskStub = PR_PI__give_lang_meta_task_from_slave__ML( requestingSlv, VSs_MAGIC_NUMBER ); parentTaskStub->numLiveChildThreads += 1; - taskStub = create_thread_task_stub(); //only used for wait info + taskStub = VSs__create_generic_slave_task_stub_in_slave(requestingSlv); //used for wait info taskStub->parentTaskStub = parentTaskStub; //note, semantic data will be initialized by separate, registered @@ -151,15 +185,15 @@ #else //Assigning slaves to cores is part of SSR code.. - int32 coreToAssignOnto = semReq->coreToAssignOnto; + int32 coreToAssignOnto = langReq->coreToAssignOnto; if(coreToAssignOnto < 0 || coreToAssignOnto >= NUM_CORES ) { //out-of-range, so round-robin assignment - newSlv->coreAnimatedBy = semEnv->nextCoreToGetNewSlv; + newSlv->coreAnimatedBy = langEnv->nextCoreToGetNewSlv; - if( semEnv->nextCoreToGetNewSlv >= NUM_CORES - 1 ) - semEnv->nextCoreToGetNewSlv = 0; + if( langEnv->nextCoreToGetNewSlv >= NUM_CORES - 1 ) + langEnv->nextCoreToGetNewSlv = 0; else - semEnv->nextCoreToGetNewSlv += 1; + langEnv->nextCoreToGetNewSlv += 1; } else //core num in-range, so use it { newSlv->coreAnimatedBy = coreToAssignOnto; @@ -170,51 +204,55 @@ DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", - requestingSlv->slaveID, newSlv->slaveID) + requestingSlv->slaveNum, newSlv->slaveNum) #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC Dependency newD; - newD.from_vp = requestingSlv->slaveID; + newD.from_vp = requestingSlv->slaveNum; newD.from_task = requestingSlv->numTimesAssignedToASlot; - newD.to_vp = newSlv->slaveID; + newD.to_vp = newSlv->slaveNum; newD.to_task = 1; - addToListOfArrays(Dependency,newD,semEnv->commDependenciesList); + addToListOfArrays(Dependency,newD,langEnv->commDependenciesList); #endif //For VSs, caller needs ptr to created thread returned to it requestingSlv->dataRetFromReq = newSlv; - resume_slaveVP(requestingSlv , semEnv ); - resume_slaveVP( newSlv, semEnv ); + resume_slaveVP(requestingSlv , langEnv ); + resume_slaveVP( newSlv, langEnv ); + + return newSlv; } /*Initialize semantic data struct.. this initializer doesn't need any input, * but some languages may need something from inside the request that was sent * to create a slave.. in that case, just make initializer do the malloc then - * use the PR_PI__give_sem_data inside the create handler, and fill in the - * semData values there. + * use the PR_PI__give_lang_data inside the create handler, and fill in the + * langData values there. */ -void * createInitialSemanticData( ) - { VSsSemData *semData; +void * +createInitialSemanticData( ) + { VSsLangData *langData; - semData = PR_PI__malloc( sizeof(VSsSemData) ); + langData = PR_PI__malloc( sizeof(VSsLangData) ); - semData->highestTransEntered = -1; - semData->lastTransEntered = NULL; - return semData; + langData->highestTransEntered = -1; + langData->lastTransEntered = NULL; + return langData; } /*SlaveVP dissipate -- this is NOT task-end!, only call this to end explicitly * created threads */ -inline void -handleDissipate( SlaveVP *requestingSlv, VSsSemEnv *semEnv ) - { VSsSemData *semData; +//inline +void +handleDissipate( SlaveVP *requestingSlv, VSsLangEnv *langEnv ) + { VSsTaskStub *parentTaskStub, *ownTaskStub; DEBUG__printf1(dbgRqstHdlr,"Dissipate request from processor %d", - requestingSlv->slaveID) + requestingSlv->slaveNum) - ownTaskStub = PR_PI__give_lang_meta_task( requestingSlv, VSs_MAGIC_NUMBER ); + ownTaskStub = PR_PI__give_lang_meta_task_from_slave__ML( requestingSlv, VSs_MAGIC_NUMBER ); parentTaskStub = ownTaskStub->parentTaskStub; parentTaskStub->numLiveChildThreads -= 1; //parent wasn't freed, even if ended @@ -233,7 +271,7 @@ if( parentTaskStub->isWaitingForChildTasksToEnd ) return; //still waiting on tasks (should be impossible) else //parent free to resume - resume_slaveVP( PR_PI__give_slave_assigned_to(parentTaskStub), semEnv ); + resume_slaveVP( PR_PI__give_slave_lang_meta_task_assigned_to(parentTaskStub), langEnv ); } //check if this is last child of ended parent (note, not possible to @@ -241,34 +279,44 @@ if( parentTaskStub->isEnded && parentTaskStub->numLiveChildTasks == 0 && parentTaskStub->numLiveChildThreads == 0 ) - { free_task_stub( parentTaskStub ); //just stub, semData already freed + { free_task_stub( parentTaskStub ); //just stub, langData already freed } FreeSlaveStateAndReturn: - //Used to free the semData and requesting slave's base state, but - // now PR does those things, so nothing more to do.. -//PR handles this: PR_PI__free( semData ); -//PR handles this: PR_PI__dissipate_slaveVP( requestingSlv ); + //PR frees the langData, task stub and requesting slave's base state + return; + } +inline +void +handleShutdownDissipate( SlaveVP *requestingSlv, VSsLangEnv *langEnv ) + { + VSsTaskStub *ownTaskStub; + + ownTaskStub = PR_PI__give_lang_meta_task_from_slave__ML( requestingSlv, VSs_MAGIC_NUMBER ); + free_task_stub( ownTaskStub ); + + //PR frees the langData, task stub and requesting slave's base state return; } /*Register this with PR, during VSs start * - *At some point, may change PR so that it recycles semData, in which case this + *At some point, may change PR so that it recycles langData, in which case this * only gets called when a process shuts down.. at that point, PR will call * dissipate on all the slaves it has in the recycle Q. */ void -freeVSsSemData( void *_semData ) +freeVSsLangData( void *_langData ) { // - PR_PI__free( _semData ); + PR_PI__free( _langData ); } -void resetVSsSemData( void *_semData ) - { VSsSemData *semData = (VSsSemData *)_semData; +void +resetVSsLangData( void *_langData ) + { VSsLangData *langData = (VSsLangData *)_langData; - semData->highestTransEntered = -1; - semData->lastTransEntered = NULL; + langData->highestTransEntered = -1; + langData->lastTransEntered = NULL; } //========================================================================== @@ -279,12 +327,12 @@ *PR creates a PRMetaTask and passes it in. This handler adds language- * specific stuff to it. The language-specific stuff is linked to the * PRMetaTask, but if the task is suspended for any reason, the lang-specific - * part is moved to the semData of the slave that is animating the task. + * part is moved to the langData of the slave that is animating the task. *So, while the PRMetaTask is inside the creating language's semantic * env, waiting to be assigned to a slave for animation, the lang-specific * task info is accessed from the PRMetaTask. But once the task suspends, - * that lang-specific task info transfers to the slave's semData. All lang - * constructs that want to access it must get it from the semData. + * that lang-specific task info transfers to the slave's langData. All lang + * constructs that want to access it must get it from the langData. *However, taskEnd still accesses the lang-specific task info from the * PRMetaTask, whether it suspended or not.. and the task code can access * data to be used within the application behavior via @@ -354,9 +402,9 @@ * decide garbage collection of no-longer-used pointers later) * */ -inline +//inline void * -handleSubmitTask( VSsSemReq *semReq, VSsSemEnv *semEnv ) +handleSubmitTask( VSsLangReq *langReq, VSsLangEnv *langEnv ) { uint32 key[3]; HashEntry *rawHashEntry; //has char *, but use with uint32 * VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer @@ -366,7 +414,7 @@ VSsTaskStubCarrier *taskCarrier; HashTable * - argPtrHashTbl = semEnv->argPtrHashTbl; + argPtrHashTbl = langEnv->argPtrHashTbl; /* ========================== creation ========================== @@ -376,19 +424,19 @@ * inputs from the sequential portion. Note that all controlled arguments * are pointers, and marked as controlled in the application code). */ - args = semReq->args; - taskType = semReq->taskType; //this is VSs task type struct + args = langReq->args; + taskType = langReq->taskType; //this is VSs task type struct taskStub = create_task_stub( taskType, args );//copies arg ptrs taskStub->numBlockingProp = taskType->numCtldArgs; - //PR does this (metaTask contains taskID): taskStub->taskID = semReq->taskID; + //PR does this (metaTask contains taskID): taskStub->taskID = langReq->taskID; - parentTaskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task(semReq->callingSlv, VSs_MAGIC_NUMBER); + parentTaskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task_from_slave__ML(langReq->callingSlv, VSs_MAGIC_NUMBER); taskStub->parentTaskStub = parentTaskStub; parentTaskStub->numLiveChildTasks += 1; - //DEBUG__printf3(dbgRqstHdlr,"Submit req from slaveID: %d, from task: %d, for task: %d", semReq->callingSlv->slaveID, parentSemData->taskStub->taskID[1], taskStub->taskID[1]) - DEBUG__printf2(dbgRqstHdlr,"Submit req from slaveID: %d, for task: %d", semReq->callingSlv->slaveID, taskStub->taskID[1]) + //DEBUG__printf3(dbgRqstHdlr,"Submit req from slaveNum: %d, from task: %d, for task: %d", langReq->callingSlv->slaveNum, parentLangData->taskStub->taskID[1], taskStub->taskID[1]) +// DEBUG__printf2(dbgRqstHdlr,"Submit req from slaveNum: %d, for task: %d", langReq->callingSlv->slaveNum, taskStub->taskID[1]) /*=============== Process args ================= *The controlled arguments are processed one by one. @@ -431,9 +479,8 @@ * the hash-entry's count of enabled and non-finished readers.*/ taskStub->numBlockingProp -= 1; if( taskStub->numBlockingProp == 0 ) - { writePrivQ( taskStub, semEnv->taskReadyQ ); - if( semEnv->protoSemEnv->hasWork != TRUE ) - semEnv->protoSemEnv->hasWork = TRUE; + { writePrivQ( taskStub, langEnv->taskReadyQ ); + PR_int__set_work_in_lang_env( langEnv ); } ptrEntry->numEnabledNonDoneReaders += 1; } @@ -456,9 +503,8 @@ * into the readyQ.*/ taskStub->numBlockingProp -= 1; if( taskStub->numBlockingProp == 0 ) - { writePrivQ( taskStub, semEnv->taskReadyQ ); - if( semEnv->protoSemEnv->hasWork != TRUE ) - semEnv->protoSemEnv->hasWork = TRUE; + { writePrivQ( taskStub, langEnv->taskReadyQ ); + PR_int__set_work_in_lang_env( langEnv ); } ptrEntry->hasEnabledNonFinishedWriter = TRUE; } @@ -471,9 +517,9 @@ } //for argNum //resume the parent, creator - resume_slaveVP( semReq->callingSlv, semEnv ); + resume_slaveVP( langReq->callingSlv, langEnv ); - return; + return taskStub; } @@ -512,25 +558,24 @@ *TODO: Might be safe to delete an entry when task ends and waiterQ empty * and no readers and no writers.. */ -inline void -handleEndTask( void *langMetaTask, VSsSemReq *semReq, VSsSemEnv *semEnv ) +//inline +void +handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) { VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer void **args; - VSsSemData *endingSlvSemData; VSsTaskStub *endingTaskStub, *waitingTaskStub, *parentStub; VSsTaskType *endingTaskType; VSsTaskStubCarrier *waitingTaskCarrier; VSsPointerEntry **ptrEntries; - -// endingTaskStub = (VSsTaskStub *)PR_PI__give_lang_spec_task_info( semReq->callingSlv ); - - endingTaskStub = (VSsTaskStub *)langMetaTask; + endingTaskStub = + (VSsTaskStub *)PR_int__give_lang_meta_task_from_slave__ML( requestingSlv, VSs_MAGIC_NUMBER ); + args = endingTaskStub->args; endingTaskType = endingTaskStub->taskType; ptrEntries = endingTaskStub->ptrEntries; //saved in stub when create - DEBUG__printf2(dbgRqstHdlr,"EndTask req from slaveID: %d, task: %d",semReq->callingSlv->slaveID, endingTaskStub->taskID[1]) +// DEBUG__printf2(dbgRqstHdlr,"EndTask req from slaveNum: %d, task: %d",langReq->callingSlv->slaveNum, endingTaskStub->taskID[1]) //"wait" functionality: Check if parent was waiting on this task parentStub = endingTaskStub->parentTaskStub; @@ -539,7 +584,7 @@ parentStub->numLiveChildTasks == 0) { parentStub->isWaitingForChildTasksToEnd = FALSE; - resume_slaveVP( PR_PI__give_slave_assigned_to(parentStub), semEnv ); + resume_slaveVP( PR_PI__give_slave_lang_meta_task_assigned_to(parentStub), langEnv ); } //Check if parent ended, and this was last descendent, then free it @@ -583,9 +628,8 @@ // task-stub into the readyQ. waitingTaskStub->numBlockingProp -= 1; if( waitingTaskStub->numBlockingProp == 0 ) - { writePrivQ( waitingTaskStub, semEnv->taskReadyQ ); - if( semEnv->protoSemEnv->hasWork != TRUE ) - semEnv->protoSemEnv->hasWork = TRUE; + { writePrivQ( waitingTaskStub, langEnv->taskReadyQ ); + PR_int__set_work_in_lang_env( langEnv ); } } } @@ -609,9 +653,8 @@ // If it becomes zero, then put the task-stub into the readyQ. waitingTaskStub->numBlockingProp -= 1; if( waitingTaskStub->numBlockingProp == 0 ) - { writePrivQ( waitingTaskStub, semEnv->taskReadyQ ); - if( semEnv->protoSemEnv->hasWork != TRUE ) - semEnv->protoSemEnv->hasWork = TRUE; + { writePrivQ( waitingTaskStub, langEnv->taskReadyQ ); + PR_int__set_work_in_lang_env( langEnv ); } } else @@ -627,9 +670,8 @@ // into the readyQ. waitingTaskStub->numBlockingProp -= 1; if( waitingTaskStub->numBlockingProp == 0 ) - { writePrivQ( waitingTaskStub, semEnv->taskReadyQ ); - if( semEnv->protoSemEnv->hasWork != TRUE ) - semEnv->protoSemEnv->hasWork = TRUE; + { writePrivQ( waitingTaskStub, langEnv->taskReadyQ ); + PR_int__set_work_in_lang_env( langEnv ); } //Get next waiting task waitingTaskCarrier = peekPrivQ( ptrEntry->waitersQ ); @@ -653,8 +695,59 @@ return; } +//inline +void +handleFreeTask( void *langMetaTask ) + { VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer + void **args; + VSsTaskStub *endingTaskStub, *waitingTaskStub; + VSsTaskType *endingTaskType; + VSsTaskStubCarrier *waitingTaskCarrier; + VSsPointerEntry **ptrEntries; + + + endingTaskStub = (VSsTaskStub *)langMetaTask; + args = endingTaskStub->args; + endingTaskType = endingTaskStub->taskType; + ptrEntries = endingTaskStub->ptrEntries; //saved in stub when create + + + //Now, update state of dependents and start ready tasks + /*The task's controlled arguments are processed one by one. + *Processing an argument means getting arg-pointer's entry. + */ + int32 argNum; + for( argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++ ) + { + ptrEntry = ptrEntries[argNum]; + while( TRUE ) + { + waitingTaskCarrier = readPrivQ( ptrEntry->waitersQ ); + if( waitingTaskCarrier == NULL ) + { freePrivQ( ptrEntry->waitersQ ); + PR_int__free( ptrEntry ); + continue; //next iter of for loop + } + else + { waitingTaskStub = waitingTaskCarrier->taskStub; + PR_int__free( waitingTaskCarrier ); -inline void + //Decrement the blocking propendents count of the reader's + // task-stub. If it reaches zero, then put the task-stub + // into the readyQ. + waitingTaskStub->numBlockingProp -= 1; + if( waitingTaskStub->numBlockingProp == 0 ) + { //last ptrEntry holding the task, so free it + free_task_stub( endingTaskStub ); + } + } + }// + }//for argnum in ending task + } + + +//inline +void free_task_stub( VSsTaskStub *stubToFree ) { if(stubToFree->ptrEntries != NULL ) //a thread stub has NULL entry { PR_PI__free( stubToFree->ptrEntries ); @@ -667,7 +760,7 @@ //============================ Send Handlers ============================== -/*Send of Type -- The semantic request has the receiving task ID and Type +/*Send of Type -- The lang request has the receiving task ID and Type * *Messages of a given Type have to be kept separate.. so need a separate * entry in the hash table for each pair: receiverID, Type @@ -677,19 +770,20 @@ * separate tasks can send to the same receiver, and doing hash on the * receive task, so they will stack up. */ -inline void -handleSendTypeTo( VSsSemReq *semReq, VSsSemEnv *semEnv ) +//inline +void +handleSendTypeTo( VSsLangReq *langReq, VSsLangEnv *langEnv ) { SlaveVP *senderSlv, *receiverSlv; int32 *senderID, *receiverID; int32 *key, keySz, receiverIDNumInt; - VSsSemReq *waitingReq; + VSsLangReq *waitingReq; HashEntry *entry; - HashTable *commHashTbl = semEnv->commHashTbl; + HashTable *commHashTbl = langEnv->commHashTbl; - receiverID = semReq->receiverID; //For "send", know both send & recv procrs - senderSlv = semReq->senderSlv; + receiverID = langReq->receiverID; //For "send", know both send & recv procrs + senderSlv = langReq->senderSlv; - DEBUG__printf2(dbgRqstHdlr,"SendType req from sender slaveID: %d, recTask: %d", senderSlv->slaveID, receiverID[1]) + DEBUG__printf2(dbgRqstHdlr,"SendType req from sender slaveNum: %d, recTask: %d", senderSlv->slaveNum, receiverID[1]) receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself @@ -697,15 +791,15 @@ key = PR_PI__malloc( keySz ); key[0] = receiverIDNumInt + 1; //loc 0 is num int32 in key memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) ); - key[ 1 + receiverIDNumInt ] = semReq->msgType; + key[ 1 + receiverIDNumInt ] = langReq->msgType; - entry = giveEntryElseInsertReqst32( key, semReq, commHashTbl ); + entry = giveEntryElseInsertReqst32( key, langReq, commHashTbl ); if( entry == NULL ) //was just inserted, means task has to wait { return; } //if here, found a waiting request with same key - waitingReq = (VSsSemReq *)entry->content; + waitingReq = (VSsLangReq *)entry->content; //At this point, know have waiting request(s) -- either sends or recv //Note, can only have max of one receive waiting, and cannot have both @@ -714,7 +808,7 @@ if( waitingReq->reqType == send_type_to ) { //waiting request is another send, so stack this up on list // but first clone the sending request so it persists. - VSsSemReq *clonedReq = cloneReq( semReq ); + VSsLangReq *clonedReq = cloneReq( langReq ); clonedReq-> nextReqInHashEntry = waitingReq->nextReqInHashEntry; waitingReq->nextReqInHashEntry = clonedReq; DEBUG__printf2( dbgRqstHdlr, "linked requests: %p, %p ", clonedReq,\ @@ -725,26 +819,26 @@ { #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC Dependency newD; - newD.from_vp = senderID->slaveID; + newD.from_vp = senderID->slaveNum; newD.from_task = senderID->numTimesAssignedToASlot; - newD.to_vp = receiverID->slaveID; + newD.to_vp = receiverID->slaveNum; newD.to_task = receiverID->numTimesAssignedToASlot +1; - //(newD,semEnv->commDependenciesList); - addToListOfArrays(Dependency,newD,semEnv->dynDependenciesList); - int32 groupId = semReq->msgType; - if(semEnv->ntonGroupsInfo->numInArray <= groupId){ - makeHighestDynArrayIndexBeAtLeast(semEnv->ntonGroupsInfo, groupId); + //(newD,langEnv->commDependenciesList); + addToListOfArrays(Dependency,newD,langEnv->dynDependenciesList); + int32 groupId = langReq->msgType; + if(langEnv->ntonGroupsInfo->numInArray <= groupId){ + makeHighestDynArrayIndexBeAtLeast(langEnv->ntonGroupsInfo, groupId); } - if(semEnv->ntonGroups[groupId] == NULL){ - semEnv->ntonGroups[groupId] = new_NtoN(groupId); + if(langEnv->ntonGroups[groupId] == NULL){ + langEnv->ntonGroups[groupId] = new_NtoN(groupId); } Unit u; - u.vp = senderID->slaveID; + u.vp = senderID->slaveNum; u.task = senderID->numTimesAssignedToASlot; - addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->senders); - u.vp = receiverID->slaveID; + addToListOfArrays(Unit,u,langEnv->ntonGroups[groupId]->senders); + u.vp = receiverID->slaveNum; u.task = receiverID->numTimesAssignedToASlot +1; - addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->receivers); + addToListOfArrays(Unit,u,langEnv->ntonGroups[groupId]->receivers); #endif //set receiver slave, from the waiting request @@ -763,11 +857,11 @@ //attach msg that's in this send request to receiving task's Slv // when comes back from suspend will have msg in dataRetFromReq - receiverSlv->dataRetFromReq = semReq->msg; + receiverSlv->dataRetFromReq = langReq->msg; //bring both processors back from suspend - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + resume_slaveVP( senderSlv, langEnv ); + resume_slaveVP( receiverSlv, langEnv ); return; } @@ -782,21 +876,22 @@ *Looks like can make single handler for both kinds of send.. */ //TODO: combine both send handlers into single handler -inline void -handleSendFromTo( VSsSemReq *semReq, VSsSemEnv *semEnv) +//inline +void +handleSendFromTo( VSsLangReq *langReq, VSsLangEnv *langEnv) { SlaveVP *senderSlv, *receiverSlv; int32 *senderID, *receiverID; int32 *key, keySz, receiverIDNumInt, senderIDNumInt; - VSsSemReq *waitingReq; + VSsLangReq *waitingReq; HashEntry *entry; - HashTable *commHashTbl = semEnv->commHashTbl; + HashTable *commHashTbl = langEnv->commHashTbl; DEBUG__printf2(dbgRqstHdlr,"SendFromTo req from task %d to %d", - semReq->senderID[1],semReq->receiverID[1]) + langReq->senderID[1],langReq->receiverID[1]) - receiverID = semReq->receiverID; //For "send", know both send & recv procrs - senderID = semReq->senderID; - senderSlv = semReq->senderSlv; + receiverID = langReq->receiverID; //For "send", know both send & recv procrs + senderID = langReq->senderID; + senderSlv = langReq->senderSlv; receiverIDNumInt = receiverID[0] + 1; //include the count in the key @@ -807,12 +902,12 @@ memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) ); memcpy( &key[1 + receiverIDNumInt], senderID, senderIDNumInt * sizeof(int32) ); - entry = giveEntryElseInsertReqst32( key, semReq, commHashTbl ); + entry = giveEntryElseInsertReqst32( key, langReq, commHashTbl ); if( entry == NULL ) //was just inserted, means task has to wait { return; } - waitingReq = (VSsSemReq *)entry->content; + waitingReq = (VSsLangReq *)entry->content; //At this point, know have waiting request(s) -- either sends or recv if( waitingReq->reqType == send_from_to ) @@ -822,12 +917,12 @@ { //waiting request is a receive, so it completes pair with this send #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC Dependency newD; - newD.from_vp = sendPr->slaveID; + newD.from_vp = sendPr->slaveNum; newD.from_task = sendPr->numTimesAssignedToASlot; - newD.to_vp = receivePr->slaveID; + newD.to_vp = receivePr->slaveNum; newD.to_task = receivePr->numTimesAssignedToASlot +1; - //addToListOfArraysDependency(newD,semEnv->commDependenciesList); - addToListOfArrays(Dependency,newD,semEnv->commDependenciesList); + //addToListOfArraysDependency(newD,langEnv->commDependenciesList); + addToListOfArrays(Dependency,newD,langEnv->commDependenciesList); #endif //set receiver slave, from the waiting request @@ -846,11 +941,11 @@ //attach msg that's in this send request to receiving procr // when comes back from suspend, will have msg in dataRetFromReq - receiverSlv->dataRetFromReq = semReq->msg; + receiverSlv->dataRetFromReq = langReq->msg; //bring both processors back from suspend - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + resume_slaveVP( senderSlv, langEnv ); + resume_slaveVP( receiverSlv, langEnv ); return; } @@ -862,19 +957,20 @@ // -inline void -handleReceiveTypeTo( VSsSemReq *semReq, VSsSemEnv *semEnv) +//inline +void +handleReceiveTypeTo( VSsLangReq *langReq, VSsLangEnv *langEnv) { SlaveVP *senderSlv, *receiverSlv; int32 *receiverID; int32 *key, keySz, receiverIDNumInt; - VSsSemReq *waitingReq; + VSsLangReq *waitingReq; HashEntry *entry; - HashTable *commHashTbl = semEnv->commHashTbl; + HashTable *commHashTbl = langEnv->commHashTbl; - DEBUG__printf2(dbgRqstHdlr,"ReceiveType req to ID: %d type: %d",semReq->receiverID[1], semReq->msgType) + DEBUG__printf2(dbgRqstHdlr,"ReceiveType req to ID: %d type: %d",langReq->receiverID[1], langReq->msgType) - receiverID = semReq->receiverID; //For "send", know both send & recv procrs - receiverSlv = semReq->receiverSlv; + receiverID = langReq->receiverID; //For "send", know both send & recv procrs + receiverSlv = langReq->receiverSlv; //key is the receiverID plus the type -- have to copy them into key @@ -883,14 +979,14 @@ key = PR_PI__malloc( keySz ); key[0] = receiverIDNumInt + 1; //loc 0 is num int32s in key memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) ); - key[ 1 + receiverIDNumInt ] = semReq->msgType; + key[ 1 + receiverIDNumInt ] = langReq->msgType; - entry = giveEntryElseInsertReqst32( key, semReq, commHashTbl );//clones + entry = giveEntryElseInsertReqst32( key, langReq, commHashTbl );//clones if( entry == NULL ) //was just inserted, means task has to wait { return; } - waitingReq = (VSsSemReq *)entry->content; //previously cloned by insert + waitingReq = (VSsLangReq *)entry->content; //previously cloned by insert //At this point, know have waiting request(s) -- should be send(s) if( waitingReq->reqType == send_type_to ) @@ -914,30 +1010,30 @@ #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC Dependency newD; - newD.from_vp = sendPr->slaveID; + newD.from_vp = sendPr->slaveNum; newD.from_task = sendPr->numTimesAssignedToASlot; - newD.to_vp = receivePr->slaveID; + newD.to_vp = receivePr->slaveNum; newD.to_task = receivePr->numTimesAssignedToASlot +1; - //addToListOfArraysDependency(newD,semEnv->commDependenciesList); - addToListOfArrays(Dependency,newD,semEnv->dynDependenciesList); - int32 groupId = semReq->msgType; - if(semEnv->ntonGroupsInfo->numInArray <= groupId){ - makeHighestDynArrayIndexBeAtLeast(semEnv->ntonGroupsInfo, groupId); + //addToListOfArraysDependency(newD,langEnv->commDependenciesList); + addToListOfArrays(Dependency,newD,langEnv->dynDependenciesList); + int32 groupId = langReq->msgType; + if(langEnv->ntonGroupsInfo->numInArray <= groupId){ + makeHighestDynArrayIndexBeAtLeast(langEnv->ntonGroupsInfo, groupId); } - if(semEnv->ntonGroups[groupId] == NULL){ - semEnv->ntonGroups[groupId] = new_NtoN(groupId); + if(langEnv->ntonGroups[groupId] == NULL){ + langEnv->ntonGroups[groupId] = new_NtoN(groupId); } Unit u; - u.vp = sendPr->slaveID; + u.vp = sendPr->slaveNum; u.task = sendPr->numTimesAssignedToASlot; - addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->senders); - u.vp = receivePr->slaveID; + addToListOfArrays(Unit,u,langEnv->ntonGroups[groupId]->senders); + u.vp = receivePr->slaveNum; u.task = receivePr->numTimesAssignedToASlot +1; - addToListOfArrays(Unit,u,semEnv->ntonGroups[groupId]->receivers); + addToListOfArrays(Unit,u,langEnv->ntonGroups[groupId]->receivers); #endif - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + resume_slaveVP( senderSlv, langEnv ); + resume_slaveVP( receiverSlv, langEnv ); return; } @@ -947,20 +1043,21 @@ /* */ -inline void -handleReceiveFromTo( VSsSemReq *semReq, VSsSemEnv *semEnv) +//inline +void +handleReceiveFromTo( VSsLangReq *langReq, VSsLangEnv *langEnv) { SlaveVP *senderSlv, *receiverSlv; int32 *senderID, *receiverID; int32 *key, keySz, receiverIDNumInt, senderIDNumInt; - VSsSemReq *waitingReq; + VSsLangReq *waitingReq; HashEntry *entry; - HashTable *commHashTbl = semEnv->commHashTbl; + HashTable *commHashTbl = langEnv->commHashTbl; - DEBUG__printf2(dbgRqstHdlr,"RecFromTo req from ID: %d to ID: %d",semReq->senderID[1],semReq->receiverID[1]) + DEBUG__printf2(dbgRqstHdlr,"RecFromTo req from ID: %d to ID: %d",langReq->senderID[1],langReq->receiverID[1]) - receiverID = semReq->receiverID; //For "send", know both send & recv procrs - senderID = semReq->senderID; - receiverSlv = semReq->receiverSlv; + receiverID = langReq->receiverID; //For "send", know both send & recv procrs + senderID = langReq->senderID; + receiverSlv = langReq->receiverSlv; receiverIDNumInt = receiverID[0] + 1; //pos 0 doesn't include itself senderIDNumInt = senderID[0] + 1; @@ -970,24 +1067,24 @@ memcpy( &key[1], receiverID, receiverIDNumInt * sizeof(int32) ); memcpy( &key[1 + receiverIDNumInt], senderID, senderIDNumInt * sizeof(int32)); - entry = giveEntryElseInsertReqst32( key, semReq, commHashTbl ); + entry = giveEntryElseInsertReqst32( key, langReq, commHashTbl ); if( entry == NULL ) //was just inserted, means task has to wait { return; } - waitingReq = (VSsSemReq *)entry->content; + waitingReq = (VSsLangReq *)entry->content; //At this point, know have a request to rendez-vous -- should be send if( waitingReq->reqType == send_from_to ) { //waiting request is a send, so pair it with this receive #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC Dependency newD; - newD.from_vp = sendPr->slaveID; + newD.from_vp = sendPr->slaveNum; newD.from_task = sendPr->numTimesAssignedToASlot; - newD.to_vp = receivePr->slaveID; + newD.to_vp = receivePr->slaveNum; newD.to_task = receivePr->numTimesAssignedToASlot +1; - //addToListOfArraysDependency(newD,semEnv->commDependenciesList); - addToListOfArrays(Dependency,newD,semEnv->commDependenciesList); + //addToListOfArraysDependency(newD,langEnv->commDependenciesList); + addToListOfArrays(Dependency,newD,langEnv->commDependenciesList); #endif //have receiver slave, now set sender slave @@ -1005,8 +1102,8 @@ //bring both processors back from suspend PR_PI__free( waitingReq ); - resume_slaveVP( senderSlv, semEnv ); - resume_slaveVP( receiverSlv, semEnv ); + resume_slaveVP( senderSlv, langEnv ); + resume_slaveVP( receiverSlv, langEnv ); return; } @@ -1017,18 +1114,19 @@ /*Waits for all tasks that are direct children to end, then resumes calling * task or thread */ -inline void -handleTaskwait( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) +//inline +void +handleTaskwait( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) { VSsTaskStub* taskStub; DEBUG__printf1(dbgRqstHdlr,"Taskwait request from processor %d", - requestingSlv->slaveID) + requestingSlv->slaveNum) - taskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task( requestingSlv, VSs_MAGIC_NUMBER); + taskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task_from_slave__ML( requestingSlv, VSs_MAGIC_NUMBER); if( taskStub->numLiveChildTasks == 0 ) { //nobody to wait for, resume - resume_slaveVP( requestingSlv, semEnv ); + resume_slaveVP( requestingSlv, langEnv ); } else //have to wait, mark waiting { @@ -1041,24 +1139,24 @@ /* */ void -handleMalloc( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv ) +handleMalloc( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) { void *ptr; - DEBUG__printf1(dbgRqstHdlr,"Malloc request from processor %d",requestingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"Malloc request from processor %d",requestingSlv->slaveNum) - ptr = PR_PI__malloc( semReq->sizeToMalloc ); + ptr = PR_PI__malloc( langReq->sizeToMalloc ); requestingSlv->dataRetFromReq = ptr; - resume_slaveVP( requestingSlv, semEnv ); + resume_slaveVP( requestingSlv, langEnv ); } /* */ void -handleFree( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv ) +handleFree( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) { - DEBUG__printf1(dbgRqstHdlr,"Free request from processor %d",requestingSlv->slaveID) - PR_PI__free( semReq->ptrToFree ); - resume_slaveVP( requestingSlv, semEnv ); + DEBUG__printf1(dbgRqstHdlr,"Free request from processor %d",requestingSlv->slaveNum) + PR_PI__free( langReq->ptrToFree ); + resume_slaveVP( requestingSlv, langEnv ); } @@ -1067,14 +1165,15 @@ /*Uses ID as index into array of flags. If flag already set, resumes from * end-label. Else, sets flag and resumes normally. */ -void inline +void +//inline handleStartSingleton_helper( VSsSingleton *singleton, SlaveVP *reqstingSlv, - VSsSemEnv *semEnv ) + VSsLangEnv *langEnv ) { if( singleton->hasFinished ) { //the code that sets the flag to true first sets the end instr addr reqstingSlv->dataRetFromReq = singleton->endInstrAddr; - resume_slaveVP( reqstingSlv, semEnv ); + resume_slaveVP( reqstingSlv, langEnv ); return; } else if( singleton->hasBeenStarted ) @@ -1086,42 +1185,45 @@ { //hasn't been started, so this is the first attempt at the singleton singleton->hasBeenStarted = TRUE; reqstingSlv->dataRetFromReq = 0x0; - resume_slaveVP( reqstingSlv, semEnv ); + resume_slaveVP( reqstingSlv, langEnv ); return; } } -void inline -handleStartFnSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ) +void +//inline +handleStartFnSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ) { VSsSingleton *singleton; - DEBUG__printf1(dbgRqstHdlr,"StartFnSingleton request from processor %d",requestingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"StartFnSingleton request from processor %d",requestingSlv->slaveNum) - singleton = &(semEnv->fnSingletons[ semReq->singletonID ]); - handleStartSingleton_helper( singleton, requestingSlv, semEnv ); + singleton = &(langEnv->fnSingletons[ langReq->singletonID ]); + handleStartSingleton_helper( singleton, requestingSlv, langEnv ); } -void inline -handleStartDataSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ) +void +//inline +handleStartDataSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ) { VSsSingleton *singleton; - DEBUG__printf1(dbgRqstHdlr,"StartDataSingleton request from processor %d",requestingSlv->slaveID) - if( *(semReq->singletonPtrAddr) == NULL ) + DEBUG__printf1(dbgRqstHdlr,"StartDataSingleton request from processor %d",requestingSlv->slaveNum) + if( *(langReq->singletonPtrAddr) == NULL ) { singleton = PR_PI__malloc( sizeof(VSsSingleton) ); singleton->waitQ = makePRQ(); singleton->endInstrAddr = 0x0; singleton->hasBeenStarted = FALSE; singleton->hasFinished = FALSE; - *(semReq->singletonPtrAddr) = singleton; + *(langReq->singletonPtrAddr) = singleton; } else - singleton = *(semReq->singletonPtrAddr); - handleStartSingleton_helper( singleton, requestingSlv, semEnv ); + singleton = *(langReq->singletonPtrAddr); + handleStartSingleton_helper( singleton, requestingSlv, langEnv ); } -void inline +void +//inline handleEndSingleton_helper( VSsSingleton *singleton, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ) + VSsLangEnv *langEnv ) { PrivQueueStruc *waitQ; int32 numWaiting, i; SlaveVP *resumingSlv; @@ -1139,33 +1241,33 @@ { //they will resume inside start singleton, then jmp to end singleton resumingSlv = readPrivQ( waitQ ); resumingSlv->dataRetFromReq = singleton->endInstrAddr; - resume_slaveVP( resumingSlv, semEnv ); + resume_slaveVP( resumingSlv, langEnv ); } - resume_slaveVP( requestingSlv, semEnv ); + resume_slaveVP( requestingSlv, langEnv ); } -void inline -handleEndFnSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ) +void +handleEndFnSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ) { VSsSingleton *singleton; - DEBUG__printf1(dbgRqstHdlr,"EndFnSingleton request from processor %d",requestingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"EndFnSingleton request from processor %d",requestingSlv->slaveNum) - singleton = &(semEnv->fnSingletons[ semReq->singletonID ]); - handleEndSingleton_helper( singleton, requestingSlv, semEnv ); + singleton = &(langEnv->fnSingletons[ langReq->singletonID ]); + handleEndSingleton_helper( singleton, requestingSlv, langEnv ); } -void inline -handleEndDataSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ) +void +handleEndDataSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ) { VSsSingleton *singleton; - DEBUG__printf1(dbgRqstHdlr,"EndDataSingleton request from processor %d",requestingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"EndDataSingleton request from processor %d",requestingSlv->slaveNum) - singleton = *(semReq->singletonPtrAddr); - handleEndSingleton_helper( singleton, requestingSlv, semEnv ); + singleton = *(langReq->singletonPtrAddr); + handleEndSingleton_helper( singleton, requestingSlv, langEnv ); } @@ -1173,11 +1275,11 @@ * pointer out of the request and call it, then resume the VP. */ void -handleAtomic( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv ) +handleAtomic( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) { - DEBUG__printf1(dbgRqstHdlr,"Atomic request from processor %d",requestingSlv->slaveID) - semReq->fnToExecInMaster( semReq->dataForFn ); - resume_slaveVP( requestingSlv, semEnv ); + DEBUG__printf1(dbgRqstHdlr,"Atomic request from processor %d",requestingSlv->slaveNum) + langReq->fnToExecInMaster( langReq->dataForFn ); + resume_slaveVP( requestingSlv, langEnv ); } /*First, it looks at the VP's semantic data, to see the highest transactionID @@ -1195,35 +1297,35 @@ *If NULL, then write requesting into the field and resume. */ void -handleTransStart( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ) - { VSsSemData *semData; +handleTransStart( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ) + { VSsLangData *langData; TransListElem *nextTransElem; - DEBUG__printf1(dbgRqstHdlr,"TransStart request from processor %d",requestingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"TransStart request from processor %d",requestingSlv->slaveNum) //check ordering of entering transactions is correct - semData = requestingSlv->semanticData; - if( semData->highestTransEntered > semReq->transID ) + langData = requestingSlv->langData; + if( langData->highestTransEntered > langReq->transID ) { //throw PR exception, which shuts down PR. PR_PI__throw_exception( "transID smaller than prev", requestingSlv, NULL); } //add this trans ID to the list of transactions entered -- check when // end a transaction - semData->highestTransEntered = semReq->transID; + langData->highestTransEntered = langReq->transID; nextTransElem = PR_PI__malloc( sizeof(TransListElem) ); - nextTransElem->transID = semReq->transID; - nextTransElem->nextTrans = semData->lastTransEntered; - semData->lastTransEntered = nextTransElem; + nextTransElem->transID = langReq->transID; + nextTransElem->nextTrans = langData->lastTransEntered; + langData->lastTransEntered = nextTransElem; //get the structure for this transaction ID VSsTrans * - transStruc = &(semEnv->transactionStrucs[ semReq->transID ]); + transStruc = &(langEnv->transactionStrucs[ langReq->transID ]); if( transStruc->VPCurrentlyExecuting == NULL ) { transStruc->VPCurrentlyExecuting = requestingSlv; - resume_slaveVP( requestingSlv, semEnv ); + resume_slaveVP( requestingSlv, langEnv ); } else { //note, might make future things cleaner if save request with VP and @@ -1248,15 +1350,15 @@ * resume both. */ void -handleTransEnd(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv) - { VSsSemData *semData; +handleTransEnd(VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) + { VSsLangData *langData; SlaveVP *waitingSlv; VSsTrans *transStruc; TransListElem *lastTrans; - DEBUG__printf1(dbgRqstHdlr,"TransEnd request from processor %d",requestingSlv->slaveID) + DEBUG__printf1(dbgRqstHdlr,"TransEnd request from processor %d",requestingSlv->slaveNum) - transStruc = &(semEnv->transactionStrucs[ semReq->transID ]); + transStruc = &(langEnv->transactionStrucs[ langReq->transID ]); //make sure transaction ended in same VP as started it. if( transStruc->VPCurrentlyExecuting != requestingSlv ) @@ -1265,21 +1367,21 @@ } //make sure nesting is correct -- last ID entered should == this ID - semData = requestingSlv->semanticData; - lastTrans = semData->lastTransEntered; - if( lastTrans->transID != semReq->transID ) + langData = requestingSlv->langData; + lastTrans = langData->lastTransEntered; + if( lastTrans->transID != langReq->transID ) { PR_PI__throw_exception( "trans incorrectly nested", requestingSlv, NULL ); } - semData->lastTransEntered = semData->lastTransEntered->nextTrans; + langData->lastTransEntered = langData->lastTransEntered->nextTrans; waitingSlv = readPrivQ( transStruc->waitingVPQ ); transStruc->VPCurrentlyExecuting = waitingSlv; if( waitingSlv != NULL ) - resume_slaveVP( waitingSlv, semEnv ); + resume_slaveVP( waitingSlv, langEnv ); - resume_slaveVP( requestingSlv, semEnv ); + resume_slaveVP( requestingSlv, langEnv ); } diff -r a60399b62614 -r 3b30da4643d1 VSs_Request_Handlers.h --- a/VSs_Request_Handlers.h Thu Oct 18 02:44:30 2012 -0700 +++ b/VSs_Request_Handlers.h Sat Jan 12 11:31:51 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2009 OpenSourceStewardshipFoundation.org + * Copyright 2009 OpenSourceResearchInstitute.org * Licensed under GNU General Public License version 2 * * Author: seanhalle@yahoo.com @@ -14,46 +14,47 @@ /*This header defines everything specific to the VSs semantic plug-in */ +inline +void * +handleSubmitTask( VSsLangReq *langReq, VSsLangEnv *langEnv); inline void -handleSubmitTask( VSsSemReq *semReq, VSsSemEnv *semEnv); +handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); inline void -handleEndTask( VSsSemReq *semReq, VSsSemEnv *semEnv); +handleSendTypeTo( VSsLangReq *langReq, VSsLangEnv *langEnv); inline void -handleSendTypeTo( VSsSemReq *semReq, VSsSemEnv *semEnv); +handleSendFromTo( VSsLangReq *langReq, VSsLangEnv *langEnv); inline void -handleSendFromTo( VSsSemReq *semReq, VSsSemEnv *semEnv); +handleReceiveTypeTo( VSsLangReq *langReq, VSsLangEnv *langEnv); inline void -handleReceiveTypeTo( VSsSemReq *semReq, VSsSemEnv *semEnv); +handleReceiveFromTo( VSsLangReq *langReq, VSsLangEnv *langEnv); inline void -handleReceiveFromTo( VSsSemReq *semReq, VSsSemEnv *semEnv); -inline void -handleTaskwait(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv); +handleTaskwait(VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); inline void -handleMalloc( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv); +handleMalloc( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); inline void -handleFree( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv ); +handleFree( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); inline void -handleTransEnd(VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv*semEnv); +handleTransEnd(VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv*langEnv); inline void -handleTransStart( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ); +handleTransStart( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ); inline void -handleAtomic( VSsSemReq *semReq, SlaveVP *requestingSlv, VSsSemEnv *semEnv); +handleAtomic( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); inline void -handleStartFnSingleton( VSsSemReq *semReq, SlaveVP *reqstingSlv, - VSsSemEnv *semEnv ); +handleStartFnSingleton( VSsLangReq *langReq, SlaveVP *reqstingSlv, + VSsLangEnv *langEnv ); inline void -handleEndFnSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ); +handleEndFnSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ); inline void -handleStartDataSingleton( VSsSemReq *semReq, SlaveVP *reqstingSlv, - VSsSemEnv *semEnv ); +handleStartDataSingleton( VSsLangReq *langReq, SlaveVP *reqstingSlv, + VSsLangEnv *langEnv ); inline void -handleEndDataSingleton( VSsSemReq *semReq, SlaveVP *requestingSlv, - VSsSemEnv *semEnv ); +handleEndDataSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, + VSsLangEnv *langEnv ); inline void -free_task_stub( PRMetaTask *stubToFree ); +free_task_stub( VSsTaskStub *stubToFree ); #endif /* _VSs_REQ_H */ diff -r a60399b62614 -r 3b30da4643d1 VSs_SS.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VSs_SS.c Sat Jan 12 11:31:51 2013 -0800 @@ -0,0 +1,268 @@ +/* + * Copyright 2010 OpenSourceCodeStewardshipFoundation + * + * Licensed under BSD + */ + +#include +#include +#include + +#include "Queue_impl/PrivateQueue.h" +#include "Hash_impl/PrivateHash.h" + +#include "VSs.h" +#include "Measurement/VSs_Counter_Recording.h" + +//========================================================================== + + + +//=========================================================================== + +/* + */ +void +VSs__start( SlaveVP *seedSlv ) + { VSsLangEnv *langEnv; + int32 i, coreNum, slotNum; + VSsLangData *langData; + VSsTaskStub *threadTaskStub, *parentTaskStub; + + langEnv = + PR_SS__create_lang_env( sizeof(VSsLangEnv), seedSlv, VSs_MAGIC_NUMBER); + + //seed slave is a thread slave, so make a thread's task stub for it + // and then make another to stand for the seed's parent task. Make + // the parent be already ended, and have one child (the seed). This + // will make the dissipate handler do the right thing when the seed + // is dissipated. + threadTaskStub = + PR_int__create_lang_meta_task_in_slave__ML( sizeof(VSsTaskStub), seedSlv, VSs_MAGIC_NUMBER ); + + threadTaskStub->isEnded = FALSE; + threadTaskStub->isWaitingForChildTasksToEnd = FALSE; + + parentTaskStub = + PR_int__create_lang_meta_task__ML(sizeof(VSsTaskStub), seedSlv, VSs_MAGIC_NUMBER); + + parentTaskStub->isEnded = TRUE; + parentTaskStub->numLiveChildThreads = 1; //so dissipate works for seed + threadTaskStub->parentTaskStub = parentTaskStub; + //Note: threadTaskStub and parentTaskStub freed when dissipate seedSlv + + //register the langlet's handlers with PR +/* + PR_SS__register_create_task_handler( &createTaskHandler, seedVP, VSs_MAGIC_NUMBER ); + PR_SS__register_end_task_handler( &endTaskHandler, seedVP, VSs_MAGIC_NUMBER ); + PR_SS__register_create_slave_handler( &createThreadHandler, seedVP, VSs_MAGIC_NUMBER ); + PR_SS__register_dissipate_slave_handler( &endThreadHandler, seedVP, VSs_MAGIC_NUMBER ); + RequestHandler createInitialLangDataFn; + RequestHandler resetLangDataFn; +*/ + PR_SS__register_request_handler( &VSs__Request_Handler, seedSlv, VSs_MAGIC_NUMBER ); + PR_SS__register_assigner( &VSs__assign_work_to_slot, seedSlv, VSs_MAGIC_NUMBER ); + PR_SS__register_shutdown_handler( &VSs__shutdown, seedSlv, VSs_MAGIC_NUMBER ); + + #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS + _PRTopEnv->counterHandler = &VSs__counter_handler; + VSs__init_counter_data_structs(); + #endif + + + //create the ready queues, hash tables used for matching and so forth + langEnv->slavesReadyToResumeQ = makePRQ(); + langEnv->taskReadyQ = makePRQ(); + + langEnv->argPtrHashTbl = makeHashTable32( 16, &PR_int__free ); + langEnv->commHashTbl = makeHashTable32( 16, &PR_int__free ); + + langEnv->nextCoreToGetNewSlv = 0; + + + //TODO: bug -- turn these arrays into dyn arrays to eliminate limit + //langEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); + //langEnv->transactionStrucs = makeDynArrayInfo( ); + for( i = 0; i < NUM_STRUCS_IN_LANG_ENV; i++ ) + { + langEnv->fnSingletons[i].endInstrAddr = NULL; + langEnv->fnSingletons[i].hasBeenStarted = FALSE; + langEnv->fnSingletons[i].hasFinished = FALSE; + langEnv->fnSingletons[i].waitQ = makePRQ(); + langEnv->transactionStrucs[i].waitingVPQ = makePRQ(); + } + + + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC + langEnv->unitList = makeListOfArrays(sizeof(Unit),128); + langEnv->ctlDependenciesList = makeListOfArrays(sizeof(Dependency),128); + langEnv->commDependenciesList = makeListOfArrays(sizeof(Dependency),128); + langEnv->dynDependenciesList = makeListOfArrays(sizeof(Dependency),128); + langEnv->ntonGroupsInfo = makePrivDynArrayOfSize((void***)&(langEnv->ntonGroups),8); + + langEnv->hwArcs = makeListOfArrays(sizeof(Dependency),128); + memset(langEnv->last_in_slot,0,sizeof(NUM_CORES * NUM_ANIM_SLOTS * sizeof(Unit))); + #endif + } + + +/*This shuts down the langket + * Frees any memory allocated by VSs__init() and deletes any slaves or tasks + * still in ready Qs. + */ +void +VSs__shutdown( void *_langEnv ) + { VSsLangEnv *langEnv = (VSsLangEnv *)_langEnv; + + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC + //UCC + FILE* output; + int n; + char filename[255]; + for(n=0;n<255;n++) + { + sprintf(filename, "./counters/UCC.%d",n); + output = fopen(filename,"r"); + if(output) + { + fclose(output); + }else{ + break; + } + } + if(n<255){ + printf("Saving UCC to File: %s ...\n", filename); + output = fopen(filename,"w+"); + if(output!=NULL){ + set_dependency_file(output); + //fprintf(output,"digraph Dependencies {\n"); + //set_dot_file(output); + //FIXME: first line still depends on counters being enabled, replace w/ unit struct! + //forAllInDynArrayDo(_PRTopEnv->counter_history_array_info, &print_dot_node_info ); + forAllInListOfArraysDo(langEnv->unitList, &print_unit_to_file); + forAllInListOfArraysDo( langEnv->commDependenciesList, &print_comm_dependency_to_file ); + forAllInListOfArraysDo( langEnv->ctlDependenciesList, &print_ctl_dependency_to_file ); + forAllInDynArrayDo(langEnv->ntonGroupsInfo,&print_nton_to_file); + //fprintf(output,"}\n"); + fflush(output); + + } else + printf("Opening UCC file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n"); + } else { + printf("Could not open UCC file, please clean \"counters\" folder. (Must contain less than 255 files.)\n"); + } + //Loop Graph + for(n=0;n<255;n++) + { + sprintf(filename, "./counters/LoopGraph.%d",n); + output = fopen(filename,"r"); + if(output) + { + fclose(output); + }else{ + break; + } + } + if(n<255){ + printf("Saving LoopGraph to File: %s ...\n", filename); + output = fopen(filename,"w+"); + if(output!=NULL){ + set_dependency_file(output); + //fprintf(output,"digraph Dependencies {\n"); + //set_dot_file(output); + //FIXME: first line still depends on counters being enabled, replace w/ unit struct! + //forAllInDynArrayDo(_PRTopEnv->counter_history_array_info, &print_dot_node_info ); + forAllInListOfArraysDo( langEnv->unitList, &print_unit_to_file ); + forAllInListOfArraysDo( langEnv->commDependenciesList, &print_comm_dependency_to_file ); + forAllInListOfArraysDo( langEnv->ctlDependenciesList, &print_ctl_dependency_to_file ); + forAllInListOfArraysDo( langEnv->dynDependenciesList, &print_dyn_dependency_to_file ); + forAllInListOfArraysDo( langEnv->hwArcs, &print_hw_dependency_to_file ); + //fprintf(output,"}\n"); + fflush(output); + + } else + printf("Opening LoopGraph file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n"); + } else { + printf("Could not open LoopGraph file, please clean \"counters\" folder. (Must contain less than 255 files.)\n"); + } + + + freeListOfArrays(langEnv->unitList); + freeListOfArrays(langEnv->commDependenciesList); + freeListOfArrays(langEnv->ctlDependenciesList); + freeListOfArrays(langEnv->dynDependenciesList); + + #endif +#ifdef HOLISTIC__TURN_ON_PERF_COUNTERS + for(n=0;n<255;n++) + { + sprintf(filename, "./counters/Counters.%d.csv",n); + output = fopen(filename,"r"); + if(output) + { + fclose(output); + }else{ + break; + } + } + if(n<255){ + printf("Saving Counter measurements to File: %s ...\n", filename); + output = fopen(filename,"w+"); + if(output!=NULL){ + set_counter_file(output); + int i; + for(i=0;icounterList[i], &print_counter_events_to_file ); + fflush(output); + } + + } else + printf("Opening UCC file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n"); + } else { + printf("Could not open UCC file, please clean \"counters\" folder. (Must contain less than 255 files.)\n"); + } + +#endif + + //Things to free: + // tasks and slaves in ready Qs + // ready Qs + // tasks and slaves in the comm hash table + // comm hash table + // tasks in the argPtrHashTbl + // the argPtrHashTbl + PrivQueueStruc *queue; + SlaveVP *slave; + VSsTaskStub *task; + + queue = langEnv->slavesReadyToResumeQ; + slave = readPrivQ( queue ); + while( slave != NULL ) + { handleShutdownDissipate(slave); + PR_int__recycle_slave__ML( slave ); //recycler is for all of PR + slave = readPrivQ( queue ); + } + freePrivQ( queue ); + + queue = langEnv->taskReadyQ; + task = readPrivQ( queue ); + while( task != NULL ) + { handleFreeTask( task ); + task = readPrivQ( queue ); + } + freePrivQ( queue ); + + freeHashTable( langEnv->commHashTbl ); + freeHashTable( langEnv->argPtrHashTbl ); + + int32 i; + for( i = 0; i < NUM_STRUCS_IN_LANG_ENV; i++ ) + { + freePrivQ( langEnv->fnSingletons[i].waitQ ); + freePrivQ( langEnv->transactionStrucs[i].waitingVPQ ); + } + + PR_int__free_lang_env( langEnv ); + } + +