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