# HG changeset patch # User Some Random Person # Date 1331688484 25200 # Node ID b0b93147adfb86d4f8d361b659c6b453ec614f69 # Parent c88ce1db91ef3c39f00a390d13f29d754876aca3 More rearrangement -- have "Services_Offered_by_VMS" directory now, w/Debug etc diff -r c88ce1db91ef -r b0b93147adfb Defines/VMS_defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Defines/VMS_defs.h Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,43 @@ +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _VMS_DEFS_MAIN_H +#define _VMS_DEFS_MAIN_H +#define _GNU_SOURCE + +//=========================== VMS-wide defs =============================== + +#define SUCCESS 0 + + //only after macro-expansion are the defs of writePrivQ, aso looked up + // so these defs can be at the top, and writePrivQ defined later on.. +#define writeVMSQ writePrivQ +#define readVMSQ readPrivQ +#define makeVMSQ makePrivQ +#define numInVMSQ numInPrivQ +#define VMSQueueStruc PrivQueueStruc + + +/*The language should re-define this, but need a default in case it doesn't*/ +#ifndef _LANG_NAME_ +#define _LANG_NAME_ "" +#endif + +//====================== Hardware Constants ============================ +#include "VMS_defs__HW_constants.h" + +//====================== Macros ====================== + //for turning macros and other VMS features on and off +#include "VMS_defs__turn_on_and_off.h" + +#include "../Services_Offered_by_VMS/Debugging/DEBUG__macros.h" +#include "../Services_Offered_by_VMS/Measurement_and_Stats/MEAS__macros.h" + +//=========================================================================== +#endif /* */ + diff -r c88ce1db91ef -r b0b93147adfb Defines/VMS_defs__DEBUG.h --- a/Defines/VMS_defs__DEBUG.h Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright 2009 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - */ - -#ifndef _VMS_DEFS_DEBUG_H -#define _VMS_DEFS_DEBUG_H -#define _GNU_SOURCE - -/* - */ -#ifdef DEBUG__TURN_ON_DEBUG_MSGS - #define DEBUG_Print( bool, msg) \ - if( bool){ printf(msg); fflush(stdin);} - #define DEBUG_Print1( bool, msg, param) \ - if(bool){printf(msg, param); fflush(stdin);} - #define DEBUG_Print2( bool, msg, p1, p2) \ - if(bool) {printf(msg, p1, p2); fflush(stdin);} -#else - #define DEBUG_Print( bool, msg) - #define DEBUG_Print1( bool, msg, param) - #define DEBUG_Print2( bool, msg, p1, p2) -#endif - -//============================= ERROR MSGs ============================ -#define ERROR(msg) printf(msg); -#define ERROR1(msg, param) printf(msg, param); -#define ERROR2(msg, p1, p2) printf(msg, p1, p2); - -//=========================================================================== -#endif /* _VMS_DEFS_H */ - diff -r c88ce1db91ef -r b0b93147adfb Defines/VMS_defs__MEAS.h --- a/Defines/VMS_defs__MEAS.h Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,325 +0,0 @@ -/* - * Copyright 2009 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - */ - -#ifndef _VMS_DEFS_MEAS_H -#define _VMS_DEFS_MEAS_H -#define _GNU_SOURCE - -//================== Macros define types of meas want ===================== -// -/*Generic measurement macro -- has name-space collision potential, which - * compiler will catch.. so only use one pair inside a given set of - * curly braces. - */ -//TODO: finish generic capture interval in hist -enum histograms - { generic1 - }; - #define MEAS__Capture_Pre_Point \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); - - #define MEAS__Capture_Post_Point( histName ) \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->histName ); - - - - -//================== Macros define types of meas want ===================== - -#ifdef MEAS__TURN_ON_SUSP_MEAS - #define MEAS__Insert_Susp_Meas_Fields_into_Slave \ - uint32 preSuspTSCLow; \ - uint32 postSuspTSCLow; - - #define MEAS__Insert_Susp_Meas_Fields_into_MasterEnv \ - Histogram *suspLowTimeHist; \ - Histogram *suspHighTimeHist; - - #define MEAS__Make_Meas_Hists_for_Susp_Meas \ - _VMSMasterEnv->suspLowTimeHist = makeFixedBinHistExt( 100, 0, 200,\ - "master_low_time_hist");\ - _VMSMasterEnv->suspHighTimeHist = makeFixedBinHistExt( 100, 0, 200,\ - "master_high_time_hist"); - - //record time stamp: compare to time-stamp recorded below - #define MEAS__Capture_Pre_Susp_Point \ - saveLowTimeStampCountInto( animatingSlv->preSuspTSCLow ); - - //NOTE: only take low part of count -- do sanity check when take diff - #define MEAS__Capture_Post_Susp_Point \ - saveLowTimeStampCountInto( animatingSlv->postSuspTSCLow );\ - addIntervalToHist( preSuspTSCLow, postSuspTSCLow,\ - _VMSMasterEnv->suspLowTimeHist ); \ - addIntervalToHist( preSuspTSCLow, postSuspTSCLow,\ - _VMSMasterEnv->suspHighTimeHist ); - - #define MEAS__Print_Hists_for_Susp_Meas \ - printHist( _VMSMasterEnv->pluginTimeHist ); - -#else - #define MEAS__Insert_Susp_Meas_Fields_into_Slave - #define MEAS__Insert_Susp_Meas_Fields_into_MasterEnv - #define MEAS__Make_Meas_Hists_for_Susp_Meas - #define MEAS__Capture_Pre_Susp_Point - #define MEAS__Capture_Post_Susp_Point - #define MEAS__Print_Hists_for_Susp_Meas -#endif - -#ifdef MEAS__TURN_ON_MASTER_MEAS - #define MEAS__Insert_Master_Meas_Fields_into_Slave \ - uint32 startMasterTSCLow; \ - uint32 endMasterTSCLow; - - #define MEAS__Insert_Master_Meas_Fields_into_MasterEnv \ - Histogram *masterLowTimeHist; \ - Histogram *masterHighTimeHist; - - #define MEAS__Make_Meas_Hists_for_Master_Meas \ - _VMSMasterEnv->masterLowTimeHist = makeFixedBinHistExt( 100, 0, 200,\ - "master_low_time_hist");\ - _VMSMasterEnv->masterHighTimeHist = makeFixedBinHistExt( 100, 0, 200,\ - "master_high_time_hist"); - - //Total Master time includes one coreloop time -- just assume the core - // loop time is same for Master as for AppSlvs, even though it may be - // smaller due to higher predictability of the fixed jmp. - #define MEAS__Capture_Pre_Master_Point\ - saveLowTimeStampCountInto( masterVP->startMasterTSCLow ); - - #define MEAS__Capture_Post_Master_Point \ - saveLowTimeStampCountInto( masterVP->endMasterTSCLow );\ - addIntervalToHist( startMasterTSCLow, endMasterTSCLow,\ - _VMSMasterEnv->masterLowTimeHist ); \ - addIntervalToHist( startMasterTSCLow, endMasterTSCLow,\ - _VMSMasterEnv->masterHighTimeHist ); - - #define MEAS__Print_Hists_for_Master_Meas \ - printHist( _VMSMasterEnv->pluginTimeHist ); - -#else - #define MEAS__Insert_Master_Meas_Fields_into_Slave - #define MEAS__Insert_Master_Meas_Fields_into_MasterEnv - #define MEAS__Make_Meas_Hists_for_Master_Meas - #define MEAS__Capture_Pre_Master_Point - #define MEAS__Capture_Post_Master_Point - #define MEAS__Print_Hists_for_Master_Meas -#endif - - -#ifdef MEAS__TURN_ON_MASTER_LOCK_MEAS - #define MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv \ - Histogram *masterLockLowTimeHist; \ - Histogram *masterLockHighTimeHist; - - #define MEAS__Make_Meas_Hists_for_Master_Lock_Meas \ - _VMSMasterEnv->masterLockLowTimeHist = makeFixedBinHist( 50, 0, 2, \ - "master lock low time hist");\ - _VMSMasterEnv->masterLockHighTimeHist = makeFixedBinHist( 50, 0, 100,\ - "master lock high time hist"); - - #define MEAS__Capture_Pre_Master_Lock_Point \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); - - #define MEAS__Capture_Post_Master_Lock_Point \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp,\ - _VMSMasterEnv->masterLockLowTimeHist ); \ - addIntervalToHist( startStamp, endStamp,\ - _VMSMasterEnv->masterLockHighTimeHist ); - - #define MEAS__Print_Hists_for_Master_Lock_Meas \ - printHist( _VMSMasterEnv->masterLockLowTimeHist ); \ - printHist( _VMSMasterEnv->masterLockHighTimeHist ); - -#else - #define MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv - #define MEAS__Make_Meas_Hists_for_Master_Lock_Meas - #define MEAS__Capture_Pre_Master_Lock_Point - #define MEAS__Capture_Post_Master_Lock_Point - #define MEAS__Print_Hists_for_Master_Lock_Meas -#endif - - -#ifdef MEAS__TURN_ON_MALLOC_MEAS - #define MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv\ - Histogram *mallocTimeHist; \ - Histogram *freeTimeHist; - - #define MEAS__Make_Meas_Hists_for_Malloc_Meas \ - _VMSMasterEnv->mallocTimeHist = makeFixedBinHistExt( 100, 0, 30,\ - "malloc_time_hist");\ - _VMSMasterEnv->freeTimeHist = makeFixedBinHistExt( 100, 0, 30,\ - "free_time_hist"); - - #define MEAS__Capture_Pre_Malloc_Point \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); - - #define MEAS__Capture_Post_Malloc_Point \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp,\ - _VMSMasterEnv->mallocTimeHist ); - - #define MEAS__Capture_Pre_Free_Point \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); - - #define MEAS__Capture_Post_Free_Point \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp,\ - _VMSMasterEnv->freeTimeHist ); - - #define MEAS__Print_Hists_for_Malloc_Meas \ - printHist( _VMSMasterEnv->mallocTimeHist ); \ - saveHistToFile( _VMSMasterEnv->mallocTimeHist ); \ - printHist( _VMSMasterEnv->freeTimeHist ); \ - saveHistToFile( _VMSMasterEnv->freeTimeHist ); \ - freeHistExt( _VMSMasterEnv->mallocTimeHist ); \ - freeHistExt( _VMSMasterEnv->freeTimeHist ); - -#else - #define MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv - #define MEAS__Make_Meas_Hists_for_Malloc_Meas - #define MEAS__Capture_Pre_Malloc_Point - #define MEAS__Capture_Post_Malloc_Point - #define MEAS__Capture_Pre_Free_Point - #define MEAS__Capture_Post_Free_Point - #define MEAS__Print_Hists_for_Malloc_Meas -#endif - - - -#ifdef MEAS__TURN_ON_PLUGIN_MEAS - #define MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv \ - Histogram *reqHdlrLowTimeHist; \ - Histogram *reqHdlrHighTimeHist; - - #define MEAS__Make_Meas_Hists_for_Plugin_Meas \ - _VMSMasterEnv->reqHdlrLowTimeHist = makeFixedBinHistExt( 100, 0, 200,\ - "plugin_low_time_hist");\ - _VMSMasterEnv->reqHdlrHighTimeHist = makeFixedBinHistExt( 100, 0, 200,\ - "plugin_high_time_hist"); - - #define MEAS__startReqHdlr \ - int32 startStamp1, endStamp1; \ - saveLowTimeStampCountInto( startStamp1 ); - - #define MEAS__endReqHdlr \ - saveLowTimeStampCountInto( endStamp1 ); \ - addIntervalToHist( startStamp1, endStamp1, \ - _VMSMasterEnv->reqHdlrLowTimeHist ); \ - addIntervalToHist( startStamp1, endStamp1, \ - _VMSMasterEnv->reqHdlrHighTimeHist ); - - #define MEAS__Print_Hists_for_Plugin_Meas \ - printHist( _VMSMasterEnv->reqHdlrLowTimeHist ); \ - saveHistToFile( _VMSMasterEnv->reqHdlrLowTimeHist ); \ - printHist( _VMSMasterEnv->reqHdlrHighTimeHist ); \ - saveHistToFile( _VMSMasterEnv->reqHdlrHighTimeHist ); \ - freeHistExt( _VMSMasterEnv->reqHdlrLowTimeHist ); \ - freeHistExt( _VMSMasterEnv->reqHdlrHighTimeHist ); -#else - #define MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv - #define MEAS__Make_Meas_Hists_for_Plugin_Meas - #define MEAS__startReqHdlr - #define MEAS__endReqHdlr - #define MEAS__Print_Hists_for_Plugin_Meas - -#endif - - -#ifdef MEAS__TURN_ON_SYSTEM_MEAS - #define MEAS__Insert_System_Meas_Fields_into_Slave \ - TSCountLowHigh startSusp; \ - uint64 totalSuspCycles; \ - uint32 numGoodSusp; - - #define MEAS__Insert_System_Meas_Fields_into_MasterEnv \ - TSCountLowHigh startMaster; \ - uint64 totalMasterCycles; \ - uint32 numMasterAnimations; \ - TSCountLowHigh startReqHdlr; \ - uint64 totalPluginCycles; \ - uint32 numPluginAnimations; \ - uint64 cyclesTillStartMasterLoop; \ - TSCountLowHigh endMasterLoop; - - #define MEAS__startMasterLoop_forSys \ - TSCountLowHigh startStamp1, endStamp1; \ - saveTSCLowHigh( endStamp1 ); \ - _VMSMasterEnv->cyclesTillStartMasterLoop = \ - endStamp1.longVal - masterVP->startSusp.longVal; - - #define Meas_startReqHdlr_forSys \ - saveTSCLowHigh( startStamp1 ); \ - _VMSMasterEnv->startReqHdlr.longVal = startStamp1.longVal; - - #define MEAS__endMasterLoop_forSys \ - saveTSCLowHigh( startStamp1 ); \ - _VMSMasterEnv->endMasterLoop.longVal = startStamp1.longVal; - - /*A TSC is stored in VP first thing inside wrapper-lib - * Now, measures cycles from there to here - * Master and Plugin will add this value to other trace-seg measures - */ - #define MEAS__Capture_End_Susp_in_CoreCtlr_ForSys\ - saveTSCLowHigh(endSusp); \ - numCycles = endSusp.longVal - currVP->startSusp.longVal; \ - /*sanity check (400K is about 20K iters)*/ \ - if( numCycles < 400000 ) \ - { currVP->totalSuspCycles += numCycles; \ - currVP->numGoodSusp++; \ - } \ - /*recorded every time, but only read if currVP == MasterVP*/ \ - _VMSMasterEnv->startMaster.longVal = endSusp.longVal; - -#else - #define MEAS__Insert_System_Meas_Fields_into_Slave - #define MEAS__Insert_System_Meas_Fields_into_MasterEnv - #define MEAS__Make_Meas_Hists_for_System_Meas - #define MEAS__startMasterLoop_forSys - #define MEAS__startReqHdlr_forSys - #define MEAS__endMasterLoop_forSys - #define MEAS__Capture_End_Susp_in_CoreCtlr_ForSys - #define MEAS__Print_Hists_for_System_Meas -#endif - - -//Experiment in two-step macros -- if doesn't work, insert each separately -#define MEAS__Insert_Meas_Fields_into_Slave \ - MEAS__Insert_Susp_Meas_Fields_into_Slave \ - MEAS__Insert_Master_Meas_Fields_into_Slave \ - MEAS__Insert_System_Meas_Fields_into_Slave - - -//====================== Histogram Macros -- Create ======================== -// -// - -//The language implementation should include a definition of this macro, -// which creates all the histograms the language uses to collect measurements -// of plugin operation -- so, if the language didn't define it, must -// define it here (as empty), to avoid compile error -#ifndef MEAS__Make_Meas_Hists_for_Language -#define MEAS__Make_Meas_Hists_for_Language -#endif - -#define makeAMeasHist( idx, name, numBins, startVal, binWidth ) \ - makeHighestDynArrayIndexBeAtLeast( _VMSMasterEnv->measHistsInfo, idx ); \ - _VMSMasterEnv->measHists[idx] = \ - makeFixedBinHist( numBins, startVal, binWidth, name ); - -//============================== Probes =================================== - - -//=========================================================================== -#endif /* _VMS_DEFS_MEAS_H */ - diff -r c88ce1db91ef -r b0b93147adfb Defines/VMS_defs__lang_specific.h --- a/Defines/VMS_defs__lang_specific.h Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright 2009 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - */ - -#ifndef _VMS_LANG_SPEC_DEFS_H -#define _VMS_LANG_SPEC_DEFS_H - - - -//=================== Language-specific Measurement Stuff =================== -// -//TODO: move these into the language implementation directories -// - - -//=========================================================================== -//VCilk - -#ifdef VCILK - -#define spawnHistIdx 1 //note: starts at 1 -#define syncHistIdx 2 - -#define MEAS__Make_Meas_Hists_for_Language() \ - _VMSMasterEnv->measHistsInfo = \ - makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \ - makeAMeasHist( spawnHistIdx, "Spawn", 50, 0, 200 ) \ - makeAMeasHist( syncHistIdx, "Sync", 50, 0, 200 ) - - -#define Meas_startSpawn \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endSpawn \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ spawnHistIdx ] ); - -#define Meas_startSync \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endSync \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ syncHistIdx ] ); -#endif - -//=========================================================================== -// SSR - -#ifdef SSR - -#define SendFromToHistIdx 1 //note: starts at 1 -#define SendOfTypeHistIdx 2 -#define ReceiveFromToHistIdx 3 -#define ReceiveOfTypeHistIdx 4 - -#define MEAS__Make_Meas_Hists_for_Language() \ - _VMSMasterEnv->measHistsInfo = \ - makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \ - makeAMeasHist( SendFromToHistIdx, "SendFromTo", 50, 0, 100 ) \ - makeAMeasHist( SendOfTypeHistIdx, "SendOfType", 50, 0, 100 ) \ - makeAMeasHist( ReceiveFromToHistIdx,"ReceiveFromTo", 50, 0, 100 ) \ - makeAMeasHist( ReceiveOfTypeHistIdx,"ReceiveOfType", 50, 0, 100 ) - -#define Meas_startSendFromTo \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endSendFromTo \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ SendFromToHistIdx ] ); - -#define Meas_startSendOfType \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endSendOfType \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ SendOfTypeHistIdx ] ); - -#define Meas_startReceiveFromTo \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endReceiveFromTo \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ ReceiveFromToHistIdx ] ); - -#define Meas_startReceiveOfType \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endReceiveOfType \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ReceiveOfTypeHistIdx ] ); -#endif /* SSR */ - -#endif /* _VMS_DEFS_H */ - diff -r c88ce1db91ef -r b0b93147adfb Defines/VMS_defs__main.h --- a/Defines/VMS_defs__main.h Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright 2009 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - */ - -#ifndef _VMS_DEFS_MAIN_H -#define _VMS_DEFS_MAIN_H -#define _GNU_SOURCE - -//=========================== VMS-wide defs =============================== - -#define SUCCESS 0 - - //only after macro-expansion are the defs of writePrivQ, aso looked up - // so these defs can be at the top, and writePrivQ defined later on.. -#define writeVMSQ writePrivQ -#define readVMSQ readPrivQ -#define makeVMSQ makePrivQ -#define numInVMSQ numInPrivQ -#define VMSQueueStruc PrivQueueStruc - - -/*The language should re-define this, but need a default in case it doesn't*/ -#ifndef _LANG_NAME_ -#define _LANG_NAME_ "" -#endif - -//====================== Hardware Constants ============================ -#include "VMS_defs__HW_constants.h" - -//====================== Debug, Meas, etc defines ====================== -#include "VMS_defs__turn_on_and_off.h" -#include "VMS_defs__DEBUG.h" -#include "VMS_defs__MEAS.h" - -//=========================================================================== -#endif /* */ - diff -r c88ce1db91ef -r b0b93147adfb Probes/probes.c --- a/Probes/probes.c Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,303 +0,0 @@ -/* - * Copyright 2010 OpenSourceStewardshipFoundation - * - * Licensed under BSD - */ - -#include -#include -#include - -#include "../VMS.h" - - - -//==================== Probes ================= -/* - * In practice, probe operations are called from the app, from inside slaves - * -- so have to be sure each probe is single-Slv owned, and be sure that - * any place common structures are modified it's done inside the master. - * So -- the only place common structures are modified is during creation. - * after that, all mods are to individual instances. - * - * Thniking perhaps should change the semantics to be that probes are - * attached to the virtual processor -- and then everything is guaranteed - * to be isolated -- except then can't take any intervals that span Slvs, - * and would have to transfer the probes to Master env when Slv dissipates.. - * gets messy.. - * - * For now, just making so that probe creation causes a suspend, so that - * the dynamic array in the master env is only modified from the master - * - */ - -//============================ Helpers =========================== -inline void -doNothing() - { - } - -float64 inline -giveInterval( struct timeval _start, struct timeval _end ) - { float64 start, end; - start = _start.tv_sec + _start.tv_usec / 1000000.0; - end = _end.tv_sec + _end.tv_usec / 1000000.0; - return end - start; - } - -//================================================================= -IntervalProbe * -create_generic_probe( char *nameStr, SlaveVP *animSlv ) - { - VMSSemReq reqData; - - reqData.reqType = createProbe; - reqData.nameStr = nameStr; - - VMS_WL__send_VMSSem_request( &reqData, animSlv ); - - return animSlv->dataRetFromReq; - } - -/*Use this version from outside VMS -- it uses external malloc, and modifies - * dynamic array, so can't be animated in a slave Slv - */ -IntervalProbe * -ext__create_generic_probe( char *nameStr ) - { IntervalProbe *newProbe; - int32 nameLen; - - newProbe = malloc( sizeof(IntervalProbe) ); - nameLen = strlen( nameStr ); - newProbe->nameStr = malloc( nameLen ); - memcpy( newProbe->nameStr, nameStr, nameLen ); - newProbe->hist = NULL; - newProbe->schedChoiceWasRecorded = FALSE; - newProbe->probeID = - addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); - - return newProbe; - } - -//============================ Fns def in header ======================= - -int32 -VMS_impl__create_single_interval_probe( char *nameStr, SlaveVP *animSlv ) - { IntervalProbe *newProbe; - - newProbe = create_generic_probe( nameStr, animSlv ); - - return newProbe->probeID; - } - -int32 -VMS_impl__create_histogram_probe( int32 numBins, float64 startValue, - float64 binWidth, char *nameStr, SlaveVP *animSlv ) - { IntervalProbe *newProbe; - - newProbe = create_generic_probe( nameStr, animSlv ); - -#ifdef PROBES__USE_TIME_OF_DAY_PROBES - DblHist *hist; - hist = makeDblHistogram( numBins, startValue, binWidth ); -#else - Histogram *hist; - hist = makeHistogram( numBins, startValue, binWidth ); -#endif - newProbe->hist = hist; - return newProbe->probeID; - } - - -int32 -VMS_impl__record_time_point_into_new_probe( char *nameStr, SlaveVP *animSlv) - { IntervalProbe *newProbe; - struct timeval *startStamp; - float64 startSecs; - - newProbe = create_generic_probe( nameStr, animSlv ); - newProbe->endSecs = 0; - - - gettimeofday( &(newProbe->startStamp), NULL); - - //turn into a double - startStamp = &(newProbe->startStamp); - startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); - newProbe->startSecs = startSecs; - - return newProbe->probeID; - } - -int32 -VMS_ext_impl__record_time_point_into_new_probe( char *nameStr ) - { IntervalProbe *newProbe; - struct timeval *startStamp; - float64 startSecs; - - newProbe = ext__create_generic_probe( nameStr ); - newProbe->endSecs = 0; - - gettimeofday( &(newProbe->startStamp), NULL); - - //turn into a double - startStamp = &(newProbe->startStamp); - startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); - newProbe->startSecs = startSecs; - - return newProbe->probeID; - } - - -/*Only call from inside master or main startup/shutdown thread - */ -void -VMS_impl__free_probe( IntervalProbe *probe ) - { if( probe->hist != NULL ) freeDblHist( probe->hist ); - if( probe->nameStr != NULL) VMS_int__free( probe->nameStr ); - VMS_int__free( probe ); - } - - -void -VMS_impl__index_probe_by_its_name( int32 probeID, SlaveVP *animSlv ) - { IntervalProbe *probe; - - //TODO: fix this To be in Master -- race condition - probe = _VMSMasterEnv->intervalProbes[ probeID ]; - - addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl); - } - - -IntervalProbe * -VMS_impl__get_probe_by_name( char *probeName, SlaveVP *animSlv ) - { - //TODO: fix this To be in Master -- race condition - return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl ); - } - - -/*Everything is local to the animating slaveVP, so no need for request, do - * work locally, in the anim Slv - */ -void -VMS_impl__record_sched_choice_into_probe( int32 probeID, SlaveVP *animatingSlv ) - { IntervalProbe *probe; - - probe = _VMSMasterEnv->intervalProbes[ probeID ]; - probe->schedChoiceWasRecorded = TRUE; - probe->coreNum = animatingSlv->coreAnimatedBy; - probe->slaveID = animatingSlv->slaveID; - probe->slaveCreateSecs = animatingSlv->createPtInSecs; - } - -/*Everything is local to the animating slaveVP, so no need for request, do - * work locally, in the anim Slv - */ -void -VMS_impl__record_interval_start_in_probe( int32 probeID ) - { IntervalProbe *probe; - - DEBUG_Print( dbgProbes, "record start of interval\n" ) - probe = _VMSMasterEnv->intervalProbes[ probeID ]; - - //record *start* point as last thing, after lookup -#ifdef PROBES__USE_TIME_OF_DAY_PROBES - gettimeofday( &(probe->startStamp), NULL); -#endif -#ifdef PROBES__USE_TSC_PROBES - probe->startStamp = getTSCount(); -#endif - } - - -/*Everything is local to the animating slaveVP, except the histogram, so do - * work locally, in the anim Slv -- may lose a few histogram counts - * - *This should be safe to run inside SlaveVP - */ -void -VMS_impl__record_interval_end_in_probe( int32 probeID ) - { IntervalProbe *probe; - - //Record first thing -- before looking up the probe to store it into -#ifdef PROBES__USE_TIME_OF_DAY_PROBES - struct timeval endStamp; - gettimeofday( &(endStamp), NULL); -#endif -#ifdef PROBES__USE_TSC_PROBES - TSCount endStamp, interval; - endStamp = getTSCount(); -#endif -#ifdef PROBES__USE_PERF_CTR_PROBES - -#endif - - probe = _VMSMasterEnv->intervalProbes[ probeID ]; - -#ifdef PROBES__USE_TIME_OF_DAY_PROBES - if( probe->hist != NULL ) - { addToDblHist( giveInterval( probe->startStamp, endStamp), probe->hist ); - } -#endif -#ifdef PROBES__USE_TSC_PROBES - if( probe->hist != NULL ) - { interval = probe->endStamp - probe->startStamp; - //Sanity check for TSC counter overflow: if sane, add to histogram - if( interval < probe->hist->endOfRange * 10 ) - addToHist( interval, probe->hist ); - } -#endif -#ifdef PROBES__USE_PERF_CTR_PROBES - -#endif - - DEBUG_Print( dbgProbes, "record end of interval\n" ) - } - - -void -print_probe_helper( IntervalProbe *probe ) - { - printf( "\nprobe: %s, ", probe->nameStr ); - - - if( probe->schedChoiceWasRecorded ) - { printf( "coreNum: %d, slaveID: %d, slaveVPCreated: %0.6f | ", - probe->coreNum, probe->slaveID, probe->slaveCreateSecs ); - } - - if( probe->endSecs == 0 ) //just a single point in time - { - printf( " time point: %.6f\n", - probe->startSecs - _VMSMasterEnv->createPtInSecs ); - } - else if( probe->hist == NULL ) //just an interval - { - printf( " startSecs: %.6f interval: %.6f\n", - (probe->startSecs - _VMSMasterEnv->createPtInSecs), probe->interval); - } - else //a full histogram of intervals - { - printDblHist( probe->hist ); - } - } - -void -VMS_impl__print_stats_of_probe( IntervalProbe *probe ) - { - -// probe = _VMSMasterEnv->intervalProbes[ probeID ]; - - print_probe_helper( probe ); - } - - -void -VMS_impl__print_stats_of_all_probes() - { - forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo, - (DynArrayFnPtr) &VMS_impl__print_stats_of_probe ); - fflush( stdout ); - } diff -r c88ce1db91ef -r b0b93147adfb Probes/probes.h --- a/Probes/probes.h Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -/* - * Copyright 2009 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - */ - -#ifndef _PROBES_H -#define _PROBES_H -#define _GNU_SOURCE - -#include "../VMS_primitive_data_types.h" - -#include - -/*Note on order of include files: - * This file relies on #defines that appear in other files, which must come - * first in the #include sequence.. - */ - - -/*Use these aliases in application code*/ -#define VMS_App__record_time_point_into_new_probe VMS_WL__record_time_point_into_new_probe -#define VMS_App__create_single_interval_probe VMS_WL__create_single_interval_probe -#define VMS_App__create_histogram_probe VMS_WL__create_histogram_probe -#define VMS_App__index_probe_by_its_name VMS_WL__index_probe_by_its_name -#define VMS_App__get_probe_by_name VMS_WL__get_probe_by_name -#define VMS_App__record_sched_choice_into_probe VMS_WL__record_sched_choice_into_probe -#define VMS_App__record_interval_start_in_probe VMS_WL__record_interval_start_in_probe -#define VMS_App__record_interval_end_in_probe VMS_WL__record_interval_end_in_probe -#define VMS_App__print_stats_of_probe VMS_WL__print_stats_of_probe -#define VMS_App__print_stats_of_all_probes VMS_WL__print_stats_of_all_probes - - -//========================== -#ifdef PROBES__USE_TSC_PROBES - #define PROBES__Insert_timestamps_and_intervals_into_probe_struct \ - TSCount startStamp; \ - TSCount endStamp; \ - TSCount interval; \ - Histogram *hist; /*if left NULL, then is single interval probe*/ -#endif -#ifdef PROBES__USE_TIME_OF_DAY_PROBES - #define PROBES__Insert_timestamps_and_intervals_into_probe_struct \ - struct timeval startStamp; \ - struct timeval endStamp; \ - float64 startSecs; \ - float64 endSecs; \ - float64 interval; \ - DblHist *hist; /*if NULL, then is single interval probe*/ -#endif -#ifdef PROBES__USE_PERF_CTR_PROBES - #define PROBES__Insert_timestamps_and_intervals_into_probe_struct \ - int64 startStamp; \ - int64 endStamp; \ - int64 interval; \ - Histogram *hist; /*if left NULL, then is single interval probe*/ -#endif - -//typedef struct _IntervalProbe IntervalProbe; -- is in VMS.h -struct _IntervalProbe - { - char *nameStr; - int32 probeID; - - int32 schedChoiceWasRecorded; - int32 coreNum; - int32 slaveID; - float64 slaveCreateSecs; - PROBES__Insert_timestamps_and_intervals_into_probe_struct; - }; - -//=========================== NEVER USE THESE ========================== -/*NEVER use these in any code!! These are here only for use in the macros - * defined in this file!! - */ -int32 -VMS_impl__create_single_interval_probe( char *nameStr, SlaveVP *animSlv ); - -int32 -VMS_impl__create_histogram_probe( int32 numBins, float64 startValue, - float64 binWidth, char *nameStr, SlaveVP *animSlv ); - -int32 -VMS_impl__record_time_point_into_new_probe( char *nameStr, SlaveVP *animSlv); - -int32 -VMS_ext_impl__record_time_point_into_new_probe( char *nameStr ); - -void -VMS_impl__free_probe( IntervalProbe *probe ); - -void -VMS_impl__index_probe_by_its_name( int32 probeID, SlaveVP *animSlv ); - -IntervalProbe * -VMS_impl__get_probe_by_name( char *probeName, SlaveVP *animSlv ); - -void -VMS_impl__record_sched_choice_into_probe( int32 probeID, SlaveVP *animSlv ); - -void -VMS_impl__record_interval_start_in_probe( int32 probeID ); - -void -VMS_impl__record_interval_end_in_probe( int32 probeID ); - -void -VMS_impl__print_stats_of_probe( IntervalProbe *probe ); - -void -VMS_impl__print_stats_of_all_probes(); - - -//======================== Probes ============================= -// -// Use macros to allow turning probes off with a #define switch -// This means probes have zero impact on performance when off -//============================================================= - -#ifdef PROBES__TURN_ON_STATS_PROBES - #define VMS_WL__record_time_point_into_new_probe( nameStr, animSlv ) \ - VMS_impl__record_time_point_in_new_probe( nameStr, animSlv ) - - #define VMS_ext__record_time_point_into_new_probe( nameStr ) \ - VMS_ext_impl__record_time_point_into_new_probe( nameStr ) - - #define VMS_WL__create_single_interval_probe( nameStr, animSlv ) \ - VMS_impl__create_single_interval_probe( nameStr, animSlv ) - - #define VMS_WL__create_histogram_probe( numBins, startValue, \ - binWidth, nameStr, animSlv ) \ - VMS_impl__create_histogram_probe( numBins, startValue, \ - binWidth, nameStr, animSlv ) - #define VMS_int__free_probe( probe ) \ - VMS_impl__free_probe( probe ) - - #define VMS_WL__index_probe_by_its_name( probeID, animSlv ) \ - VMS_impl__index_probe_by_its_name( probeID, animSlv ) - - #define VMS_WL__get_probe_by_name( probeID, animSlv ) \ - VMS_impl__get_probe_by_name( probeName, animSlv ) - - #define VMS_WL__record_sched_choice_into_probe( probeID, animSlv ) \ - VMS_impl__record_sched_choice_into_probe( probeID, animSlv ) - - #define VMS_WL__record_interval_start_in_probe( probeID ) \ - VMS_impl__record_interval_start_in_probe( probeID ) - - #define VMS_WL__record_interval_end_in_probe( probeID ) \ - VMS_impl__record_interval_end_in_probe( probeID ) - - #define VMS_WL__print_stats_of_probe( probeID ) \ - VMS_impl__print_stats_of_probe( probeID ) - - #define VMS_WL__print_stats_of_all_probes() \ - VMS_impl__print_stats_of_all_probes() - - -#else - #define VMS_WL__record_time_point_into_new_probe( nameStr, animSlv ) 0 /* do nothing */ - #define VMS_ext__record_time_point_into_new_probe( nameStr ) 0 /* do nothing */ - #define VMS_WL__create_single_interval_probe( nameStr, animSlv ) 0 /* do nothing */ - #define VMS_WL__create_histogram_probe( numBins, startValue, \ - binWidth, nameStr, animSlv ) \ - 0 /* do nothing */ - #define VMS_WL__index_probe_by_its_name( probeID, animSlv ) /* do nothing */ - #define VMS_WL__get_probe_by_name( probeID, animSlv ) NULL /* do nothing */ - #define VMS_WL__record_sched_choice_into_probe( probeID, animSlv ) /* do nothing */ - #define VMS_WL__record_interval_start_in_probe( probeID ) /* do nothing */ - #define VMS_WL__record_interval_end_in_probe( probeID ) /* do nothing */ - #define VMS_WL__print_stats_of_probe( probeID ) ; /* do nothing */ - #define VMS_WL__print_stats_of_all_probes() ;/* do nothing */ - -#endif /* defined PROBES__TURN_ON_STATS_PROBES */ - -#endif /* _PROBES_H */ - diff -r c88ce1db91ef -r b0b93147adfb SchedulingMaster.c --- a/SchedulingMaster.c Tue Mar 13 10:02:06 2012 -0700 +++ b/SchedulingMaster.c Tue Mar 13 18:28:04 2012 -0700 @@ -26,18 +26,18 @@ *Polls each sched slot exactly once, hands any requests made by a newly * done slave to the "request handler" plug-in function * - *Any slots that need a Slv assigned are given to the "schedule" + *Any slots that need a Slv assigned are given to the "assign" * plug-in function, which tries to assign a Slv (slave) to it. * - *When all slots needing a processor have been given to the schedule plug-in, - * a fraction of the slaves successfully scheduled are put into the + *When all slots needing a processor have been given to the assign plug-in, + * a fraction of the slaves successfully assigned are put into the * work queue, then a continuation of this function is put in, then the rest - * of the Slvs that were successfully scheduled. + * of the Slvs that were successfully assigned. * *The first thing the continuation does is busy-wait until the previous * animation completes. This is because an (unlikely) continuation may * sneak through queue before previous continuation is done putting second - * part of scheduled slaves in, which is the only race condition. + * part of assigned slaves in, which is the only race condition. * */ @@ -78,7 +78,7 @@ MasterEnv *masterEnv; VMSQueueStruc *readyToAnimateQ; - Sched_Assigner slaveAssigner; + SlaveAssigner slaveAssigner; RequestHandler requestHandler; void *semanticEnv; @@ -143,7 +143,7 @@ if( currSlot->needsSlaveAssigned ) { //give slot a new Slv schedSlaveVP = - (*slaveAssigner)( semanticEnv, thisCoresIdx ); + (*slaveAssigner)( semanticEnv, thisCoresIdx, currSlot ); if( schedSlaveVP != NULL ) { currSlot->slaveAssignedToSlot = schedSlaveVP; diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Debugging/DEBUG__macros.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Debugging/DEBUG__macros.h Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _VMS_DEFS_DEBUG_H +#define _VMS_DEFS_DEBUG_H +#define _GNU_SOURCE + +/* + */ +#ifdef DEBUG__TURN_ON_DEBUG_MSGS + #define DEBUG_Print( bool, msg) \ + if( bool){ printf(msg); fflush(stdin);} + #define DEBUG_Print1( bool, msg, param) \ + if(bool){printf(msg, param); fflush(stdin);} + #define DEBUG_Print2( bool, msg, p1, p2) \ + if(bool) {printf(msg, p1, p2); fflush(stdin);} +#else + #define DEBUG_Print( bool, msg) + #define DEBUG_Print1( bool, msg, param) + #define DEBUG_Print2( bool, msg, p1, p2) +#endif + +//============================= ERROR MSGs ============================ +#define ERROR(msg) printf(msg); +#define ERROR1(msg, param) printf(msg, param); +#define ERROR2(msg, p1, p2) printf(msg, p1, p2); + +//=========================================================================== +#endif /* _VMS_DEFS_H */ + diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Lang_Constructs/VMS_Lang.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Lang_Constructs/VMS_Lang.h Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,44 @@ +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _VMS_LANG_CONSTRUCTS_H +#define _VMS_LANG_CONSTRUCTS_H + +#include "VMS_impl/VMS_primitive_data_types.h" + +/*This header defines everything specific to the VMS provided language + * constructs. + *Such constructs are used in application code, mixed-in with calls to + * constructs of the VMS-based language. + */ +inline void +handleMalloc( SSRSemReq *semReq, SlaveVP *requestingSlv, SSRSemEnv *semEnv); +inline void +handleFree( SSRSemReq *semReq, SlaveVP *requestingSlv, SSRSemEnv *semEnv ); +inline void +handleTransEnd(SSRSemReq *semReq, SlaveVP *requestingSlv, SSRSemEnv*semEnv); +inline void +handleTransStart( SSRSemReq *semReq, SlaveVP *requestingSlv, + SSRSemEnv *semEnv ); +inline void +handleAtomic( SSRSemReq *semReq, SlaveVP *requestingSlv, SSRSemEnv *semEnv); +inline void +handleStartFnSingleton( SSRSemReq *semReq, SlaveVP *reqstingSlv, + SSRSemEnv *semEnv ); +inline void +handleEndFnSingleton( SSRSemReq *semReq, SlaveVP *requestingSlv, + SSRSemEnv *semEnv ); +inline void +handleStartDataSingleton( SSRSemReq *semReq, SlaveVP *reqstingSlv, + SSRSemEnv *semEnv ); +inline void +handleEndDataSingleton( SSRSemReq *semReq, SlaveVP *requestingSlv, + SSRSemEnv *semEnv ); + +#endif /* _VMS_LANG_CONSTRUCTS_H */ + diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Measurement_and_Stats/MEAS__macros.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Measurement_and_Stats/MEAS__macros.h Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,325 @@ +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _VMS_MEAS_MACROS_H +#define _VMS_MEAS_MACROS_H +#define _GNU_SOURCE + +//================== Macros define types of meas want ===================== +// +/*Generic measurement macro -- has name-space collision potential, which + * compiler will catch.. so only use one pair inside a given set of + * curly braces. + */ +//TODO: finish generic capture interval in hist +enum histograms + { generic1 + }; + #define MEAS__Capture_Pre_Point \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); + + #define MEAS__Capture_Post_Point( histName ) \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->histName ); + + + + +//================== Macros define types of meas want ===================== + +#ifdef MEAS__TURN_ON_SUSP_MEAS + #define MEAS__Insert_Susp_Meas_Fields_into_Slave \ + uint32 preSuspTSCLow; \ + uint32 postSuspTSCLow; + + #define MEAS__Insert_Susp_Meas_Fields_into_MasterEnv \ + Histogram *suspLowTimeHist; \ + Histogram *suspHighTimeHist; + + #define MEAS__Make_Meas_Hists_for_Susp_Meas \ + _VMSMasterEnv->suspLowTimeHist = makeFixedBinHistExt( 100, 0, 200,\ + "master_low_time_hist");\ + _VMSMasterEnv->suspHighTimeHist = makeFixedBinHistExt( 100, 0, 200,\ + "master_high_time_hist"); + + //record time stamp: compare to time-stamp recorded below + #define MEAS__Capture_Pre_Susp_Point \ + saveLowTimeStampCountInto( animatingSlv->preSuspTSCLow ); + + //NOTE: only take low part of count -- do sanity check when take diff + #define MEAS__Capture_Post_Susp_Point \ + saveLowTimeStampCountInto( animatingSlv->postSuspTSCLow );\ + addIntervalToHist( preSuspTSCLow, postSuspTSCLow,\ + _VMSMasterEnv->suspLowTimeHist ); \ + addIntervalToHist( preSuspTSCLow, postSuspTSCLow,\ + _VMSMasterEnv->suspHighTimeHist ); + + #define MEAS__Print_Hists_for_Susp_Meas \ + printHist( _VMSMasterEnv->pluginTimeHist ); + +#else + #define MEAS__Insert_Susp_Meas_Fields_into_Slave + #define MEAS__Insert_Susp_Meas_Fields_into_MasterEnv + #define MEAS__Make_Meas_Hists_for_Susp_Meas + #define MEAS__Capture_Pre_Susp_Point + #define MEAS__Capture_Post_Susp_Point + #define MEAS__Print_Hists_for_Susp_Meas +#endif + +#ifdef MEAS__TURN_ON_MASTER_MEAS + #define MEAS__Insert_Master_Meas_Fields_into_Slave \ + uint32 startMasterTSCLow; \ + uint32 endMasterTSCLow; + + #define MEAS__Insert_Master_Meas_Fields_into_MasterEnv \ + Histogram *masterLowTimeHist; \ + Histogram *masterHighTimeHist; + + #define MEAS__Make_Meas_Hists_for_Master_Meas \ + _VMSMasterEnv->masterLowTimeHist = makeFixedBinHistExt( 100, 0, 200,\ + "master_low_time_hist");\ + _VMSMasterEnv->masterHighTimeHist = makeFixedBinHistExt( 100, 0, 200,\ + "master_high_time_hist"); + + //Total Master time includes one coreloop time -- just assume the core + // loop time is same for Master as for AppSlvs, even though it may be + // smaller due to higher predictability of the fixed jmp. + #define MEAS__Capture_Pre_Master_Point\ + saveLowTimeStampCountInto( masterVP->startMasterTSCLow ); + + #define MEAS__Capture_Post_Master_Point \ + saveLowTimeStampCountInto( masterVP->endMasterTSCLow );\ + addIntervalToHist( startMasterTSCLow, endMasterTSCLow,\ + _VMSMasterEnv->masterLowTimeHist ); \ + addIntervalToHist( startMasterTSCLow, endMasterTSCLow,\ + _VMSMasterEnv->masterHighTimeHist ); + + #define MEAS__Print_Hists_for_Master_Meas \ + printHist( _VMSMasterEnv->pluginTimeHist ); + +#else + #define MEAS__Insert_Master_Meas_Fields_into_Slave + #define MEAS__Insert_Master_Meas_Fields_into_MasterEnv + #define MEAS__Make_Meas_Hists_for_Master_Meas + #define MEAS__Capture_Pre_Master_Point + #define MEAS__Capture_Post_Master_Point + #define MEAS__Print_Hists_for_Master_Meas +#endif + + +#ifdef MEAS__TURN_ON_MASTER_LOCK_MEAS + #define MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv \ + Histogram *masterLockLowTimeHist; \ + Histogram *masterLockHighTimeHist; + + #define MEAS__Make_Meas_Hists_for_Master_Lock_Meas \ + _VMSMasterEnv->masterLockLowTimeHist = makeFixedBinHist( 50, 0, 2, \ + "master lock low time hist");\ + _VMSMasterEnv->masterLockHighTimeHist = makeFixedBinHist( 50, 0, 100,\ + "master lock high time hist"); + + #define MEAS__Capture_Pre_Master_Lock_Point \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); + + #define MEAS__Capture_Post_Master_Lock_Point \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp,\ + _VMSMasterEnv->masterLockLowTimeHist ); \ + addIntervalToHist( startStamp, endStamp,\ + _VMSMasterEnv->masterLockHighTimeHist ); + + #define MEAS__Print_Hists_for_Master_Lock_Meas \ + printHist( _VMSMasterEnv->masterLockLowTimeHist ); \ + printHist( _VMSMasterEnv->masterLockHighTimeHist ); + +#else + #define MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv + #define MEAS__Make_Meas_Hists_for_Master_Lock_Meas + #define MEAS__Capture_Pre_Master_Lock_Point + #define MEAS__Capture_Post_Master_Lock_Point + #define MEAS__Print_Hists_for_Master_Lock_Meas +#endif + + +#ifdef MEAS__TURN_ON_MALLOC_MEAS + #define MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv\ + Histogram *mallocTimeHist; \ + Histogram *freeTimeHist; + + #define MEAS__Make_Meas_Hists_for_Malloc_Meas \ + _VMSMasterEnv->mallocTimeHist = makeFixedBinHistExt( 100, 0, 30,\ + "malloc_time_hist");\ + _VMSMasterEnv->freeTimeHist = makeFixedBinHistExt( 100, 0, 30,\ + "free_time_hist"); + + #define MEAS__Capture_Pre_Malloc_Point \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); + + #define MEAS__Capture_Post_Malloc_Point \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp,\ + _VMSMasterEnv->mallocTimeHist ); + + #define MEAS__Capture_Pre_Free_Point \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); + + #define MEAS__Capture_Post_Free_Point \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp,\ + _VMSMasterEnv->freeTimeHist ); + + #define MEAS__Print_Hists_for_Malloc_Meas \ + printHist( _VMSMasterEnv->mallocTimeHist ); \ + saveHistToFile( _VMSMasterEnv->mallocTimeHist ); \ + printHist( _VMSMasterEnv->freeTimeHist ); \ + saveHistToFile( _VMSMasterEnv->freeTimeHist ); \ + freeHistExt( _VMSMasterEnv->mallocTimeHist ); \ + freeHistExt( _VMSMasterEnv->freeTimeHist ); + +#else + #define MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv + #define MEAS__Make_Meas_Hists_for_Malloc_Meas + #define MEAS__Capture_Pre_Malloc_Point + #define MEAS__Capture_Post_Malloc_Point + #define MEAS__Capture_Pre_Free_Point + #define MEAS__Capture_Post_Free_Point + #define MEAS__Print_Hists_for_Malloc_Meas +#endif + + + +#ifdef MEAS__TURN_ON_PLUGIN_MEAS + #define MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv \ + Histogram *reqHdlrLowTimeHist; \ + Histogram *reqHdlrHighTimeHist; + + #define MEAS__Make_Meas_Hists_for_Plugin_Meas \ + _VMSMasterEnv->reqHdlrLowTimeHist = makeFixedBinHistExt( 100, 0, 200,\ + "plugin_low_time_hist");\ + _VMSMasterEnv->reqHdlrHighTimeHist = makeFixedBinHistExt( 100, 0, 200,\ + "plugin_high_time_hist"); + + #define MEAS__startReqHdlr \ + int32 startStamp1, endStamp1; \ + saveLowTimeStampCountInto( startStamp1 ); + + #define MEAS__endReqHdlr \ + saveLowTimeStampCountInto( endStamp1 ); \ + addIntervalToHist( startStamp1, endStamp1, \ + _VMSMasterEnv->reqHdlrLowTimeHist ); \ + addIntervalToHist( startStamp1, endStamp1, \ + _VMSMasterEnv->reqHdlrHighTimeHist ); + + #define MEAS__Print_Hists_for_Plugin_Meas \ + printHist( _VMSMasterEnv->reqHdlrLowTimeHist ); \ + saveHistToFile( _VMSMasterEnv->reqHdlrLowTimeHist ); \ + printHist( _VMSMasterEnv->reqHdlrHighTimeHist ); \ + saveHistToFile( _VMSMasterEnv->reqHdlrHighTimeHist ); \ + freeHistExt( _VMSMasterEnv->reqHdlrLowTimeHist ); \ + freeHistExt( _VMSMasterEnv->reqHdlrHighTimeHist ); +#else + #define MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv + #define MEAS__Make_Meas_Hists_for_Plugin_Meas + #define MEAS__startReqHdlr + #define MEAS__endReqHdlr + #define MEAS__Print_Hists_for_Plugin_Meas + +#endif + + +#ifdef MEAS__TURN_ON_SYSTEM_MEAS + #define MEAS__Insert_System_Meas_Fields_into_Slave \ + TSCountLowHigh startSusp; \ + uint64 totalSuspCycles; \ + uint32 numGoodSusp; + + #define MEAS__Insert_System_Meas_Fields_into_MasterEnv \ + TSCountLowHigh startMaster; \ + uint64 totalMasterCycles; \ + uint32 numMasterAnimations; \ + TSCountLowHigh startReqHdlr; \ + uint64 totalPluginCycles; \ + uint32 numPluginAnimations; \ + uint64 cyclesTillStartMasterLoop; \ + TSCountLowHigh endMasterLoop; + + #define MEAS__startMasterLoop_forSys \ + TSCountLowHigh startStamp1, endStamp1; \ + saveTSCLowHigh( endStamp1 ); \ + _VMSMasterEnv->cyclesTillStartMasterLoop = \ + endStamp1.longVal - masterVP->startSusp.longVal; + + #define Meas_startReqHdlr_forSys \ + saveTSCLowHigh( startStamp1 ); \ + _VMSMasterEnv->startReqHdlr.longVal = startStamp1.longVal; + + #define MEAS__endMasterLoop_forSys \ + saveTSCLowHigh( startStamp1 ); \ + _VMSMasterEnv->endMasterLoop.longVal = startStamp1.longVal; + + /*A TSC is stored in VP first thing inside wrapper-lib + * Now, measures cycles from there to here + * Master and Plugin will add this value to other trace-seg measures + */ + #define MEAS__Capture_End_Susp_in_CoreCtlr_ForSys\ + saveTSCLowHigh(endSusp); \ + numCycles = endSusp.longVal - currVP->startSusp.longVal; \ + /*sanity check (400K is about 20K iters)*/ \ + if( numCycles < 400000 ) \ + { currVP->totalSuspCycles += numCycles; \ + currVP->numGoodSusp++; \ + } \ + /*recorded every time, but only read if currVP == MasterVP*/ \ + _VMSMasterEnv->startMaster.longVal = endSusp.longVal; + +#else + #define MEAS__Insert_System_Meas_Fields_into_Slave + #define MEAS__Insert_System_Meas_Fields_into_MasterEnv + #define MEAS__Make_Meas_Hists_for_System_Meas + #define MEAS__startMasterLoop_forSys + #define MEAS__startReqHdlr_forSys + #define MEAS__endMasterLoop_forSys + #define MEAS__Capture_End_Susp_in_CoreCtlr_ForSys + #define MEAS__Print_Hists_for_System_Meas +#endif + + +//Experiment in two-step macros -- if doesn't work, insert each separately +#define MEAS__Insert_Meas_Fields_into_Slave \ + MEAS__Insert_Susp_Meas_Fields_into_Slave \ + MEAS__Insert_Master_Meas_Fields_into_Slave \ + MEAS__Insert_System_Meas_Fields_into_Slave + + +//====================== Histogram Macros -- Create ======================== +// +// + +//The language implementation should include a definition of this macro, +// which creates all the histograms the language uses to collect measurements +// of plugin operation -- so, if the language didn't define it, must +// define it here (as empty), to avoid compile error +#ifndef MEAS__Make_Meas_Hists_for_Language +#define MEAS__Make_Meas_Hists_for_Language +#endif + +#define makeAMeasHist( idx, name, numBins, startVal, binWidth ) \ + makeHighestDynArrayIndexBeAtLeast( _VMSMasterEnv->measHistsInfo, idx ); \ + _VMSMasterEnv->measHists[idx] = \ + makeFixedBinHist( numBins, startVal, binWidth, name ); + +//============================== Probes =================================== + + +//=========================================================================== +#endif /* _VMS_DEFS_MEAS_H */ + diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Measurement_and_Stats/probes.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Measurement_and_Stats/probes.c Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,303 @@ +/* + * Copyright 2010 OpenSourceStewardshipFoundation + * + * Licensed under BSD + */ + +#include +#include +#include + +#include "VMS_impl/VMS.h" + + + +//==================== Probes ================= +/* + * In practice, probe operations are called from the app, from inside slaves + * -- so have to be sure each probe is single-Slv owned, and be sure that + * any place common structures are modified it's done inside the master. + * So -- the only place common structures are modified is during creation. + * after that, all mods are to individual instances. + * + * Thniking perhaps should change the semantics to be that probes are + * attached to the virtual processor -- and then everything is guaranteed + * to be isolated -- except then can't take any intervals that span Slvs, + * and would have to transfer the probes to Master env when Slv dissipates.. + * gets messy.. + * + * For now, just making so that probe creation causes a suspend, so that + * the dynamic array in the master env is only modified from the master + * + */ + +//============================ Helpers =========================== +inline void +doNothing() + { + } + +float64 inline +giveInterval( struct timeval _start, struct timeval _end ) + { float64 start, end; + start = _start.tv_sec + _start.tv_usec / 1000000.0; + end = _end.tv_sec + _end.tv_usec / 1000000.0; + return end - start; + } + +//================================================================= +IntervalProbe * +create_generic_probe( char *nameStr, SlaveVP *animSlv ) + { + VMSSemReq reqData; + + reqData.reqType = createProbe; + reqData.nameStr = nameStr; + + VMS_WL__send_VMSSem_request( &reqData, animSlv ); + + return animSlv->dataRetFromReq; + } + +/*Use this version from outside VMS -- it uses external malloc, and modifies + * dynamic array, so can't be animated in a slave Slv + */ +IntervalProbe * +ext__create_generic_probe( char *nameStr ) + { IntervalProbe *newProbe; + int32 nameLen; + + newProbe = malloc( sizeof(IntervalProbe) ); + nameLen = strlen( nameStr ); + newProbe->nameStr = malloc( nameLen ); + memcpy( newProbe->nameStr, nameStr, nameLen ); + newProbe->hist = NULL; + newProbe->schedChoiceWasRecorded = FALSE; + newProbe->probeID = + addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); + + return newProbe; + } + +//============================ Fns def in header ======================= + +int32 +VMS_impl__create_single_interval_probe( char *nameStr, SlaveVP *animSlv ) + { IntervalProbe *newProbe; + + newProbe = create_generic_probe( nameStr, animSlv ); + + return newProbe->probeID; + } + +int32 +VMS_impl__create_histogram_probe( int32 numBins, float64 startValue, + float64 binWidth, char *nameStr, SlaveVP *animSlv ) + { IntervalProbe *newProbe; + + newProbe = create_generic_probe( nameStr, animSlv ); + +#ifdef PROBES__USE_TIME_OF_DAY_PROBES + DblHist *hist; + hist = makeDblHistogram( numBins, startValue, binWidth ); +#else + Histogram *hist; + hist = makeHistogram( numBins, startValue, binWidth ); +#endif + newProbe->hist = hist; + return newProbe->probeID; + } + + +int32 +VMS_impl__record_time_point_into_new_probe( char *nameStr, SlaveVP *animSlv) + { IntervalProbe *newProbe; + struct timeval *startStamp; + float64 startSecs; + + newProbe = create_generic_probe( nameStr, animSlv ); + newProbe->endSecs = 0; + + + gettimeofday( &(newProbe->startStamp), NULL); + + //turn into a double + startStamp = &(newProbe->startStamp); + startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); + newProbe->startSecs = startSecs; + + return newProbe->probeID; + } + +int32 +VMS_ext_impl__record_time_point_into_new_probe( char *nameStr ) + { IntervalProbe *newProbe; + struct timeval *startStamp; + float64 startSecs; + + newProbe = ext__create_generic_probe( nameStr ); + newProbe->endSecs = 0; + + gettimeofday( &(newProbe->startStamp), NULL); + + //turn into a double + startStamp = &(newProbe->startStamp); + startSecs = startStamp->tv_sec + ( startStamp->tv_usec / 1000000.0 ); + newProbe->startSecs = startSecs; + + return newProbe->probeID; + } + + +/*Only call from inside master or main startup/shutdown thread + */ +void +VMS_impl__free_probe( IntervalProbe *probe ) + { if( probe->hist != NULL ) freeDblHist( probe->hist ); + if( probe->nameStr != NULL) VMS_int__free( probe->nameStr ); + VMS_int__free( probe ); + } + + +void +VMS_impl__index_probe_by_its_name( int32 probeID, SlaveVP *animSlv ) + { IntervalProbe *probe; + + //TODO: fix this To be in Master -- race condition + probe = _VMSMasterEnv->intervalProbes[ probeID ]; + + addValueIntoTable(probe->nameStr, probe, _VMSMasterEnv->probeNameHashTbl); + } + + +IntervalProbe * +VMS_impl__get_probe_by_name( char *probeName, SlaveVP *animSlv ) + { + //TODO: fix this To be in Master -- race condition + return getValueFromTable( probeName, _VMSMasterEnv->probeNameHashTbl ); + } + + +/*Everything is local to the animating slaveVP, so no need for request, do + * work locally, in the anim Slv + */ +void +VMS_impl__record_sched_choice_into_probe( int32 probeID, SlaveVP *animatingSlv ) + { IntervalProbe *probe; + + probe = _VMSMasterEnv->intervalProbes[ probeID ]; + probe->schedChoiceWasRecorded = TRUE; + probe->coreNum = animatingSlv->coreAnimatedBy; + probe->slaveID = animatingSlv->slaveID; + probe->slaveCreateSecs = animatingSlv->createPtInSecs; + } + +/*Everything is local to the animating slaveVP, so no need for request, do + * work locally, in the anim Slv + */ +void +VMS_impl__record_interval_start_in_probe( int32 probeID ) + { IntervalProbe *probe; + + DEBUG_Print( dbgProbes, "record start of interval\n" ) + probe = _VMSMasterEnv->intervalProbes[ probeID ]; + + //record *start* point as last thing, after lookup +#ifdef PROBES__USE_TIME_OF_DAY_PROBES + gettimeofday( &(probe->startStamp), NULL); +#endif +#ifdef PROBES__USE_TSC_PROBES + probe->startStamp = getTSCount(); +#endif + } + + +/*Everything is local to the animating slaveVP, except the histogram, so do + * work locally, in the anim Slv -- may lose a few histogram counts + * + *This should be safe to run inside SlaveVP + */ +void +VMS_impl__record_interval_end_in_probe( int32 probeID ) + { IntervalProbe *probe; + + //Record first thing -- before looking up the probe to store it into +#ifdef PROBES__USE_TIME_OF_DAY_PROBES + struct timeval endStamp; + gettimeofday( &(endStamp), NULL); +#endif +#ifdef PROBES__USE_TSC_PROBES + TSCount endStamp, interval; + endStamp = getTSCount(); +#endif +#ifdef PROBES__USE_PERF_CTR_PROBES + +#endif + + probe = _VMSMasterEnv->intervalProbes[ probeID ]; + +#ifdef PROBES__USE_TIME_OF_DAY_PROBES + if( probe->hist != NULL ) + { addToDblHist( giveInterval( probe->startStamp, endStamp), probe->hist ); + } +#endif +#ifdef PROBES__USE_TSC_PROBES + if( probe->hist != NULL ) + { interval = probe->endStamp - probe->startStamp; + //Sanity check for TSC counter overflow: if sane, add to histogram + if( interval < probe->hist->endOfRange * 10 ) + addToHist( interval, probe->hist ); + } +#endif +#ifdef PROBES__USE_PERF_CTR_PROBES + +#endif + + DEBUG_Print( dbgProbes, "record end of interval\n" ) + } + + +void +print_probe_helper( IntervalProbe *probe ) + { + printf( "\nprobe: %s, ", probe->nameStr ); + + + if( probe->schedChoiceWasRecorded ) + { printf( "coreNum: %d, slaveID: %d, slaveVPCreated: %0.6f | ", + probe->coreNum, probe->slaveID, probe->slaveCreateSecs ); + } + + if( probe->endSecs == 0 ) //just a single point in time + { + printf( " time point: %.6f\n", + probe->startSecs - _VMSMasterEnv->createPtInSecs ); + } + else if( probe->hist == NULL ) //just an interval + { + printf( " startSecs: %.6f interval: %.6f\n", + (probe->startSecs - _VMSMasterEnv->createPtInSecs), probe->interval); + } + else //a full histogram of intervals + { + printDblHist( probe->hist ); + } + } + +void +VMS_impl__print_stats_of_probe( IntervalProbe *probe ) + { + +// probe = _VMSMasterEnv->intervalProbes[ probeID ]; + + print_probe_helper( probe ); + } + + +void +VMS_impl__print_stats_of_all_probes() + { + forAllInDynArrayDo( _VMSMasterEnv->dynIntervalProbesInfo, + (DynArrayFnPtr) &VMS_impl__print_stats_of_probe ); + fflush( stdout ); + } diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Measurement_and_Stats/probes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Measurement_and_Stats/probes.h Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,192 @@ +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _PROBES_H +#define _PROBES_H +#define _GNU_SOURCE + +#include "VMS_impl/VMS_primitive_data_types.h" + +#include + +/*Note on order of include files: + * This file relies on #defines that appear in other files, which must come + * first in the #include sequence.. + */ + +/*Use these aliases in application code*/ +#define VMS_App__record_time_point_into_new_probe VMS_WL__record_time_point_into_new_probe +#define VMS_App__create_single_interval_probe VMS_WL__create_single_interval_probe +#define VMS_App__create_histogram_probe VMS_WL__create_histogram_probe +#define VMS_App__index_probe_by_its_name VMS_WL__index_probe_by_its_name +#define VMS_App__get_probe_by_name VMS_WL__get_probe_by_name +#define VMS_App__record_sched_choice_into_probe VMS_WL__record_sched_choice_into_probe +#define VMS_App__record_interval_start_in_probe VMS_WL__record_interval_start_in_probe +#define VMS_App__record_interval_end_in_probe VMS_WL__record_interval_end_in_probe +#define VMS_App__print_stats_of_probe VMS_WL__print_stats_of_probe +#define VMS_App__print_stats_of_all_probes VMS_WL__print_stats_of_all_probes + + +//========================== +#ifdef PROBES__USE_TSC_PROBES + #define PROBES__Insert_timestamps_and_intervals_into_probe_struct \ + TSCount startStamp; \ + TSCount endStamp; \ + TSCount interval; \ + Histogram *hist; /*if left NULL, then is single interval probe*/ +#endif +#ifdef PROBES__USE_TIME_OF_DAY_PROBES + #define PROBES__Insert_timestamps_and_intervals_into_probe_struct \ + struct timeval startStamp; \ + struct timeval endStamp; \ + float64 startSecs; \ + float64 endSecs; \ + float64 interval; \ + DblHist *hist; /*if NULL, then is single interval probe*/ +#endif +#ifdef PROBES__USE_PERF_CTR_PROBES + #define PROBES__Insert_timestamps_and_intervals_into_probe_struct \ + int64 startStamp; \ + int64 endStamp; \ + int64 interval; \ + Histogram *hist; /*if left NULL, then is single interval probe*/ +#endif + +//typedef struct _IntervalProbe IntervalProbe; -- is in VMS.h +struct _IntervalProbe + { + char *nameStr; + int32 probeID; + + int32 schedChoiceWasRecorded; + int32 coreNum; + int32 slaveID; + float64 slaveCreateSecs; + PROBES__Insert_timestamps_and_intervals_into_probe_struct; + }; + +//=========================== NEVER USE THESE ========================== +/*NEVER use these in any code!! These are here only for use in the macros + * defined in this file!! + */ +int32 +VMS_impl__create_single_interval_probe( char *nameStr, SlaveVP *animSlv ); + +int32 +VMS_impl__create_histogram_probe( int32 numBins, float64 startValue, + float64 binWidth, char *nameStr, SlaveVP *animSlv ); + +int32 +VMS_impl__record_time_point_into_new_probe( char *nameStr, SlaveVP *animSlv); + +int32 +VMS_ext_impl__record_time_point_into_new_probe( char *nameStr ); + +void +VMS_impl__free_probe( IntervalProbe *probe ); + +void +VMS_impl__index_probe_by_its_name( int32 probeID, SlaveVP *animSlv ); + +IntervalProbe * +VMS_impl__get_probe_by_name( char *probeName, SlaveVP *animSlv ); + +void +VMS_impl__record_sched_choice_into_probe( int32 probeID, SlaveVP *animSlv ); + +void +VMS_impl__record_interval_start_in_probe( int32 probeID ); + +void +VMS_impl__record_interval_end_in_probe( int32 probeID ); + +void +VMS_impl__print_stats_of_probe( IntervalProbe *probe ); + +void +VMS_impl__print_stats_of_all_probes(); + + +//======================== Probes ============================= +// +// Use macros to allow turning probes off with a #define switch +// This means probes have zero impact on performance when off +//============================================================= + +#ifdef PROBES__TURN_ON_STATS_PROBES + + #define PROBES__Create_Probe_Bookkeeping_Vars \ + _VMSMasterEnv->dynIntervalProbesInfo = \ + makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->intervalProbes), 200); \ + \ + _VMSMasterEnv->probeNameHashTbl = makeHashTable( 1000, &VMS_int__free ); \ + \ + /*put creation time directly into master env, for fast retrieval*/ \ + struct timeval timeStamp; \ + gettimeofday( &(timeStamp), NULL); \ + _VMSMasterEnv->createPtInSecs = \ + timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0); + + #define VMS_WL__record_time_point_into_new_probe( nameStr, animSlv ) \ + VMS_impl__record_time_point_in_new_probe( nameStr, animSlv ) + + #define VMS_ext__record_time_point_into_new_probe( nameStr ) \ + VMS_ext_impl__record_time_point_into_new_probe( nameStr ) + + #define VMS_WL__create_single_interval_probe( nameStr, animSlv ) \ + VMS_impl__create_single_interval_probe( nameStr, animSlv ) + + #define VMS_WL__create_histogram_probe( numBins, startValue, \ + binWidth, nameStr, animSlv ) \ + VMS_impl__create_histogram_probe( numBins, startValue, \ + binWidth, nameStr, animSlv ) + #define VMS_int__free_probe( probe ) \ + VMS_impl__free_probe( probe ) + + #define VMS_WL__index_probe_by_its_name( probeID, animSlv ) \ + VMS_impl__index_probe_by_its_name( probeID, animSlv ) + + #define VMS_WL__get_probe_by_name( probeID, animSlv ) \ + VMS_impl__get_probe_by_name( probeName, animSlv ) + + #define VMS_WL__record_sched_choice_into_probe( probeID, animSlv ) \ + VMS_impl__record_sched_choice_into_probe( probeID, animSlv ) + + #define VMS_WL__record_interval_start_in_probe( probeID ) \ + VMS_impl__record_interval_start_in_probe( probeID ) + + #define VMS_WL__record_interval_end_in_probe( probeID ) \ + VMS_impl__record_interval_end_in_probe( probeID ) + + #define VMS_WL__print_stats_of_probe( probeID ) \ + VMS_impl__print_stats_of_probe( probeID ) + + #define VMS_WL__print_stats_of_all_probes() \ + VMS_impl__print_stats_of_all_probes() + + +#else + #define PROBES__Create_Probe_Bookkeeping_Vars + #define VMS_WL__record_time_point_into_new_probe( nameStr, animSlv ) 0 /* do nothing */ + #define VMS_ext__record_time_point_into_new_probe( nameStr ) 0 /* do nothing */ + #define VMS_WL__create_single_interval_probe( nameStr, animSlv ) 0 /* do nothing */ + #define VMS_WL__create_histogram_probe( numBins, startValue, \ + binWidth, nameStr, animSlv ) \ + 0 /* do nothing */ + #define VMS_WL__index_probe_by_its_name( probeID, animSlv ) /* do nothing */ + #define VMS_WL__get_probe_by_name( probeID, animSlv ) NULL /* do nothing */ + #define VMS_WL__record_sched_choice_into_probe( probeID, animSlv ) /* do nothing */ + #define VMS_WL__record_interval_start_in_probe( probeID ) /* do nothing */ + #define VMS_WL__record_interval_end_in_probe( probeID ) /* do nothing */ + #define VMS_WL__print_stats_of_probe( probeID ) ; /* do nothing */ + #define VMS_WL__print_stats_of_all_probes() ;/* do nothing */ + +#endif /* defined PROBES__TURN_ON_STATS_PROBES */ + +#endif /* _PROBES_H */ + diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Memory_Handling/vmalloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Memory_Handling/vmalloc.c Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,375 @@ +/* + * Copyright 2009 OpenSourceCodeStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + * Created on November 14, 2009, 9:07 PM + */ + +#include +#include +#include +#include +#include +#include + +#include "VMS_impl/VMS.h" +#include "Histogram/Histogram.h" + +#define MAX_UINT64 0xFFFFFFFFFFFFFFFF + +//A MallocProlog is a head element if the HigherInMem variable is NULL +//A Chunk is free if the prevChunkInFreeList variable is NULL + +/* + * This calculates the container which fits the given size. + */ +inline +uint32 getContainer(size_t size) +{ + return (log2(size)-LOG128)/LOG54; +} + +/* + * Removes the first chunk of a freeList + * The chunk is removed but not set as free. There is no check if + * the free list is empty, so make sure this is not the case. + */ +inline +MallocProlog *removeChunk(MallocArrays* freeLists, uint32 containerIdx) +{ + MallocProlog** container = &freeLists->bigChunks[containerIdx]; + MallocProlog* removedChunk = *container; + *container = removedChunk->nextChunkInFreeList; + + if(removedChunk->nextChunkInFreeList) + removedChunk->nextChunkInFreeList->prevChunkInFreeList = + (MallocProlog*)container; + + if(*container == NULL) + { + if(containerIdx < 64) + freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); + else + freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); + } + + return removedChunk; +} + +/* + * Removes the first chunk of a freeList + * The chunk is removed but not set as free. There is no check if + * the free list is empty, so make sure this is not the case. + */ +inline +MallocProlog *removeSmallChunk(MallocArrays* freeLists, uint32 containerIdx) +{ + MallocProlog** container = &freeLists->smallChunks[containerIdx]; + MallocProlog* removedChunk = *container; + *container = removedChunk->nextChunkInFreeList; + + if(removedChunk->nextChunkInFreeList) + removedChunk->nextChunkInFreeList->prevChunkInFreeList = + (MallocProlog*)container; + + return removedChunk; +} + +inline +size_t getChunkSize(MallocProlog* chunk) +{ + return (uintptr_t)chunk->nextHigherInMem - + (uintptr_t)chunk - sizeof(MallocProlog); +} + +/* + * Removes a chunk from a free list. + */ +inline +void extractChunk(MallocProlog* chunk, MallocArrays *freeLists) +{ + chunk->prevChunkInFreeList->nextChunkInFreeList = chunk->nextChunkInFreeList; + if(chunk->nextChunkInFreeList) + chunk->nextChunkInFreeList->prevChunkInFreeList = chunk->prevChunkInFreeList; + + //The last element in the list points to the container. If the container points + //to NULL the container is empty + if(*((void**)(chunk->prevChunkInFreeList)) == NULL && getChunkSize(chunk) >= BIG_LOWER_BOUND) + { + //Find the approppiate container because we do not know it + uint64 containerIdx = ((uintptr_t)chunk->prevChunkInFreeList - (uintptr_t)freeLists->bigChunks) >> 3; + if(containerIdx < (uint32)64) + freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); + if(containerIdx < 128 && containerIdx >=64) + freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); + + } +} + +/* + * Merges two chunks. + * Chunk A has to be before chunk B in memory. Both have to be removed from + * a free list + */ +inline +MallocProlog *mergeChunks(MallocProlog* chunkA, MallocProlog* chunkB) +{ + chunkA->nextHigherInMem = chunkB->nextHigherInMem; + chunkB->nextHigherInMem->nextLowerInMem = chunkA; + return chunkA; +} +/* + * Inserts a chunk into a free list. + */ +inline +void insertChunk(MallocProlog* chunk, MallocProlog** container) +{ + chunk->nextChunkInFreeList = *container; + chunk->prevChunkInFreeList = (MallocProlog*)container; + if(*container) + (*container)->prevChunkInFreeList = chunk; + *container = chunk; +} + +/* + * Divides the chunk that a new chunk of newSize is created. + * There is no size check, so make sure the size value is valid. + */ +inline +MallocProlog *divideChunk(MallocProlog* chunk, size_t newSize) +{ + MallocProlog* newChunk = (MallocProlog*)((uintptr_t)chunk->nextHigherInMem - + newSize - sizeof(MallocProlog)); + + newChunk->nextLowerInMem = chunk; + newChunk->nextHigherInMem = chunk->nextHigherInMem; + + chunk->nextHigherInMem->nextLowerInMem = newChunk; + chunk->nextHigherInMem = newChunk; + + return newChunk; +} + +/* + * Search for chunk in the list of big chunks. Split the block if it's too big + */ +inline +MallocProlog *searchChunk(MallocArrays *freeLists, size_t sizeRequested, uint32 containerIdx) +{ + MallocProlog* foundChunk; + + uint64 searchVector = freeLists->bigChunksSearchVector[0]; + //set small chunk bits to zero + searchVector &= MAX_UINT64 << containerIdx; + containerIdx = __builtin_ffsl(searchVector); + + if(containerIdx == 0) + { + searchVector = freeLists->bigChunksSearchVector[1]; + containerIdx = __builtin_ffsl(searchVector); + if(containerIdx == 0) + { + printf("VMS malloc failed: low memory"); + exit(1); + } + containerIdx += 64; + } + containerIdx--; + + + foundChunk = removeChunk(freeLists, containerIdx); + size_t chunkSize = getChunkSize(foundChunk); + + //If the new chunk is larger than the requested size: split + if(chunkSize > sizeRequested + 2 * sizeof(MallocProlog) + BIG_LOWER_BOUND) + { + MallocProlog *newChunk = divideChunk(foundChunk,sizeRequested); + containerIdx = getContainer(getChunkSize(foundChunk)) - 1; + insertChunk(foundChunk,&freeLists->bigChunks[containerIdx]); + if(containerIdx < 64) + freeLists->bigChunksSearchVector[0] |= ((uint64)1 << containerIdx); + else + freeLists->bigChunksSearchVector[1] |= ((uint64)1 << (containerIdx-64)); + foundChunk = newChunk; + } + + return foundChunk; +} + + +/* + * This is sequential code, meant to only be called from the Master, not from + * any slave Slvs. + */ +void * +VMS_int__malloc( size_t sizeRequested ) + { + MEAS__Capture_Pre_Malloc_Point + + MallocArrays* freeLists = _VMSMasterEnv->freeLists; + MallocProlog* foundChunk; + + //Return a small chunk if the requested size is smaller than 128B + if(sizeRequested <= LOWER_BOUND) + { + uint32 freeListIdx = (sizeRequested-1)/SMALL_CHUNK_SIZE; + if(freeLists->smallChunks[freeListIdx] == NULL) + foundChunk = searchChunk(freeLists, SMALL_CHUNK_SIZE*(freeListIdx+1), 0); + else + foundChunk = removeSmallChunk(freeLists, freeListIdx); + + //Mark as allocated + foundChunk->prevChunkInFreeList = NULL; + return foundChunk + 1; + } + + //Calculate the expected container. Start one higher to have a Chunk that's + //always big enough. + uint32 containerIdx = getContainer(sizeRequested); + + if(freeLists->bigChunks[containerIdx] == NULL) + foundChunk = searchChunk(freeLists, sizeRequested, containerIdx); + else + foundChunk = removeChunk(freeLists, containerIdx); + + //Mark as allocated + foundChunk->prevChunkInFreeList = NULL; + + MEAS__Capture_Post_Malloc_Point + + //skip over the prolog by adding its size to the pointer return + return foundChunk + 1; + } + +/* + * This is sequential code, meant to only be called from the Master, not from + * any slave Slvs. + */ +void +VMS_int__free( void *ptrToFree ) + { + + MEAS__Capture_Pre_Free_Point; + + MallocArrays* freeLists = _VMSMasterEnv->freeLists; + MallocProlog *chunkToFree = (MallocProlog*)ptrToFree - 1; + uint32 containerIdx; + + //Check for free neighbors + if(chunkToFree->nextLowerInMem) + { + if(chunkToFree->nextLowerInMem->prevChunkInFreeList != NULL) + {//Chunk is not allocated + extractChunk(chunkToFree->nextLowerInMem, freeLists); + chunkToFree = mergeChunks(chunkToFree->nextLowerInMem, chunkToFree); + } + } + if(chunkToFree->nextHigherInMem) + { + if(chunkToFree->nextHigherInMem->prevChunkInFreeList != NULL) + {//Chunk is not allocated + extractChunk(chunkToFree->nextHigherInMem, freeLists); + chunkToFree = mergeChunks(chunkToFree, chunkToFree->nextHigherInMem); + } + } + + size_t chunkSize = getChunkSize(chunkToFree); + if(chunkSize < BIG_LOWER_BOUND) + { + containerIdx = (chunkSize/SMALL_CHUNK_SIZE)-1; + if(containerIdx > SMALL_CHUNK_COUNT-1) + containerIdx = SMALL_CHUNK_COUNT-1; + insertChunk(chunkToFree, &freeLists->smallChunks[containerIdx]); + } + else + { + containerIdx = getContainer(getChunkSize(chunkToFree)) - 1; + insertChunk(chunkToFree, &freeLists->bigChunks[containerIdx]); + if(containerIdx < 64) + freeLists->bigChunksSearchVector[0] |= (uint64)1 << containerIdx; + else + freeLists->bigChunksSearchVector[1] |= (uint64)1 << (containerIdx-64); + } + + MEAS__Capture_Post_Free_Point; + } + +/* + * Designed to be called from the main thread outside of VMS, during init + */ +MallocArrays * +VMS_ext__create_free_list() +{ + //Initialize containers for small chunks and fill with zeros + _VMSMasterEnv->freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) ); + MallocArrays *freeLists = _VMSMasterEnv->freeLists; + + freeLists->smallChunks = + (MallocProlog**)malloc(SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); + memset((void*)freeLists->smallChunks, + 0,SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); + + //Calculate number of containers for big chunks + uint32 container = getContainer(MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE)+1; + freeLists->bigChunks = (MallocProlog**)malloc(container*sizeof(MallocProlog*)); + memset((void*)freeLists->bigChunks,0,container*sizeof(MallocProlog*)); + freeLists->containerCount = container; + + //Create first element in lastContainer + MallocProlog *firstChunk = malloc( MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE ); + if( firstChunk == NULL ) {printf("Can't allocate initial memory\n"); exit(1);} + freeLists->memSpace = firstChunk; + + //Touch memory to avoid page faults + void *ptr,*endPtr; + endPtr = (void*)firstChunk+MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE; + for(ptr = firstChunk; ptr < endPtr; ptr+=PAGE_SIZE) + { + *(char*)ptr = 0; + } + + firstChunk->nextLowerInMem = NULL; + firstChunk->nextHigherInMem = (MallocProlog*)((uintptr_t)firstChunk + + MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog)); + firstChunk->nextChunkInFreeList = NULL; + //previous element in the queue is the container + firstChunk->prevChunkInFreeList = &freeLists->bigChunks[container-2]; + + freeLists->bigChunks[container-2] = firstChunk; + //Insert into bit search list + if(container <= 65) + { + freeLists->bigChunksSearchVector[0] = ((uint64)1 << (container-2)); + freeLists->bigChunksSearchVector[1] = 0; + } + else + { + freeLists->bigChunksSearchVector[0] = 0; + freeLists->bigChunksSearchVector[1] = ((uint64)1 << (container-66)); + } + + //Create dummy chunk to mark the top of stack this is of course + //never freed + MallocProlog *dummyChunk = firstChunk->nextHigherInMem; + dummyChunk->nextHigherInMem = dummyChunk+1; + dummyChunk->nextLowerInMem = NULL; + dummyChunk->nextChunkInFreeList = NULL; + dummyChunk->prevChunkInFreeList = NULL; + + return freeLists; + } + + +/*Designed to be called from the main thread outside of VMS, during cleanup + */ +void +VMS_ext__free_free_list( MallocArrays *freeLists ) + { + free(freeLists->memSpace); + free(freeLists->bigChunks); + free(freeLists->smallChunks); + + } + diff -r c88ce1db91ef -r b0b93147adfb Services_Offered_by_VMS/Memory_Handling/vmalloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Services_Offered_by_VMS/Memory_Handling/vmalloc.h Tue Mar 13 18:28:04 2012 -0700 @@ -0,0 +1,91 @@ +/* + * Copyright 2009 OpenSourceCodeStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + * Created on November 14, 2009, 9:07 PM + */ + +#ifndef _VMALLOC_H +#define _VMALLOC_H + +#include +#include +#include "VMS_impl/VMS_primitive_data_types.h" + +#define SMALL_CHUNK_SIZE 32 +#define SMALL_CHUNK_COUNT 4 +#define LOWER_BOUND 128 //Biggest chunk size that is created for the small chunks +#define BIG_LOWER_BOUND 160 //Smallest chunk size that is created for the big chunks + +#define LOG54 0.3219280948873623 +#define LOG128 7 + +typedef struct _MallocProlog MallocProlog; + +struct _MallocProlog + { + MallocProlog *nextChunkInFreeList; + MallocProlog *prevChunkInFreeList; + MallocProlog *nextHigherInMem; + MallocProlog *nextLowerInMem; + }; +//MallocProlog + + typedef struct MallocArrays MallocArrays; + + struct MallocArrays + { + MallocProlog **smallChunks; + MallocProlog **bigChunks; + uint64 bigChunksSearchVector[2]; + void *memSpace; + uint32 containerCount; + }; + //MallocArrays + +typedef struct + { + MallocProlog *firstChunkInFreeList; + int32 numInList; //TODO not used + } +FreeListHead; + +void * +VMS_int__malloc( size_t sizeRequested ); +#define VMS_PI__malloc VMS_int__malloc +#define VMS_WL__malloc VMS_int__malloc /*TODO: Bug -- Not protected!! */ +#define VMS_App__malloc VMS_int__malloc /*TODO: Bug -- Not protected!! */ + +void * +VMS_int__malloc_aligned( size_t sizeRequested ); +#define VMS_PI__malloc_aligned VMS_int__malloc_aligned +#define VMS_WL__malloc_aligned VMS_int__malloc_aligned + +void +VMS_int__free( void *ptrToFree ); +#define VMS_PI__free VMS_int__free +#define VMS_WL__free VMS_int__free /*TODO: Bug -- Not protected!! */ +#define VMS_App__free VMS_int__free /*TODO: Bug -- Not protected!! */ + + + +/*Allocates memory from the external system -- higher overhead + */ +void * +VMS_ext__malloc_in_ext( size_t sizeRequested ); + +/*Frees memory that was allocated in the external system -- higher overhead + */ +void +VMS_ext__free_in_ext( void *ptrToFree ); + + +MallocArrays * +VMS_ext__create_free_list(); + +void +VMS_ext__free_free_list(MallocArrays *freeLists ); + +#endif \ No newline at end of file diff -r c88ce1db91ef -r b0b93147adfb VMS.h --- a/VMS.h Tue Mar 13 10:02:06 2012 -0700 +++ b/VMS.h Tue Mar 13 18:28:04 2012 -0700 @@ -15,7 +15,7 @@ #include "Hash_impl/PrivateHash.h" #include "Histogram/Histogram.h" #include "Queue_impl/PrivateQueue.h" -#include "vmalloc.h" +#include "Services_Offered_by_VMS/Memory_Handling/vmalloc.h" #include #include @@ -24,7 +24,7 @@ // // Note: ALL defines are in other files, none are in here // -#include "Defines/VMS_defs__main.h" +#include "Defines/VMS_defs.h" //================================ Typedefs ================================= @@ -44,11 +44,11 @@ typedef struct _GateStruc GateStruc; -typedef SlaveVP * (*Sched_Assigner) ( void *, int ); //semEnv, coreIdx -typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv -typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv -typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv -typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); +typedef SlaveVP *(*SlaveAssigner) ( void *, int, SchedSlot *); //semEnv, coreIdx, slot for HW info +typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv +typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv +typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv +typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); //============================ HW Dependent Fns ================================ @@ -98,9 +98,10 @@ struct _SchedSlot { + int slotIdx; //needed by Holistic Model's data gathering int workIsDone; int needsSlaveAssigned; - SlaveVP *slaveAssignedToSlot; + SlaveVP *slaveAssignedToSlot; }; //SchedSlot @@ -140,7 +141,7 @@ */ typedef struct { - Sched_Assigner slaveAssigner; + SlaveAssigner slaveAssigner; RequestHandler requestHandler; SchedSlot ***allSchedSlots; @@ -149,13 +150,12 @@ void *semanticEnv; void *OSEventStruc; //for future, when add I/O to BLIS - MallocArrays *freeLists; + MallocArrays *freeLists; int32 amtOfOutstandingMem; //total currently allocated void *coreCtlrReturnPt;//addr to jump to to re-enter coreCtlr int32 setupComplete; - int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP int32 masterLock __align_to_cacheline__; GateStruc *workStealingGates[ NUM_CORES ]; //concurrent work-steal int32 workStealingLock; @@ -235,39 +235,6 @@ void VMS_SS__init(); -//Fix; -/*seed-slaveVP creation -- put box around language, have lang register stuff - with VMS. - have main program explicitly INIT Lang! -- makes more sense to - C programmers -- makes it clear that there's a transition. -(might need to have the pthreads remain waiting for - cond until work is scheduled) -Have main do call to tell language to perform work -- like did with DKU - -Ex: "HWSim__run_a_simulation(netlist, paramBag);" - "processID = SSR__run_program(seed_fn, seedData); " - "SSR__Wait_for_program_to_end(processID);" - "SSR__run_program_and_wait_till_it_ends(seed_fn, seedData);" - - allows multiple languages to be started, and programs run in several, - overlapped, or one program to be run that uses multiple langs..? - So, each program is in separate directory: - "HWSim_ArchDef__PingPong" "SSR_Program__Blocked_Matrix_Mult" - - Those programs can talk to each other, via VMS, by handles they each - return - "processIDs[0] = SSR__run_program(seed_fn1, seedData1);" - "processIDs[1] = SSR__run_program(seed_fn2, seedData2);" - "SSR__link_programs(processIDs, 2);" -or even - "processIDs[0] = Vthread__run_program(seed_fn1, seedData1);" - "processIDs[1] = SSR__run_program(seed_fn2, seedData2);" - "VMS__link_programs(processIDs, 2);" - Then, the programs just know they sync with other prog, but use own - lang's sync constructs -- VMS uses message system to establish tie-pt, - each lang defines what a tie-point means to it.. (work with the - diff semantics?) -*/ void VMS_SS__start_the_work_then_wait_until_done(); @@ -360,7 +327,7 @@ //========================= Probes ======================= -#include "Probes/probes.h" +#include "Services_Offered_by_VMS/Measurement_and_Stats/probes.h" //================================================ #endif /* _VMS_H */ diff -r c88ce1db91ef -r b0b93147adfb VMS__int.c --- a/VMS__int.c Tue Mar 13 10:02:06 2012 -0700 +++ b/VMS__int.c Tue Mar 13 18:28:04 2012 -0700 @@ -64,7 +64,7 @@ { //The request to master will cause this suspended Slv to get - // scheduled again at some future point -- to resume, core ctlr jumps + // assigned again at some future point -- to resume, core ctlr jumps // to the resume point (below), which causes restore of saved regs and // "return" from this call. //animatingSlv->resumeInstrPtr = &&ResumePt; @@ -181,8 +181,8 @@ VMS_int__strDup( char *str ) { char *retStr; + if( str == NULL ) return NULL; retStr = (char *)VMS_int__malloc( strlen(str) + 1 ); - if( str == NULL ) return str; strcpy( retStr, str ); return (char *)retStr; diff -r c88ce1db91ef -r b0b93147adfb VMS__startup_and_shutdown.c --- a/VMS__startup_and_shutdown.c Tue Mar 13 10:02:06 2012 -0700 +++ b/VMS__startup_and_shutdown.c Tue Mar 13 18:28:04 2012 -0700 @@ -43,7 +43,7 @@ * 1) Semantic layer first calls init_VMS, which creates masterEnv, and puts * the master Slv into the work-queue, ready for first "call" * 2) Semantic layer then does its own init, which creates the seed virt - * slave inside the semantic layer, ready to schedule it when + * slave inside the semantic layer, ready to assign it when * asked by the first run of the schedulingMaster. * *This part is bit weird because VMS really wants to be "always there", and @@ -52,7 +52,7 @@ * *The semantic layer is isolated from the VMS internals by making the * semantic layer do setup to a state that it's ready with its - * initial Slvs, ready to schedule them to slots when the schedulingMaster + * initial Slvs, ready to assign them to slots when the schedulingMaster * asks. Without this pattern, the semantic layer's setup would * have to modify slots directly to assign the initial virt-procrs, and put * them into the readyToAnimateQ itself, breaking the isolation completely. @@ -113,7 +113,7 @@ fprintf(output, "\n"); //Meta info gets set by calls from the language during its init, // and info registered by calls from inside the application - fprintf(output, "# Scheduler: %s\n", _VMSMasterEnv->metaInfo->schedulerInfo); + fprintf(output, "# Assigner: %s\n", _VMSMasterEnv->metaInfo->assignerInfo); //-------------------------- //Application @@ -260,9 +260,9 @@ void create_masterEnv() { MasterEnv *masterEnv; - VMSQueueStruc **readyToAnimateQs; + VMSQueueStruc **readyToAnimateQs; int coreIdx; - SlaveVP **masterVPs; + SlaveVP **masterVPs; SchedSlot ***allSchedSlots; //ptr to array of ptrs @@ -274,15 +274,15 @@ //After this, all other mallocs are VMS__malloc. _VMSMasterEnv->freeLists = VMS_ext__create_free_list(); + //===================== Only VMS__malloc after this ==================== - masterEnv = (MasterEnv*)_VMSMasterEnv; //Make a readyToAnimateQ for each core controller readyToAnimateQs = VMS_int__malloc( NUM_CORES * sizeof(VMSQueueStruc *) ); masterVPs = VMS_int__malloc( NUM_CORES * sizeof(SlaveVP *) ); - //One array for each core, 3 in array, core's masterVP scheds all + //One array for each core, several in array, core's masterVP scheds all allSchedSlots = VMS_int__malloc( NUM_CORES * sizeof(SchedSlot *) ); _VMSMasterEnv->numSlavesAlive = 0; //used to detect shut-down condition @@ -296,7 +296,6 @@ masterVPs[ coreIdx ] = VMS_int__create_slaveVP( (TopLevelFnPtr)&schedulingMaster, (void*)masterEnv ); masterVPs[ coreIdx ]->coreAnimatedBy = coreIdx; allSchedSlots[ coreIdx ] = create_sched_slots(); //makes for one core - _VMSMasterEnv->numMasterInARow[ coreIdx ] = 0; _VMSMasterEnv->workStealingGates[ coreIdx ] = NULL; } _VMSMasterEnv->readyToAnimateQs = readyToAnimateQs; @@ -313,19 +312,10 @@ MEAS__Make_Meas_Hists_for_Master_Lock_Meas; MEAS__Make_Meas_Hists_for_Malloc_Meas; MEAS__Make_Meas_Hists_for_Plugin_Meas; + MEAS__Make_Meas_Hists_for_Language; + + PROBES__Create_Probe_Bookkeeping_Vars; - #ifdef PROBES__TURN_ON_STATS_PROBES - _VMSMasterEnv->dynIntervalProbesInfo = - makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->intervalProbes), 200); - - _VMSMasterEnv->probeNameHashTbl = makeHashTable( 1000, &VMS_int__free ); - - //put creation time directly into master env, for fast retrieval - struct timeval timeStamp; - gettimeofday( &(timeStamp), NULL); - _VMSMasterEnv->createPtInSecs = - timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0); - #endif //======================================================================== } @@ -343,6 +333,7 @@ //Set state to mean "handling requests done, slot needs filling" schedSlots[i]->workIsDone = FALSE; schedSlots[i]->needsSlaveAssigned = TRUE; + schedSlots[i]->slotIdx = i; //quick retrieval of slot pos } return schedSlots; } @@ -394,7 +385,7 @@ void -VMS_SS__register_sched_assigner( Sched_Assigner schedAssigner ) +VMS_SS__register_sched_assigner( SlaveAssigner schedAssigner ) { _VMSMasterEnv->slaveAssigner = schedAssigner; } diff -r c88ce1db91ef -r b0b93147adfb vmalloc.c --- a/vmalloc.c Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -/* - * Copyright 2009 OpenSourceCodeStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - * Created on November 14, 2009, 9:07 PM - */ - -#include -#include -#include -#include -#include -#include - -#include "VMS.h" -#include "Histogram/Histogram.h" - -#define MAX_UINT64 0xFFFFFFFFFFFFFFFF - -//A MallocProlog is a head element if the HigherInMem variable is NULL -//A Chunk is free if the prevChunkInFreeList variable is NULL - -/* - * This calculates the container which fits the given size. - */ -inline -uint32 getContainer(size_t size) -{ - return (log2(size)-LOG128)/LOG54; -} - -/* - * Removes the first chunk of a freeList - * The chunk is removed but not set as free. There is no check if - * the free list is empty, so make sure this is not the case. - */ -inline -MallocProlog *removeChunk(MallocArrays* freeLists, uint32 containerIdx) -{ - MallocProlog** container = &freeLists->bigChunks[containerIdx]; - MallocProlog* removedChunk = *container; - *container = removedChunk->nextChunkInFreeList; - - if(removedChunk->nextChunkInFreeList) - removedChunk->nextChunkInFreeList->prevChunkInFreeList = - (MallocProlog*)container; - - if(*container == NULL) - { - if(containerIdx < 64) - freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); - else - freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); - } - - return removedChunk; -} - -/* - * Removes the first chunk of a freeList - * The chunk is removed but not set as free. There is no check if - * the free list is empty, so make sure this is not the case. - */ -inline -MallocProlog *removeSmallChunk(MallocArrays* freeLists, uint32 containerIdx) -{ - MallocProlog** container = &freeLists->smallChunks[containerIdx]; - MallocProlog* removedChunk = *container; - *container = removedChunk->nextChunkInFreeList; - - if(removedChunk->nextChunkInFreeList) - removedChunk->nextChunkInFreeList->prevChunkInFreeList = - (MallocProlog*)container; - - return removedChunk; -} - -inline -size_t getChunkSize(MallocProlog* chunk) -{ - return (uintptr_t)chunk->nextHigherInMem - - (uintptr_t)chunk - sizeof(MallocProlog); -} - -/* - * Removes a chunk from a free list. - */ -inline -void extractChunk(MallocProlog* chunk, MallocArrays *freeLists) -{ - chunk->prevChunkInFreeList->nextChunkInFreeList = chunk->nextChunkInFreeList; - if(chunk->nextChunkInFreeList) - chunk->nextChunkInFreeList->prevChunkInFreeList = chunk->prevChunkInFreeList; - - //The last element in the list points to the container. If the container points - //to NULL the container is empty - if(*((void**)(chunk->prevChunkInFreeList)) == NULL && getChunkSize(chunk) >= BIG_LOWER_BOUND) - { - //Find the approppiate container because we do not know it - uint64 containerIdx = ((uintptr_t)chunk->prevChunkInFreeList - (uintptr_t)freeLists->bigChunks) >> 3; - if(containerIdx < (uint32)64) - freeLists->bigChunksSearchVector[0] &= ~((uint64)1 << containerIdx); - if(containerIdx < 128 && containerIdx >=64) - freeLists->bigChunksSearchVector[1] &= ~((uint64)1 << (containerIdx-64)); - - } -} - -/* - * Merges two chunks. - * Chunk A has to be before chunk B in memory. Both have to be removed from - * a free list - */ -inline -MallocProlog *mergeChunks(MallocProlog* chunkA, MallocProlog* chunkB) -{ - chunkA->nextHigherInMem = chunkB->nextHigherInMem; - chunkB->nextHigherInMem->nextLowerInMem = chunkA; - return chunkA; -} -/* - * Inserts a chunk into a free list. - */ -inline -void insertChunk(MallocProlog* chunk, MallocProlog** container) -{ - chunk->nextChunkInFreeList = *container; - chunk->prevChunkInFreeList = (MallocProlog*)container; - if(*container) - (*container)->prevChunkInFreeList = chunk; - *container = chunk; -} - -/* - * Divides the chunk that a new chunk of newSize is created. - * There is no size check, so make sure the size value is valid. - */ -inline -MallocProlog *divideChunk(MallocProlog* chunk, size_t newSize) -{ - MallocProlog* newChunk = (MallocProlog*)((uintptr_t)chunk->nextHigherInMem - - newSize - sizeof(MallocProlog)); - - newChunk->nextLowerInMem = chunk; - newChunk->nextHigherInMem = chunk->nextHigherInMem; - - chunk->nextHigherInMem->nextLowerInMem = newChunk; - chunk->nextHigherInMem = newChunk; - - return newChunk; -} - -/* - * Search for chunk in the list of big chunks. Split the block if it's too big - */ -inline -MallocProlog *searchChunk(MallocArrays *freeLists, size_t sizeRequested, uint32 containerIdx) -{ - MallocProlog* foundChunk; - - uint64 searchVector = freeLists->bigChunksSearchVector[0]; - //set small chunk bits to zero - searchVector &= MAX_UINT64 << containerIdx; - containerIdx = __builtin_ffsl(searchVector); - - if(containerIdx == 0) - { - searchVector = freeLists->bigChunksSearchVector[1]; - containerIdx = __builtin_ffsl(searchVector); - if(containerIdx == 0) - { - printf("VMS malloc failed: low memory"); - exit(1); - } - containerIdx += 64; - } - containerIdx--; - - - foundChunk = removeChunk(freeLists, containerIdx); - size_t chunkSize = getChunkSize(foundChunk); - - //If the new chunk is larger than the requested size: split - if(chunkSize > sizeRequested + 2 * sizeof(MallocProlog) + BIG_LOWER_BOUND) - { - MallocProlog *newChunk = divideChunk(foundChunk,sizeRequested); - containerIdx = getContainer(getChunkSize(foundChunk)) - 1; - insertChunk(foundChunk,&freeLists->bigChunks[containerIdx]); - if(containerIdx < 64) - freeLists->bigChunksSearchVector[0] |= ((uint64)1 << containerIdx); - else - freeLists->bigChunksSearchVector[1] |= ((uint64)1 << (containerIdx-64)); - foundChunk = newChunk; - } - - return foundChunk; -} - - -/* - * This is sequential code, meant to only be called from the Master, not from - * any slave Slvs. - */ -void *VMS_int__malloc( size_t sizeRequested ) - { - //============================= MEASUREMENT STUFF ======================== - #ifdef MEAS__TIME_MALLOC - int32 startStamp, endStamp; - saveLowTimeStampCountInto( startStamp ); - #endif - //======================================================================== - - MallocArrays* freeLists = _VMSMasterEnv->freeLists; - MallocProlog* foundChunk; - - //Return a small chunk if the requested size is smaller than 128B - if(sizeRequested <= LOWER_BOUND) - { - uint32 freeListIdx = (sizeRequested-1)/SMALL_CHUNK_SIZE; - if(freeLists->smallChunks[freeListIdx] == NULL) - foundChunk = searchChunk(freeLists, SMALL_CHUNK_SIZE*(freeListIdx+1), 0); - else - foundChunk = removeSmallChunk(freeLists, freeListIdx); - - //Mark as allocated - foundChunk->prevChunkInFreeList = NULL; - return foundChunk + 1; - } - - //Calculate the expected container. Start one higher to have a Chunk that's - //always big enough. - uint32 containerIdx = getContainer(sizeRequested); - - if(freeLists->bigChunks[containerIdx] == NULL) - foundChunk = searchChunk(freeLists, sizeRequested, containerIdx); - else - foundChunk = removeChunk(freeLists, containerIdx); - - //Mark as allocated - foundChunk->prevChunkInFreeList = NULL; - - //============================= MEASUREMENT STUFF ======================== - #ifdef MEAS__TIME_MALLOC - saveLowTimeStampCountInto( endStamp ); - addIntervalToHist( startStamp, endStamp, _VMSMasterEnv->mallocTimeHist ); - #endif - //======================================================================== - - //skip over the prolog by adding its size to the pointer return - return foundChunk + 1; - } - -/* - * This is sequential code, meant to only be called from the Master, not from - * any slave Slvs. - */ -void -VMS_int__free( void *ptrToFree ) - { - - MEAS__Capture_Pre_Free_Point; - - MallocArrays* freeLists = _VMSMasterEnv->freeLists; - MallocProlog *chunkToFree = (MallocProlog*)ptrToFree - 1; - uint32 containerIdx; - - //Check for free neighbors - if(chunkToFree->nextLowerInMem) - { - if(chunkToFree->nextLowerInMem->prevChunkInFreeList != NULL) - {//Chunk is not allocated - extractChunk(chunkToFree->nextLowerInMem, freeLists); - chunkToFree = mergeChunks(chunkToFree->nextLowerInMem, chunkToFree); - } - } - if(chunkToFree->nextHigherInMem) - { - if(chunkToFree->nextHigherInMem->prevChunkInFreeList != NULL) - {//Chunk is not allocated - extractChunk(chunkToFree->nextHigherInMem, freeLists); - chunkToFree = mergeChunks(chunkToFree, chunkToFree->nextHigherInMem); - } - } - - size_t chunkSize = getChunkSize(chunkToFree); - if(chunkSize < BIG_LOWER_BOUND) - { - containerIdx = (chunkSize/SMALL_CHUNK_SIZE)-1; - if(containerIdx > SMALL_CHUNK_COUNT-1) - containerIdx = SMALL_CHUNK_COUNT-1; - insertChunk(chunkToFree, &freeLists->smallChunks[containerIdx]); - } - else - { - containerIdx = getContainer(getChunkSize(chunkToFree)) - 1; - insertChunk(chunkToFree, &freeLists->bigChunks[containerIdx]); - if(containerIdx < 64) - freeLists->bigChunksSearchVector[0] |= (uint64)1 << containerIdx; - else - freeLists->bigChunksSearchVector[1] |= (uint64)1 << (containerIdx-64); - } - - MEAS__Capture_Post_Free_Point; - } - -/* - * Designed to be called from the main thread outside of VMS, during init - */ -MallocArrays * -VMS_ext__create_free_list() -{ - //Initialize containers for small chunks and fill with zeros - _VMSMasterEnv->freeLists = (MallocArrays*)malloc( sizeof(MallocArrays) ); - MallocArrays *freeLists = _VMSMasterEnv->freeLists; - - freeLists->smallChunks = - (MallocProlog**)malloc(SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); - memset((void*)freeLists->smallChunks, - 0,SMALL_CHUNK_COUNT*sizeof(MallocProlog*)); - - //Calculate number of containers for big chunks - uint32 container = getContainer(MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE)+1; - freeLists->bigChunks = (MallocProlog**)malloc(container*sizeof(MallocProlog*)); - memset((void*)freeLists->bigChunks,0,container*sizeof(MallocProlog*)); - freeLists->containerCount = container; - - //Create first element in lastContainer - MallocProlog *firstChunk = malloc( MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE ); - if( firstChunk == NULL ) {printf("Can't allocate initial memory\n"); exit(1);} - freeLists->memSpace = firstChunk; - - //Touch memory to avoid page faults - void *ptr,*endPtr; - endPtr = (void*)firstChunk+MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE; - for(ptr = firstChunk; ptr < endPtr; ptr+=PAGE_SIZE) - { - *(char*)ptr = 0; - } - - firstChunk->nextLowerInMem = NULL; - firstChunk->nextHigherInMem = (MallocProlog*)((uintptr_t)firstChunk + - MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE - sizeof(MallocProlog)); - firstChunk->nextChunkInFreeList = NULL; - //previous element in the queue is the container - firstChunk->prevChunkInFreeList = &freeLists->bigChunks[container-2]; - - freeLists->bigChunks[container-2] = firstChunk; - //Insert into bit search list - if(container <= 65) - { - freeLists->bigChunksSearchVector[0] = ((uint64)1 << (container-2)); - freeLists->bigChunksSearchVector[1] = 0; - } - else - { - freeLists->bigChunksSearchVector[0] = 0; - freeLists->bigChunksSearchVector[1] = ((uint64)1 << (container-66)); - } - - //Create dummy chunk to mark the top of stack this is of course - //never freed - MallocProlog *dummyChunk = firstChunk->nextHigherInMem; - dummyChunk->nextHigherInMem = dummyChunk+1; - dummyChunk->nextLowerInMem = NULL; - dummyChunk->nextChunkInFreeList = NULL; - dummyChunk->prevChunkInFreeList = NULL; - - return freeLists; - } - - -/*Designed to be called from the main thread outside of VMS, during cleanup - */ -void -VMS_ext__free_free_list( MallocArrays *freeLists ) - { - free(freeLists->memSpace); - free(freeLists->bigChunks); - free(freeLists->smallChunks); - - } - diff -r c88ce1db91ef -r b0b93147adfb vmalloc.h --- a/vmalloc.h Tue Mar 13 10:02:06 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright 2009 OpenSourceCodeStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - * Created on November 14, 2009, 9:07 PM - */ - -#ifndef _VMALLOC_H -#define _VMALLOC_H - -#include -#include -#include "VMS_primitive_data_types.h" - -#define SMALL_CHUNK_SIZE 32 -#define SMALL_CHUNK_COUNT 4 -#define LOWER_BOUND 128 //Biggest chunk size that is created for the small chunks -#define BIG_LOWER_BOUND 160 //Smallest chunk size that is created for the big chunks - -#define LOG54 0.3219280948873623 -#define LOG128 7 - -typedef struct _MallocProlog MallocProlog; - -struct _MallocProlog - { - MallocProlog *nextChunkInFreeList; - MallocProlog *prevChunkInFreeList; - MallocProlog *nextHigherInMem; - MallocProlog *nextLowerInMem; - }; -//MallocProlog - - typedef struct MallocArrays MallocArrays; - - struct MallocArrays - { - MallocProlog **smallChunks; - MallocProlog **bigChunks; - uint64 bigChunksSearchVector[2]; - void *memSpace; - uint32 containerCount; - }; - //MallocArrays - -typedef struct - { - MallocProlog *firstChunkInFreeList; - int32 numInList; //TODO not used - } -FreeListHead; - -void * -VMS_int__malloc( size_t sizeRequested ); -#define VMS_PI__malloc VMS_int__malloc -#define VMS_WL__malloc VMS_int__malloc /*TODO: Bug -- Not protected!! */ -#define VMS_App__malloc VMS_int__malloc /*TODO: Bug -- Not protected!! */ - -void * -VMS_int__malloc_aligned( size_t sizeRequested ); -#define VMS_PI__malloc_aligned VMS_int__malloc_aligned -#define VMS_WL__malloc_aligned VMS_int__malloc_aligned - -void -VMS_int__free( void *ptrToFree ); -#define VMS_PI__free VMS_int__free -#define VMS_WL__free VMS_int__free /*TODO: Bug -- Not protected!! */ -#define VMS_App__free VMS_int__free /*TODO: Bug -- Not protected!! */ - - - -/*Allocates memory from the external system -- higher overhead - */ -void * -VMS_ext__malloc_in_ext( size_t sizeRequested ); - -/*Frees memory that was allocated in the external system -- higher overhead - */ -void -VMS_ext__free_in_ext( void *ptrToFree ); - - -MallocArrays * -VMS_ext__create_free_list(); - -void -VMS_ext__free_free_list(MallocArrays *freeLists ); - -#endif \ No newline at end of file