# HG changeset patch # User Merten Sach # Date 1320242369 -3600 # Node ID d7c0c0a8187acea78f4d2af848b8cd34bd6bb0e3 # Parent 395f58384a5ccb67de20c6f20ae10b7879853cde# Parent ad8213a8e9164e07fa301958c38d9972ddc65a7a Merged default branch diff -r 395f58384a5c -r d7c0c0a8187a .hgtags --- a/.hgtags Thu Sep 15 17:31:33 2011 +0200 +++ b/.hgtags Wed Nov 02 14:59:29 2011 +0100 @@ -1,6 +1,1 @@ 9c3107044f86c36fea3a8f72f64910b1363555be Dec27_2010_about_to_add_sched_record -97e26095c01fef53783d2d89e11575856ce243c5 V0 -21c95d402fe66570067000e484bfec9a5d92c9d0 malloc_touch -42d015d48eebc7ba49b24fa5f24cb1e66244e5e7 malloc_touch -42d015d48eebc7ba49b24fa5f24cb1e66244e5e7 malloc_touch -0000000000000000000000000000000000000000 malloc_touch diff -r 395f58384a5c -r d7c0c0a8187a VMS.c --- a/VMS.c Thu Sep 15 17:31:33 2011 +0200 +++ b/VMS.c Wed Nov 02 14:59:29 2011 +0100 @@ -118,15 +118,15 @@ //============================= MEASUREMENT STUFF ======================== #ifdef MEAS__TIME_MALLOC - _VMSMasterEnv->mallocTimeHist = makeFixedBinHistExt( 100, 0, 100, + _VMSMasterEnv->mallocTimeHist = makeFixedBinHistExt( 100, 0, 30, "malloc_time_hist"); - _VMSMasterEnv->freeTimeHist = makeFixedBinHistExt( 80, 0, 100, + _VMSMasterEnv->freeTimeHist = makeFixedBinHistExt( 100, 0, 30, "free_time_hist"); #endif #ifdef MEAS__TIME_PLUGIN - _VMSMasterEnv->reqHdlrLowTimeHist = makeFixedBinHistExt( 1000, 0, 100, + _VMSMasterEnv->reqHdlrLowTimeHist = makeFixedBinHistExt( 100, 0, 200, "plugin_low_time_hist"); - _VMSMasterEnv->reqHdlrHighTimeHist = makeFixedBinHistExt( 1000, 0, 100, + _VMSMasterEnv->reqHdlrHighTimeHist = makeFixedBinHistExt( 100, 0, 200, "plugin_high_time_hist"); #endif //======================================================================== diff -r 395f58384a5c -r d7c0c0a8187a VMS.h --- a/VMS.h Thu Sep 15 17:31:33 2011 +0200 +++ b/VMS.h Wed Nov 02 14:59:29 2011 +0100 @@ -1,627 +1,627 @@ -/* - * Copyright 2009 OpenSourceStewardshipFoundation.org - * Licensed under GNU General Public License version 2 - * - * Author: seanhalle@yahoo.com - * - */ - -#ifndef _VMS_H -#define _VMS_H -#define _GNU_SOURCE - -#include "VMS_primitive_data_types.h" -#include "Queue_impl/PrivateQueue.h" -#include "Histogram/Histogram.h" -#include "DynArray/DynArray.h" -#include "Hash_impl/PrivateHash.h" -#include "vmalloc.h" -#include "Counters/Counters.h" -#include "dependency.h" - -#include -#include - - -//=============================== Debug =================================== -// -//When SEQUENTIAL is defined, VMS does sequential exe in the main thread -// It still does co-routines and all the mechanisms are the same, it just -// has only a single thread and animates VPs one at a time -//#define SEQUENTIAL - -//#define USE_WORK_STEALING - -//turns on the probe-instrumentation in the application -- when not -// defined, the calls to the probe functions turn into comments -//#define STATS__ENABLE_PROBES -//#define TURN_ON_DEBUG_PROBES - -//These defines turn types of bug messages on and off -// be sure debug messages are un-commented (next block of defines) -#define dbgAppFlow FALSE /* Top level flow of application code -- general*/ -#define dbgProbes FALSE /* for issues inside probes themselves*/ -#define dbgB2BMaster FALSE /* in coreloop, back to back master VPs*/ -#define dbgRqstHdlr FALSE /* in request handler code*/ -#define dbgDependency TRUE /* in request handler code, print dependencies */ - -//Comment or un- the substitute half to turn on/off types of debug message -#define DEBUG( bool, msg) \ - if( bool){ printf(msg); fflush(stdin);} -#define DEBUG1( bool, msg, param) \ - if(bool){printf(msg, param); fflush(stdin);} -#define DEBUG2( bool, msg, p1, p2) \ - if(bool) {printf(msg, p1, p2); fflush(stdin);} - -#define ERROR(msg) printf(msg); -#define ERROR1(msg, param) printf(msg, param); -#define ERROR2(msg, p1, p2) printf(msg, p1, p2); - -//=========================== STATS ======================= - - //when MEAS__TIME_STAMP_SUSP is defined, causes code to be inserted and - // compiled-in that saves the low part of the time stamp count just before - // suspending a processor and just after resuming that processor. It is - // saved into a field added to VirtProcr. Have to sanity-check for - // rollover of low portion into high portion. -//#define MEAS__TIME_STAMP_SUSP -//#define MEAS__TIME_MASTER -//#define MEAS__TIME_PLUGIN -//#define MEAS__TIME_MALLOC -//#define MEAS__TIME_MASTER_LOCK -//#define MEAS__NUM_TIMES_TO_RUN 100000 - - //For code that calculates normalization-offset between TSC counts of - // different cores. -//#define NUM_TSC_ROUND_TRIPS 10 - -#define MEAS__PERF_COUNTERS -#define DETECT_DEPENDENCIES - -//========================= Hardware related Constants ===================== - //This value is the number of hardware threads in the shared memory - // machine -#define NUM_CORES 2 - - // tradeoff amortizing master fixed overhead vs imbalance potential - // when work-stealing, can make bigger, at risk of losing cache affinity -#define NUM_SCHED_SLOTS 5 - -#define MIN_WORK_UNIT_CYCLES 20000 - -#define MASTERLOCK_RETRIES 10000 - - // stack size in virtual processors created -#define VIRT_PROCR_STACK_SIZE 0x8000 /* 32K */ - - // memory for VMS__malloc -#define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x10000000 /* 256M */ - -#define CACHE_LINE 64 -#define PAGE_SIZE 4096 - - -//============================== - -#define SUCCESS 0 - -#define writeVMSQ writePrivQ -#define readVMSQ readPrivQ -#define makeVMSQ makeVMSPrivQ -#define numInVMSQ numInPrivQ -#define VMSQueueStruc PrivQueueStruc - - - -//=========================================================================== -typedef unsigned long long TSCount; - -typedef struct _SchedSlot SchedSlot; -typedef struct _VMSReqst VMSReqst; -typedef struct _VirtProcr VirtProcr; -typedef struct _IntervalProbe IntervalProbe; -typedef struct _GateStruc GateStruc; - - -typedef VirtProcr * (*SlaveScheduler) ( void *, int ); //semEnv, coreIdx -typedef void (*RequestHandler) ( VirtProcr *, void * ); //prWReqst, semEnv -typedef void (*VirtProcrFnPtr) ( void *, VirtProcr * ); //initData, animPr -typedef void VirtProcrFn ( void *, VirtProcr * ); //initData, animPr -typedef void (*ResumePrFnPtr) ( VirtProcr *, void * ); - - -//============= Requests =========== -// - -enum VMSReqstType //avoid starting enums at 0, for debug reasons - { - semantic = 1, - createReq, - dissipate, - VMSSemantic //goes with VMSSemReqst below - }; - -struct _VMSReqst - { - enum VMSReqstType reqType;//used for dissipate and in future for IO requests - void *semReqData; - - VMSReqst *nextReqst; - }; -//VMSReqst - -enum VMSSemReqstType //These are equivalent to semantic requests, but for - { // VMS's services available directly to app, like OS - createProbe = 1, // and probe services -- like a VMS-wide built-in lang - openFile, - otherIO - }; - -typedef struct - { enum VMSSemReqstType reqType; - VirtProcr *requestingPr; - char *nameStr; //for create probe - } - VMSSemReq; - - -//==================== Core data structures =================== - -struct _SchedSlot - { - int workIsDone; - int needsProcrAssigned; - VirtProcr *procrAssignedToSlot; - }; -//SchedSlot - -/*WARNING: re-arranging this data structure could cause VP switching - * assembly code to fail -- hard-codes offsets of fields - */ -struct _VirtProcr - { int procrID; //for debugging -- count up each time create - int coreAnimatedBy; - void *startOfStack; - void *stackPtr; - void *framePtr; - void *nextInstrPt; - - void *coreLoopStartPt; //allows proto-runtime to be linked later - void *coreLoopFramePtr; //restore before jmp back to core loop - void *coreLoopStackPtr; //restore before jmp back to core loop - - void *initialData; - - SchedSlot *schedSlot; - VMSReqst *requests; - - void *semanticData; //this livesUSE_GNU here for the life of VP - void *dataRetFromReq;//values returned from plugin to VP go here - - //=========== MEASUREMENT STUFF ========== - #ifdef MEAS__TIME_STAMP_SUSP - unsigned int preSuspTSCLow; - unsigned int postSuspTSCLow; - #endif - #ifdef MEAS__TIME_MASTER /* in VirtProcr because multiple masterVPs*/ - unsigned int startMasterTSCLow;USE_GNU - unsigned int endMasterTSCLow; - #endif - #ifdef MEAS__PERF_COUNTERS // - CounterRecord** counter_history; - PrivDynArrayInfo* counter_history_array_info; - #endif - //======================================== - - float64 createPtInSecs; //have space but don't use on some configs - }; -//VirtProcr - - -/*WARNING: re-arranging this data structure could cause VP-switching - * assembly code to fail -- hard-codes offsets of fields - * (because -O3 messes with things otherwise) - */ -typedef struct - { - SlaveScheduler slaveScheduler; - RequestHandler requestHandler; - - SchedSlot ***allSchedSlots; - VMSQueueStruc **readyToAnimateQs; - VirtProcr **masterVPs; - - void *semanticEnv; - void *OSEventStruc; //for future, when add I/O to BLIS - MallocProlog *freeListHead; - int32 amtOfOutstandingMem; //total currently allocated - - void *coreLoopReturnPt;//addr to jump to to re-enter coreLoop - - int32 setupComplete; - volatile int32 masterLock; - - int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP - GateStruc *workStealingGates[ NUM_CORES ]; //concurrent work-steal - int32 workStealingLock; - - int32 numProcrsCreated; //gives ordering to processor creation - - //=========== MEASUREMENT STUFF ============= - IntervalProbe **intervalProbes; - PrivDynArrayInfo *dynIntervalProbesInfo; - HashTable *probeNameHashTbl; - int32 masterCreateProbeID; - float64 createPtInSecs; - Histogram **measHists; - PrivDynArrayInfo *measHistsInfo; - #ifdef MEAS__TIME_PLUGIN - Histogram *reqHdlrLowTimeHist; - Histogram *reqHdlrHighTimeHist; - #endif - #ifdef MEAS__TIME_MALLOC - Histogram *mallocTimeHist; - Histogram *freeTimeHist; - #endif - #ifdef MEAS__TIME_MASTER_LOCK - Histogram *masterLockLowTimeHist; - Histogram *masterLockHighTimeHist; - #endif - #ifdef MEAS__PERF_COUNTERS - int cycles_counter_fd[NUM_CORES]; - int instrs_counter_fd[NUM_CORES]; - FILE* counteroutput; - #endif - #ifdef DETECT_DEPENDENCIES - Dependency** dependencies; - PrivDynArrayInfo* dependenciesInfo; - #endif - #ifdef MEAS__PERF_COUNTERS // - CounterRecord** counter_history; - PrivDynArrayInfo* counter_history_array_info; - #endif - } -MasterEnv; - -//========================= Extra Stuff Data Strucs ======================= -typedef struct - { - - } -VMSExcp; - -struct _GateStruc - { - int32 gateClosed; - int32 preGateProgress; - int32 waitProgress; - int32 exitProgress; - }; -//GateStruc - -//======================= OS Thread related =============================== - -void * coreLoop( void *paramsIn ); //standard PThreads fn prototype -void * coreLoop_Seq( void *paramsIn ); //standard PThreads fn prototype -void masterLoop( void *initData, VirtProcr *masterPr ); - - -typedef struct - { - void *endThdPt; - unsigned int coreNum; - } -ThdParams; - -pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state -ThdParams *coreLoopThdParams [ NUM_CORES ]; -pthread_mutex_t suspendLock; -pthread_cond_t suspend_cond; - - - -//===================== Global Vars =================== - -volatile MasterEnv *_VMSMasterEnv; - - - - -//=========================== Function Prototypes ========================= - - -//========== Setup and shutdown ========== -void -VMS__init(); - -void -VMS__init_Seq(); - -void -VMS__start_the_work_then_wait_until_done(); - -void -VMS__start_the_work_then_wait_until_done_Seq(); - -inline VirtProcr * -VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); - -void -VMS__dissipate_procr( VirtProcr *procrToDissipate ); - - //Use this to create processor inside entry point & other places outside - // the VMS system boundary (IE, not run in slave nor Master) -VirtProcr * -VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); - -void -VMS_ext__dissipate_procr( VirtProcr *procrToDissipate ); - -void -VMS__throw_exception( char *msgStr, VirtProcr *reqstPr, VMSExcp *excpData ); - -void -VMS__shutdown(); - -void -VMS__cleanup_at_end_of_shutdown(); - -void * -VMS__give_sem_env_for( VirtProcr *animPr ); - - -//============== Request Related =============== - -void -VMS__suspend_procr( VirtProcr *callingPr ); - -inline void -VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, VirtProcr *callingPr ); - -/*inline*/ __attribute__ ((noinline)) void -VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ); - -void -VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr ); - -void /*inline**/ __attribute__ ((noinline)) -VMS__send_dissipate_req( VirtProcr *prToDissipate ); - -/*inline**/ __attribute__ ((noinline)) void -VMS__send_VMSSem_request( void *semReqData, VirtProcr *callingPr ); - -VMSReqst * -VMS__take_next_request_out_of( VirtProcr *procrWithReq ); - -inline void * -VMS__take_sem_reqst_from( VMSReqst *req ); - -void inline -VMS__handle_VMSSemReq( VMSReqst *req, VirtProcr *requestingPr, void *semEnv, - ResumePrFnPtr resumePrFnPtr ); - -//======================== STATS ====================== - -//===== RDTSC wrapper ===== //Also runs with x86_64 code - -#define saveTimeStampCountInto(low, high) \ - asm volatile("RDTSC; \ - movl %%eax, %0; \ - movl %%edx, %1;" \ - /* outputs */ : "=m" (low), "=m" (high)\ - /* inputs */ : \ - /* clobber */ : "%eax", "%edx" \ - ); - -#define saveLowTimeStampCountInto(low) \ - asm volatile("RDTSC; \ - movl %%eax, %0;" \ - /* outputs */ : "=m" (low) \ - /* inputs */ : \ - /* clobber */ : "%eax", "%edx" \ - ); - -//==================== -#define makeAMeasHist( idx, name, numBins, startVal, binWidth ) \ - makeHighestDynArrayIndexBeAtLeast( _VMSMasterEnv->measHistsInfo, idx ); \ - _VMSMasterEnv->measHists[idx] = \ - makeFixedBinHist( numBins, startVal, binWidth, name ); - -#define saveCyclesAndInstrs(core,cycles,instrs) do{ \ - int cycles_fd = _VMSMasterEnv->cycles_counter_fd[core]; \ - int instrs_fd = _VMSMasterEnv->instrs_counter_fd[core]; \ - int nread; \ - \ - nread = read(cycles_fd,&(cycles),sizeof(cycles)); \ - if(nread<0){ \ - perror("Error reading cycles counter"); \ - cycles = 0; \ - } \ - \ - nread = read(instrs_fd,&(instrs),sizeof(instrs)); \ - if(nread<0){ \ - perror("Error reading cycles counter"); \ - instrs = 0; \ - } \ -} while (0) - -#define getReturnAddressBeforeLibraryCall(vp_ptr, res_ptr) do{ \ -void* frame_ptr0 = vp_ptr->framePtr; \ -void* frame_ptr1 = *((void**)frame_ptr0); \ -void* frame_ptr2 = *((void**)frame_ptr1); \ -void* frame_ptr3 = *((void**)frame_ptr2); \ -void* ret_addr = *((void**)frame_ptr3 + 1); \ -*res_ptr = ret_addr; \ -} while (0) - -#define MEAS__SUB_CREATE /*turn on/off subtraction of create from plugin*/ - -#ifdef VPTHREAD - -//VPThread -#define createHistIdx 1 -#define mutexLockHistIdx 2 -#define mutexUnlockHistIdx 3 -#define condWaitHistIdx 4 -#define condSignalHistIdx 5 - -#define MakeTheMeasHists() \ - _VMSMasterEnv->measHistsInfo = \ - makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \ - makeAMeasHist( createHistIdx, "create", 250, 0, 100 ) \ - makeAMeasHist( mutexLockHistIdx, "mutex_lock", 50, 0, 100 ) \ - makeAMeasHist( mutexUnlockHistIdx, "mutex_unlock", 50, 0, 100 ) \ - makeAMeasHist( condWaitHistIdx, "cond_wait", 50, 0, 100 ) \ - makeAMeasHist( condSignalHistIdx, "cond_signal", 50, 0, 100 ) - -#endif - - -#ifdef VCILK - -//VCilk -#define spawnHistIdx 1 -#define syncHistIdx 2 - -#define MakeTheMeasHists() \ - _VMSMasterEnv->measHistsInfo = \ - makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \ - makeAMeasHist( spawnHistIdx, "Spawn", 50, 0, 200 ) \ - makeAMeasHist( syncHistIdx, "Sync", 50, 0, 200 ) - - -#endif - -#ifdef SSR - -//SSR -#define SendFromToHistIdx 1 -#define SendOfTypeHistIdx 2 -#define ReceiveFromToHistIdx 3 -#define ReceiveOfTypeHistIdx 4 - -#define MakeTheMeasHists() \ - _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 ) - -#endif - -//=========================================================================== -//VPThread - - -#define Meas_startCreate \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endCreate \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ createHistIdx ] ); - -#define Meas_startMutexLock \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endMutexLock \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ mutexLockHistIdx ] ); - -#define Meas_startMutexUnlock \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endMutexUnlock \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ mutexUnlockHistIdx ] ); - -#define Meas_startCondWait \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endCondWait \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ condWaitHistIdx ] ); - -#define Meas_startCondSignal \ - int32 startStamp, endStamp; \ - saveLowTimeStampCountInto( startStamp ); \ - -#define Meas_endCondSignal \ - saveLowTimeStampCountInto( endStamp ); \ - addIntervalToHist( startStamp, endStamp, \ - _VMSMasterEnv->measHists[ condSignalHistIdx ] ); - -//=========================================================================== -// VCilk -#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 ] ); - -//=========================================================================== -// SSR -#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 ] ); - -//===== - -#include "ProcrContext.h" -#include "probes.h" -#include "vutilities.h" - -#endif /* _VMS_H */ - +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _VMS_H +#define _VMS_H +#define _GNU_SOURCE + +#include "VMS_primitive_data_types.h" +#include "Queue_impl/PrivateQueue.h" +#include "Histogram/Histogram.h" +#include "DynArray/DynArray.h" +#include "Hash_impl/PrivateHash.h" +#include "vmalloc.h" +#include "Counters/Counters.h" +#include "dependency.h" + +#include +#include + + +//=============================== Debug =================================== +// +//When SEQUENTIAL is defined, VMS does sequential exe in the main thread +// It still does co-routines and all the mechanisms are the same, it just +// has only a single thread and animates VPs one at a time +//#define SEQUENTIAL + +//#define USE_WORK_STEALING + +//turns on the probe-instrumentation in the application -- when not +// defined, the calls to the probe functions turn into comments +//#define STATS__ENABLE_PROBES +//#define TURN_ON_DEBUG_PROBES + +//These defines turn types of bug messages on and off +// be sure debug messages are un-commented (next block of defines) +#define dbgAppFlow FALSE /* Top level flow of application code -- general*/ +#define dbgProbes FALSE /* for issues inside probes themselves*/ +#define dbgB2BMaster FALSE /* in coreloop, back to back master VPs*/ +#define dbgRqstHdlr FALSE /* in request handler code*/ +#define dbgDependency TRUE /* in request handler code, print dependencies */ + +//Comment or un- the substitute half to turn on/off types of debug message +#define DEBUG( bool, msg) \ + if( bool){ printf(msg); fflush(stdin);} +#define DEBUG1( bool, msg, param) \ + if(bool){printf(msg, param); fflush(stdin);} +#define DEBUG2( bool, msg, p1, p2) \ + if(bool) {printf(msg, p1, p2); fflush(stdin);} + +#define ERROR(msg) printf(msg); +#define ERROR1(msg, param) printf(msg, param); +#define ERROR2(msg, p1, p2) printf(msg, p1, p2); + +//=========================== STATS ======================= + + //when MEAS__TIME_STAMP_SUSP is defined, causes code to be inserted and + // compiled-in that saves the low part of the time stamp count just before + // suspending a processor and just after resuming that processor. It is + // saved into a field added to VirtProcr. Have to sanity-check for + // rollover of low portion into high portion. +//#define MEAS__TIME_STAMP_SUSP +//#define MEAS__TIME_MASTER +//#define MEAS__TIME_PLUGIN +//#define MEAS__TIME_MALLOC +//#define MEAS__TIME_MASTER_LOCK +//#define MEAS__NUM_TIMES_TO_RUN 100000 + + //For code that calculates normalization-offset between TSC counts of + // different cores. +//#define NUM_TSC_ROUND_TRIPS 10 + +#define MEAS__PERF_COUNTERS +#define DETECT_DEPENDENCIES + +//========================= Hardware related Constants ===================== + //This value is the number of hardware threads in the shared memory + // machine +//#define NUM_CORES 8 + + // tradeoff amortizing master fixed overhead vs imbalance potential + // when work-stealing, can make bigger, at risk of losing cache affinity +#define NUM_SCHED_SLOTS 5 + +#define MIN_WORK_UNIT_CYCLES 20000 + +#define MASTERLOCK_RETRIES 10000 + + // stack size in virtual processors created +#define VIRT_PROCR_STACK_SIZE 0x8000 /* 32K */ + + // memory for VMS__malloc +#define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x10000000 /* 256M */ + +#define CACHE_LINE 64 +#define PAGE_SIZE 4096 + + +//============================== + +#define SUCCESS 0 + +#define writeVMSQ writePrivQ +#define readVMSQ readPrivQ +#define makeVMSQ makeVMSPrivQ +#define numInVMSQ numInPrivQ +#define VMSQueueStruc PrivQueueStruc + + + +//=========================================================================== +typedef unsigned long long TSCount; + +typedef struct _SchedSlot SchedSlot; +typedef struct _VMSReqst VMSReqst; +typedef struct _VirtProcr VirtProcr; +typedef struct _IntervalProbe IntervalProbe; +typedef struct _GateStruc GateStruc; + + +typedef VirtProcr * (*SlaveScheduler) ( void *, int ); //semEnv, coreIdx +typedef void (*RequestHandler) ( VirtProcr *, void * ); //prWReqst, semEnv +typedef void (*VirtProcrFnPtr) ( void *, VirtProcr * ); //initData, animPr +typedef void VirtProcrFn ( void *, VirtProcr * ); //initData, animPr +typedef void (*ResumePrFnPtr) ( VirtProcr *, void * ); + + +//============= Requests =========== +// + +enum VMSReqstType //avoid starting enums at 0, for debug reasons + { + semantic = 1, + createReq, + dissipate, + VMSSemantic //goes with VMSSemReqst below + }; + +struct _VMSReqst + { + enum VMSReqstType reqType;//used for dissipate and in future for IO requests + void *semReqData; + + VMSReqst *nextReqst; + }; +//VMSReqst + +enum VMSSemReqstType //These are equivalent to semantic requests, but for + { // VMS's services available directly to app, like OS + createProbe = 1, // and probe services -- like a VMS-wide built-in lang + openFile, + otherIO + }; + +typedef struct + { enum VMSSemReqstType reqType; + VirtProcr *requestingPr; + char *nameStr; //for create probe + } + VMSSemReq; + + +//==================== Core data structures =================== + +struct _SchedSlot + { + int workIsDone; + int needsProcrAssigned; + VirtProcr *procrAssignedToSlot; + }; +//SchedSlot + +/*WARNING: re-arranging this data structure could cause VP switching + * assembly code to fail -- hard-codes offsets of fields + */ +struct _VirtProcr + { int procrID; //for debugging -- count up each time create + int coreAnimatedBy; + void *startOfStack; + void *stackPtr; + void *framePtr; + void *nextInstrPt; + + void *coreLoopStartPt; //allows proto-runtime to be linked later + void *coreLoopFramePtr; //restore before jmp back to core loop + void *coreLoopStackPtr; //restore before jmp back to core loop + + void *initialData; + + SchedSlot *schedSlot; + VMSReqst *requests; + + void *semanticData; //this livesUSE_GNU here for the life of VP + void *dataRetFromReq;//values returned from plugin to VP go here + + //=========== MEASUREMENT STUFF ========== + #ifdef MEAS__TIME_STAMP_SUSP + unsigned int preSuspTSCLow; + unsigned int postSuspTSCLow; + #endif + #ifdef MEAS__TIME_MASTER /* in VirtProcr because multiple masterVPs*/ + unsigned int startMasterTSCLow;USE_GNU + unsigned int endMasterTSCLow; + #endif + #ifdef MEAS__PERF_COUNTERS // + CounterRecord** counter_history; + PrivDynArrayInfo* counter_history_array_info; + #endif + //======================================== + + float64 createPtInSecs; //have space but don't use on some configs + }; +//VirtProcr + + +/*WARNING: re-arranging this data structure could cause VP-switching + * assembly code to fail -- hard-codes offsets of fields + * (because -O3 messes with things otherwise) + */ +typedef struct + { + SlaveScheduler slaveScheduler; + RequestHandler requestHandler; + + SchedSlot ***allSchedSlots; + VMSQueueStruc **readyToAnimateQs; + VirtProcr **masterVPs; + + void *semanticEnv; + void *OSEventStruc; //for future, when add I/O to BLIS + MallocProlog *freeListHead; + int32 amtOfOutstandingMem; //total currently allocated + + void *coreLoopReturnPt;//addr to jump to to re-enter coreLoop + + int32 setupComplete; + volatile int32 masterLock; + + int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP + GateStruc *workStealingGates[ NUM_CORES ]; //concurrent work-steal + int32 workStealingLock; + + int32 numProcrsCreated; //gives ordering to processor creation + + //=========== MEASUREMENT STUFF ============= + IntervalProbe **intervalProbes; + PrivDynArrayInfo *dynIntervalProbesInfo; + HashTable *probeNameHashTbl; + int32 masterCreateProbeID; + float64 createPtInSecs; + Histogram **measHists; + PrivDynArrayInfo *measHistsInfo; + #ifdef MEAS__TIME_PLUGIN + Histogram *reqHdlrLowTimeHist; + Histogram *reqHdlrHighTimeHist; + #endif + #ifdef MEAS__TIME_MALLOC + Histogram *mallocTimeHist; + Histogram *freeTimeHist; + #endif + #ifdef MEAS__TIME_MASTER_LOCK + Histogram *masterLockLowTimeHist; + Histogram *masterLockHighTimeHist; + #endif + #ifdef MEAS__PERF_COUNTERS + int cycles_counter_fd[NUM_CORES]; + int instrs_counter_fd[NUM_CORES]; + FILE* counteroutput; + #endif + #ifdef DETECT_DEPENDENCIES + Dependency** dependencies; + PrivDynArrayInfo* dependenciesInfo; + #endif + #ifdef MEAS__PERF_COUNTERS // + CounterRecord** counter_history; + PrivDynArrayInfo* counter_history_array_info; + #endif + } +MasterEnv; + +//========================= Extra Stuff Data Strucs ======================= +typedef struct + { + + } +VMSExcp; + +struct _GateStruc + { + int32 gateClosed; + int32 preGateProgress; + int32 waitProgress; + int32 exitProgress; + }; +//GateStruc + +//======================= OS Thread related =============================== + +void * coreLoop( void *paramsIn ); //standard PThreads fn prototype +void * coreLoop_Seq( void *paramsIn ); //standard PThreads fn prototype +void masterLoop( void *initData, VirtProcr *masterPr ); + + +typedef struct + { + void *endThdPt; + unsigned int coreNum; + } +ThdParams; + +pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state +ThdParams *coreLoopThdParams [ NUM_CORES ]; +pthread_mutex_t suspendLock; +pthread_cond_t suspend_cond; + + + +//===================== Global Vars =================== + +volatile MasterEnv *_VMSMasterEnv; + + + + +//=========================== Function Prototypes ========================= + + +//========== Setup and shutdown ========== +void +VMS__init(); + +void +VMS__init_Seq(); + +void +VMS__start_the_work_then_wait_until_done(); + +void +VMS__start_the_work_then_wait_until_done_Seq(); + +inline VirtProcr * +VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); + +void +VMS__dissipate_procr( VirtProcr *procrToDissipate ); + + //Use this to create processor inside entry point & other places outside + // the VMS system boundary (IE, not run in slave nor Master) +VirtProcr * +VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); + +void +VMS_ext__dissipate_procr( VirtProcr *procrToDissipate ); + +void +VMS__throw_exception( char *msgStr, VirtProcr *reqstPr, VMSExcp *excpData ); + +void +VMS__shutdown(); + +void +VMS__cleanup_at_end_of_shutdown(); + +void * +VMS__give_sem_env_for( VirtProcr *animPr ); + + +//============== Request Related =============== + +void +VMS__suspend_procr( VirtProcr *callingPr ); + +inline void +VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, VirtProcr *callingPr ); + +/*inline*/ __attribute__ ((noinline)) void +VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ); + +void +VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr ); + +void /*inline**/ __attribute__ ((noinline)) +VMS__send_dissipate_req( VirtProcr *prToDissipate ); + +/*inline**/ __attribute__ ((noinline)) void +VMS__send_VMSSem_request( void *semReqData, VirtProcr *callingPr ); + +VMSReqst * +VMS__take_next_request_out_of( VirtProcr *procrWithReq ); + +inline void * +VMS__take_sem_reqst_from( VMSReqst *req ); + +void inline +VMS__handle_VMSSemReq( VMSReqst *req, VirtProcr *requestingPr, void *semEnv, + ResumePrFnPtr resumePrFnPtr ); + +//======================== STATS ====================== + +//===== RDTSC wrapper ===== //Also runs with x86_64 code + +#define saveTimeStampCountInto(low, high) \ + asm volatile("RDTSC; \ + movl %%eax, %0; \ + movl %%edx, %1;" \ + /* outputs */ : "=m" (low), "=m" (high)\ + /* inputs */ : \ + /* clobber */ : "%eax", "%edx" \ + ); + +#define saveLowTimeStampCountInto(low) \ + asm volatile("RDTSC; \ + movl %%eax, %0;" \ + /* outputs */ : "=m" (low) \ + /* inputs */ : \ + /* clobber */ : "%eax", "%edx" \ + ); + +//==================== +#define makeAMeasHist( idx, name, numBins, startVal, binWidth ) \ + makeHighestDynArrayIndexBeAtLeast( _VMSMasterEnv->measHistsInfo, idx ); \ + _VMSMasterEnv->measHists[idx] = \ + makeFixedBinHist( numBins, startVal, binWidth, name ); + +#define saveCyclesAndInstrs(core,cycles,instrs) do{ \ + int cycles_fd = _VMSMasterEnv->cycles_counter_fd[core]; \ + int instrs_fd = _VMSMasterEnv->instrs_counter_fd[core]; \ + int nread; \ + \ + nread = read(cycles_fd,&(cycles),sizeof(cycles)); \ + if(nread<0){ \ + perror("Error reading cycles counter"); \ + cycles = 0; \ + } \ + \ + nread = read(instrs_fd,&(instrs),sizeof(instrs)); \ + if(nread<0){ \ + perror("Error reading cycles counter"); \ + instrs = 0; \ + } \ +} while (0) + +#define getReturnAddressBeforeLibraryCall(vp_ptr, res_ptr) do{ \ +void* frame_ptr0 = vp_ptr->framePtr; \ +void* frame_ptr1 = *((void**)frame_ptr0); \ +void* frame_ptr2 = *((void**)frame_ptr1); \ +void* frame_ptr3 = *((void**)frame_ptr2); \ +void* ret_addr = *((void**)frame_ptr3 + 1); \ +*res_ptr = ret_addr; \ +} while (0) + +#define MEAS__SUB_CREATE /*turn on/off subtraction of create from plugin*/ + +#ifdef VPTHREAD + +//VPThread +#define createHistIdx 0 +#define mutexLockHistIdx 1 +#define mutexUnlockHistIdx 2 +#define condWaitHistIdx 3 +#define condSignalHistIdx 4 + +#define MakeTheMeasHists() \ + _VMSMasterEnv->measHistsInfo = \ + makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \ + makeAMeasHist( createHistIdx, "create", 250, 0, 100 ) \ + makeAMeasHist( mutexLockHistIdx, "mutex_lock", 50, 0, 100 ) \ + makeAMeasHist( mutexUnlockHistIdx, "mutex_unlock", 50, 0, 100 ) \ + makeAMeasHist( condWaitHistIdx, "cond_wait", 50, 0, 100 ) \ + makeAMeasHist( condSignalHistIdx, "cond_signal", 50, 0, 100 ) + +#endif + + +#ifdef VCILK + +//VCilk +#define spawnHistIdx 0 +#define syncHistIdx 1 + +#define MakeTheMeasHists() \ + _VMSMasterEnv->measHistsInfo = \ + makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \ + makeAMeasHist( spawnHistIdx, "Spawn", 50, 0, 200 ) \ + makeAMeasHist( syncHistIdx, "Sync", 50, 0, 200 ) + + +#endif + +#ifdef SSR + +//SSR +#define SendFromToHistIdx 0 +#define SendOfTypeHistIdx 1 +#define ReceiveFromToHistIdx 2 +#define ReceiveOfTypeHistIdx 3 + +#define MakeTheMeasHists() \ + _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 ) + +#endif + +//=========================================================================== +//VPThread + + +#define Meas_startCreate \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); \ + +#define Meas_endCreate \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp, \ + _VMSMasterEnv->measHists[ createHistIdx ] ); + +#define Meas_startMutexLock \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); \ + +#define Meas_endMutexLock \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp, \ + _VMSMasterEnv->measHists[ mutexLockHistIdx ] ); + +#define Meas_startMutexUnlock \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); \ + +#define Meas_endMutexUnlock \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp, \ + _VMSMasterEnv->measHists[ mutexUnlockHistIdx ] ); + +#define Meas_startCondWait \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); \ + +#define Meas_endCondWait \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp, \ + _VMSMasterEnv->measHists[ condWaitHistIdx ] ); + +#define Meas_startCondSignal \ + int32 startStamp, endStamp; \ + saveLowTimeStampCountInto( startStamp ); \ + +#define Meas_endCondSignal \ + saveLowTimeStampCountInto( endStamp ); \ + addIntervalToHist( startStamp, endStamp, \ + _VMSMasterEnv->measHists[ condSignalHistIdx ] ); + +//=========================================================================== +// VCilk +#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 ] ); + +//=========================================================================== +// SSR +#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 ] ); + +//===== + +#include "ProcrContext.h" +#include "probes.h" +#include "vutilities.h" + +#endif /* _VMS_H */ + diff -r 395f58384a5c -r d7c0c0a8187a VMS__DESIGN_NOTES.txt --- a/VMS__DESIGN_NOTES.txt Thu Sep 15 17:31:33 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ - -Implement VMS this way: