# HG changeset patch # User Merten Sach # Date 1316196508 -7200 # Node ID 0b49fd35afc1c3ab2ad01f01a4b0e10a86b0a91e # Parent a9b72021f053310b91fd3c827b71827fb0040cae distributed free working -app sends a VMSSemReqst to his Master which send a request to a different Master -Master send the request directly -The request structure is freed by the sender, when the request was handled There are still problems on shutdown. The shutdownVPs are all allocated by one Master which is likly to be terminated diff -r a9b72021f053 -r 0b49fd35afc1 MasterLoop.c --- a/MasterLoop.c Fri Sep 16 16:19:24 2011 +0200 +++ b/MasterLoop.c Fri Sep 16 20:08:28 2011 +0200 @@ -12,7 +12,8 @@ #include "VMS.h" #include "ProcrContext.h" #include "scheduling.h" -#include "inter_VMS_request_handlers.h" +#include "inter_VMS_requests.h" +#include "inter_VMS_requests_handler.h" //=========================================================================== void inline @@ -127,12 +128,23 @@ semanticEnv = masterEnv->semanticEnv; //First, check for requests from other MasterVPs, and handle them - InterMasterReqst* currReq = masterEnv->interMasterRequestsFor[thisCoresIdx]; - while(currReq) + InterMasterReqst* currReqst = masterEnv->interMasterRequestsFor[thisCoresIdx]; + while(currReqst) { - handleInterMasterReq( currReq, semanticEnv, masterPr ); - currReq = currReq->nextReqst; + handleInterMasterReq( currReqst, semanticEnv, masterPr ); + currReqst = currReqst->nextReqst; } + masterEnv->interMasterRequestsFor[thisCoresIdx] = NULL; + + //Second, check for own request that were handled for other MasterVPs + currReqst = masterEnv->interMasterRequestsSentBy[thisCoresIdx]; + while(currReqst && currReqst->obsolete) + { + InterMasterReqst *nextReqst = currReqst->nextSentReqst; + VMS__free(currReqst); + currReqst = nextReqst; + } + masterEnv->interMasterRequestsSentBy[thisCoresIdx] = currReqst; //Now, take care of the SlaveVPs //Go through the slots -- if Slave there newly suspended, handle its request @@ -228,8 +240,10 @@ { switch( currReq->reqType ) { - case transfer_free_ptr: handleTransferFree( currReq, masterPr ); - break; + case transfer_free_ptr: + handleTransferFree( currReq, masterPr ); + currReq->obsolete = 1; //now the sender can free the structure + break; default: break; } diff -r a9b72021f053 -r 0b49fd35afc1 VMS.c --- a/VMS.c Fri Sep 16 16:19:24 2011 +0200 +++ b/VMS.c Fri Sep 16 20:08:28 2011 +0200 @@ -111,6 +111,7 @@ { _VMSMasterEnv->freeListHead[i] = VMS_ext__create_free_list(); _VMSMasterEnv->interMasterRequestsFor[i] = NULL; + _VMSMasterEnv->interMasterRequestsSentBy[i] = NULL; } _VMSMasterEnv->currentMasterProcrID = 0; @@ -562,18 +563,27 @@ semReq = req->semReqData; - newProbe = VMS__malloc( sizeof(IntervalProbe) ); - newProbe->nameStr = VMS__strDup( semReq->nameStr ); - newProbe->hist = NULL; - newProbe->schedChoiceWasRecorded = FALSE; + switch(semReq->reqType){ + case createProbe: + newProbe = VMS__malloc( sizeof(IntervalProbe) ); + newProbe->nameStr = VMS__strDup( (char*)semReq->data ); + newProbe->hist = NULL; + newProbe->schedChoiceWasRecorded = FALSE; - //This runs in masterVP, so no race-condition worries - newProbe->probeID = - addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); - - requestingPr->dataRetFromReq = newProbe; - - (*resumePrFnPtr)( requestingPr, semEnv ); + //This runs in masterVP, so no race-condition worries + newProbe->probeID = + addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); + requestingPr->dataRetFromReq = newProbe; + break; + case interMasterReqst: + sendInterMasterReqst(semReq->receiverID, + (InterMasterReqst*)semReq->data); + break; + default: + break; + } + + resumePrFnPtr( requestingPr, semEnv ); } @@ -609,8 +619,13 @@ // itself //Note, should not stack-allocate initial data -- no guarantee, in // general that creating processor will outlive ones it creates. - VMS__free( animatingPr->startOfStack ); - VMS__free( animatingPr ); + + + /* + * call the core specific version, because the creating master can already be dead + */ + //VMS__free_in_lib( animatingPr->startOfStack, animatingPr ); + //VMS__free_in_lib( animatingPr, animatingPr); } @@ -771,7 +786,9 @@ //======================================================================== */ //These are the only two that use system free - VMS_ext__free_free_list( _VMSMasterEnv->freeListHead); + int i; + for(i=0; ifreeListHead[i]); free( (void *)_VMSMasterEnv ); } diff -r a9b72021f053 -r 0b49fd35afc1 VMS.h --- a/VMS.h Fri Sep 16 16:19:24 2011 +0200 +++ b/VMS.h Fri Sep 16 20:08:28 2011 +0200 @@ -18,7 +18,7 @@ #include "DynArray/DynArray.h" #include "Hash_impl/PrivateHash.h" #include "vmalloc.h" -#include "requests.h" +#include "inter_VMS_requests.h" //=============================== Debug =================================== // @@ -118,6 +118,48 @@ typedef void (*RequestHandler) ( VirtProcr *, void * ); //prWReqst, semEnv typedef void (*ResumePrFnPtr) ( VirtProcr *, void * ); +//============= Requests =========== +// + +//VMS Request is the carrier for Slave to Master requests +// it has an embedded sub-type request that is pulled out +// inside the plugin's request handler +enum VMSReqstType //For Slave->Master requests + { + semantic = 1, //avoid starting enums at 0, for debug reasons + createReq, + dissipate, + VMSSemantic //goes with VMSSemReqst below + }; + +struct _VMSReqst + { + enum VMSReqstType reqType;//used for dissipate and in future for IO requests + void *semReqData; + + VMSReqst *nextReqst; + }; +//VMSReqst + +//This is a sub-type of Slave->Master requests. +// It's for Slaves to invoke built-in VMS-core functions that have language-like +// behavior. +enum VMSSemReqstType //These are equivalent to semantic requests, but for + { // VMS's services available directly to app, like OS + createProbe = 1, // and probe services -- like a VMS-wide built-in lang + openFile, + otherIO, + interMasterReqst + }; + +typedef struct + { enum VMSSemReqstType reqType; + //VirtProcr *requestingPr; + int receiverID; //for inter master requests + void *data; + } +VMSSemReq; + //==================== Core data structures =================== @@ -149,6 +191,7 @@ int32 workStealingLock; InterMasterReqst* interMasterRequestsFor[NUM_CORES]; + InterMasterReqst* interMasterRequestsSentBy[NUM_CORES]; RequestHandler interPluginReqHdlr; int32 numProcrsCreated; //gives ordering to processor creation diff -r a9b72021f053 -r 0b49fd35afc1 inter_VMS_request_handlers.c --- a/inter_VMS_request_handlers.c Fri Sep 16 16:19:24 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright 2011 OpenSourceCodeStewardshipFoundation - * - * Licensed under GNU GPL version 2 - */ - -#include -#include - -#include "VMS.h" -#include "Queue_impl/PrivateQueue.h" -#include "Hash_impl/PrivateHash.h" -#include "vmalloc.h" - - - -//=============================== ================================= -/*The VMS__free in a different masterVP discovered the chunk it was - * given was originally allocated by this masterVP, so it sent the - * chunk over. Simply call VMS__free here. - */ -inline void -handleTransferFree( InterVMSCoreReqst *masterReq, VirtProcr *masterPr ) - { - VMS__free( masterReq->freePtr ); - } - diff -r a9b72021f053 -r 0b49fd35afc1 inter_VMS_request_handlers.h --- a/inter_VMS_request_handlers.h Fri Sep 16 16:19:24 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -/* - * Copyright 2011 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author(s): seanhalle@yahoo.com - * - */ - -#ifndef _MASTER_REQ_H -#define _MASTER_REQ_H - -/*Defines everything specific to inter-master requests that - * are internal to VMS. - *The plugin has its own handlers for inter-master requests - * sent between plugin instances. - */ - -inline void -handleTransferFree( InterVMSCoreReqst *masterReq, VirtProcr *masterPr ); - - -#endif /* _MASTER_REQ_H */ - diff -r a9b72021f053 -r 0b49fd35afc1 inter_VMS_requests.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inter_VMS_requests.c Fri Sep 16 20:08:28 2011 +0200 @@ -0,0 +1,15 @@ +#include "VMS.h" +#include "inter_VMS_requests.h" + + +void sendInterMasterReqst(int procrID, InterMasterReqst* request) +{ + request->reqType = destVMSCore; + request->obsolete = 0; + request->nextReqst = _VMSMasterEnv->interMasterRequestsFor[procrID]; + _VMSMasterEnv->interMasterRequestsFor[procrID] = request; + request->nextSentReqst = + _VMSMasterEnv->interMasterRequestsSentBy[_VMSMasterEnv->currentMasterProcrID]; + _VMSMasterEnv->interMasterRequestsSentBy[_VMSMasterEnv->currentMasterProcrID] + = request; +} \ No newline at end of file diff -r a9b72021f053 -r 0b49fd35afc1 inter_VMS_requests.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inter_VMS_requests.h Fri Sep 16 20:08:28 2011 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright 2011 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author(s): seanhalle@yahoo.com + * + */ + +#ifndef _MASTER_REQ_H +#define _MASTER_REQ_H + +typedef struct _InterMasterReqst InterMasterReqst; + +//These are for Master to Master requests +// They get re-cast to the appropriate sub-type of request +enum InterMasterReqstType //For Master->Master + { + destVMSCore = 1, //avoid starting enums at 0, for debug reasons + destPlugin + }; + +struct _InterMasterReqst //Doing a trick to save space & time -- allocate + { // space for a sub-type then cast first as InterMaster then as sub-type + enum InterMasterReqstType reqType; + InterMasterReqst *nextReqst; + InterMasterReqst *nextSentReqst; + int32 obsolete; + }; +//InterMasterReqst (defined above in typedef block) + + +//These are a sub-type of InterMaster requests. The inter-master req gets +// re-cast to be of this type, after checking +//This ones for requests between internals of VMS-core.. such as malloc +enum InterVMSCoreReqType + { + transfer_free_ptr = 1 //avoid starting enums at 0, for debug reasons + }; + +//Doing a trick to save space & time -- allocate space +// for this, cast first as InterMaster then as this +typedef struct + { + enum InterMasterReqstType reqType; //duplicate InterMasterReqst at top + InterMasterReqst *nextReqst; + InterMasterReqst *nextSentReqst; + int32 obsolete; + + enum InterVMSCoreReqType secondReqType; + void *freePtr; //pile up fields, add as needed + } InterVMSCoreReqst; + +//This is for requests between plugins on different cores +// Here, after casting, the pluginReq is extracted and handed to plugin +//Doing a trick to save space & time -- allocate space +// for this, cast first as InterMaster then as this +typedef struct + { + enum InterMasterReqstType reqType; //copy InterMasterReqst at top + InterMasterReqst *nextReqst; + + void *pluginReq; //plugin will cast to approp type + } InterPluginReqst; + + /* + * This has to be called from the MasterLoop! + * Send inter master request. The request structure has to be malloced itself. + * The sending VP will free the structure when the request is handled. + */ + void sendInterMasterReqst(int procrID, InterMasterReqst* request); + +#endif /* _MASTER_REQ_H */ + diff -r a9b72021f053 -r 0b49fd35afc1 inter_VMS_requests_handler.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inter_VMS_requests_handler.c Fri Sep 16 20:08:28 2011 +0200 @@ -0,0 +1,26 @@ +/* + * Copyright 2011 OpenSourceCodeStewardshipFoundation + * + * Licensed under GNU GPL version 2 + */ + +#include +#include + +#include "ProcrContext.h" +#include "inter_VMS_requests.h" +#include "vmalloc.h" + + + +//================================================================== +/* The VMS__free in a different masterVP discovered the chunk it was + * given was originally allocated by this masterVP, so it sent the + * chunk over. Simply call VMS__free here. + */ +inline void +handleTransferFree( InterVMSCoreReqst *masterReq, VirtProcr *masterPr ) + { + VMS__free( masterReq->freePtr ); + } + diff -r a9b72021f053 -r 0b49fd35afc1 inter_VMS_requests_handler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inter_VMS_requests_handler.h Fri Sep 16 20:08:28 2011 +0200 @@ -0,0 +1,23 @@ +/* + * Copyright 2011 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author(s): seanhalle@yahoo.com + * + */ + +#ifndef _MASTER_REQ_HANDLER_H +#define _MASTER_REQ_HANDLER_H + +/*Defines everything specific to inter-master requests that + * are internal to VMS. + *The plugin has its own handlers for inter-master requests + * sent between plugin instances. + */ + +inline void +handleTransferFree( InterVMSCoreReqst *masterReq, VirtProcr *masterPr ); + + +#endif /* _MASTER_REQ_HANDLER_H */ + diff -r a9b72021f053 -r 0b49fd35afc1 probes.c --- a/probes.c Fri Sep 16 16:19:24 2011 +0200 +++ b/probes.c Fri Sep 16 20:08:28 2011 +0200 @@ -113,7 +113,7 @@ VMSSemReq reqData; reqData.reqType = createProbe; - reqData.nameStr = nameStr; + reqData.data = (void*)nameStr; VMS__send_VMSSem_request( &reqData, animPr ); diff -r a9b72021f053 -r 0b49fd35afc1 requests.h --- a/requests.h Fri Sep 16 16:19:24 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * File: requests.h - * Author: msach - * - * Created on September 16, 2011, 3:11 PM - */ - -#ifndef REQUESTS_H -#define REQUESTS_H - -#include "ProcrContext.h" - -typedef struct _InterMasterReqst InterMasterReqst; - -//============= Requests =========== -// - -//VMS Request is the carrier for Slave to Master requests -// it has an embedded sub-type request that is pulled out -// inside the plugin's request handler -enum VMSReqstType //For Slave->Master requests - { - semantic = 1, //avoid starting enums at 0, for debug reasons - createReq, - dissipate, - VMSSemantic //goes with VMSSemReqst below - }; - -struct _VMSReqst - { - enum VMSReqstType reqType;//used for dissipate and in future for IO requests - void *semReqData; - - VMSReqst *nextReqst; - }; -//VMSReqst - -//This is a sub-type of Slave->Master requests. -// It's for Slaves to invoke built-in VMS-core functions that have language-like -// behavior. -enum VMSSemReqstType //These are equivalent to semantic requests, but for - { // VMS's services available directly to app, like OS - createProbe = 1, // and probe services -- like a VMS-wide built-in lang - openFile, - otherIO - }; - -typedef struct - { enum VMSSemReqstType reqType; - VirtProcr *requestingPr; - char *nameStr; //for create probe - } -VMSSemReq; - -//These are for Master to Master requests -// They get re-cast to the appropriate sub-type of request -enum InterMasterReqstType //For Master->Master - { - destVMSCore = 1, //avoid starting enums at 0, for debug reasons - destPlugin - }; - -struct _InterMasterReqst //Doing a trick to save space & time -- allocate - { // space for a sub-type then cast first as InterMaster then as sub-type - enum InterMasterReqstType reqType; - InterMasterReqst *nextReqst; - }; -//InterMasterReqst (defined above in typedef block) - - -//These are a sub-type of InterMaster requests. The inter-master req gets -// re-cast to be of this type, after checking -//This ones for requests between internals of VMS-core.. such as malloc -enum InterVMSCoreReqType - { - transfer_free_ptr = 1 //avoid starting enums at 0, for debug reasons - }; - -//Doing a trick to save space & time -- allocate space -// for this, cast first as InterMaster then as this -typedef struct - { - enum InterMasterReqstType reqType; //duplicate InterMasterReqst at top - InterMasterReqst *nextReqst; - - enum InterVMSCoreReqType secondReqType; - void *freePtr; //pile up fields, add as needed - } InterVMSCoreReqst; - -//This is for requests between plugins on different cores -// Here, after casting, the pluginReq is extracted and handed to plugin -//Doing a trick to save space & time -- allocate space -// for this, cast first as InterMaster then as this -typedef struct - { - enum InterMasterReqstType reqType; //copy InterMasterReqst at top - InterMasterReqst *nextReqst; - - void *pluginReq; //plugin will cast to approp type - } InterPluginReqst; - -#endif /* REQUESTS_H */ - diff -r a9b72021f053 -r 0b49fd35afc1 scheduling.h --- a/scheduling.h Fri Sep 16 16:19:24 2011 +0200 +++ b/scheduling.h Fri Sep 16 20:08:28 2011 +0200 @@ -1,6 +1,6 @@ /* * File: scheduling.h - * Author: msach + * Author: Merten Sachh * * Created on September 16, 2011, 2:28 PM */ diff -r a9b72021f053 -r 0b49fd35afc1 vmalloc.c --- a/vmalloc.c Fri Sep 16 16:19:24 2011 +0200 +++ b/vmalloc.c Fri Sep 16 20:08:28 2011 +0200 @@ -15,6 +15,12 @@ #include "VMS.h" #include "Histogram/Histogram.h" +inline void +sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr); + +inline void +sendFreeReqst_master(int receiverID, void *ptrToFree); + /*Helper function *Insert a newly generated free chunk into the first spot on the free list. * The chunk is cast as a MallocProlog, so the various pointers in it are @@ -70,8 +76,6 @@ MallocPrologAllocated *returnElem; ssize_t amountExtra, sizeConsumed,sizeOfFound; uint32 foundElemIsTopOfHeap; - - printf("Malloc on core %d\n", procrID); //============================= MEASUREMENT STUFF ======================== #ifdef MEAS__TIME_MALLOC @@ -167,7 +171,8 @@ } else { - //Request from other Core + sendFreeReqst_master(chunk->procrID, ptrToFree); + } } @@ -180,17 +185,49 @@ VMS__free_in_lib(void *ptrToFree, VirtProcr *VProc) { MallocPrologAllocated *chunk = (MallocPrologAllocated*)ptrToFree - 1; - printf("Free from core %d for core %d\n", VProc->coreAnimatedBy, chunk->procrID); if(chunk->procrID == VProc->coreAnimatedBy) { VMS__free_on_core(ptrToFree, VProc->coreAnimatedBy); } else { - //Request from other Core + sendFreeReqst_lib(chunk->procrID, ptrToFree, VProc); } } +/* + * This is called form a masterVP and request an free from a different masterVP. + * The free of the request structure is done after the request is handled. + */ +inline void +sendFreeReqst_master(int receiverID, void *ptrToFree) +{ + InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst)); + freeReqst->freePtr = ptrToFree; + freeReqst->secondReqType = transfer_free_ptr; + + sendInterMasterReqst(receiverID, (InterMasterReqst*)freeReqst); + } + +/* + * This is called if the free is called from the plugin. This requests an inter + * master request from his master. + */ +inline void +sendFreeReqst_lib(int receiverID, void *ptrToFree, VirtProcr *animPr ) +{ + VMSSemReq reqData; + InterVMSCoreReqst *freeReqst = VMS__malloc(sizeof(InterVMSCoreReqst)); + freeReqst->freePtr = ptrToFree; + freeReqst->secondReqType = transfer_free_ptr; + + reqData.reqType = interMasterReqst; + reqData.receiverID = receiverID; + reqData.data = (void*)freeReqst; + + VMS__send_VMSSem_request( (void*)&reqData, animPr ); + } + /*This is sequential code -- only to be called from the Master * When free, subtract the size of prolog from pointer, then cast it to a * MallocProlog. Then check the nextLower and nextHigher chunks to see if @@ -367,8 +404,6 @@ { //just risk system-stack faults until get this figured out free( ptrToFree ); - - //TODO: fix this -- so } @@ -418,15 +453,11 @@ /*Designed to be called from the main thread outside of VMS, during cleanup */ void -VMS_ext__free_free_list( MallocProlog* freeListHeads[] ) +VMS_ext__free_free_list( MallocProlog* freeListHead) { //stashed a ptr to the one and only bug chunk malloc'd from OS in the // free list head's next lower in mem pointer - int i; - for(i=0; inextLowerInMem ); - } + free( freeListHead->nextLowerInMem ); //don't free the head -- it'll be in an array eventually -- free whole // array when all the free lists linked from it have already been freed } diff -r a9b72021f053 -r 0b49fd35afc1 vmalloc.h --- a/vmalloc.h Fri Sep 16 16:19:24 2011 +0200 +++ b/vmalloc.h Fri Sep 16 20:08:28 2011 +0200 @@ -71,6 +71,6 @@ VMS_ext__create_free_list(); void -VMS_ext__free_free_list( MallocProlog* freeListHeads[] ); +VMS_ext__free_free_list( MallocProlog* freeListHead ); #endif \ No newline at end of file