Me@178: /* Me@178: * Copyright 2009 OpenSourceStewardshipFoundation.org Me@178: * Licensed under GNU General Public License version 2 Me@178: * Me@178: * Author: seanhalle@yahoo.com Me@178: * Me@178: */ Me@178: Me@178: #ifndef _VMS_H Me@178: #define _VMS_H Me@178: #define _GNU_SOURCE Me@178: Me@178: #include "VMS_primitive_data_types.h" msach@205: #include "C_Libraries/DynArray/DynArray.h" msach@205: #include "C_Libraries/Hash_impl/PrivateHash.h" msach@205: #include "C_Libraries/Histogram/Histogram.h" msach@205: #include "C_Libraries/Queue_impl/PrivateQueue.h" Me@178: #include "vmalloc.h" Me@178: Me@178: #include Me@178: #include Me@178: Me@200: //================= Defines: included from separate files ================= Me@200: // Me@200: // Note: ALL defines are in other files, none are in here Me@200: // Me@200: #include "VMS_defs.h" Me@178: Me@200: Me@200: //================================ Typedefs ================================= Me@178: // Me@178: typedef unsigned long long TSCount; Me@200: typedef union Me@200: { uint32 lowHigh[2]; Me@200: uint64 longVal; Me@200: } Me@200: TSCountLowHigh; Me@178: Me@178: typedef struct _SchedSlot SchedSlot; Me@178: typedef struct _VMSReqst VMSReqst; Me@200: typedef struct _SlaveVP SlaveVP; Me@178: typedef struct _IntervalProbe IntervalProbe; Me@178: typedef struct _GateStruc GateStruc; Me@178: Me@178: Me@200: typedef SlaveVP * (*SlaveScheduler) ( void *, int ); //semEnv, coreIdx Me@200: typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv Me@200: typedef void (*VirtProcrFnPtr) ( void *, SlaveVP * ); //initData, animPr Me@200: typedef void VirtProcrFn ( void *, SlaveVP * ); //initData, animPr Me@200: typedef void (*ResumeVPFnPtr) ( SlaveVP *, void * ); Me@178: msach@205: //============================= Statistics ================================== msach@205: msach@205: inline TSCount getTSCount(); Me@178: Me@200: //============= Request Related =========== Me@178: // Me@178: Me@178: enum VMSReqstType //avoid starting enums at 0, for debug reasons Me@178: { Me@178: semantic = 1, Me@178: createReq, Me@178: dissipate, Me@178: VMSSemantic //goes with VMSSemReqst below Me@178: }; Me@178: Me@178: struct _VMSReqst Me@178: { Me@178: enum VMSReqstType reqType;//used for dissipate and in future for IO requests Me@178: void *semReqData; Me@178: Me@178: VMSReqst *nextReqst; Me@178: }; Me@178: //VMSReqst Me@178: Me@178: enum VMSSemReqstType //These are equivalent to semantic requests, but for Me@178: { // VMS's services available directly to app, like OS Me@178: createProbe = 1, // and probe services -- like a VMS-wide built-in lang Me@178: openFile, Me@178: otherIO Me@178: }; Me@178: Me@178: typedef struct Me@178: { enum VMSSemReqstType reqType; Me@200: SlaveVP *requestingPr; Me@178: char *nameStr; //for create probe Me@178: } Me@178: VMSSemReq; Me@178: Me@178: Me@178: //==================== Core data structures =================== Me@178: Me@178: struct _SchedSlot Me@178: { Me@178: int workIsDone; Me@178: int needsProcrAssigned; Me@200: SlaveVP *procrAssignedToSlot; Me@178: }; Me@178: //SchedSlot Me@178: Me@178: /*WARNING: re-arranging this data structure could cause VP switching Me@178: * assembly code to fail -- hard-codes offsets of fields Me@178: */ Me@200: struct _SlaveVP Me@178: { int procrID; //for debugging -- count up each time create Me@178: int coreAnimatedBy; Me@178: void *startOfStack; Me@178: void *stackPtr; Me@178: void *framePtr; Me@178: void *nextInstrPt; Me@178: Me@178: void *coreLoopStartPt; //allows proto-runtime to be linked later Me@178: void *coreLoopFramePtr; //restore before jmp back to core loop Me@178: void *coreLoopStackPtr; //restore before jmp back to core loop Me@178: Me@178: void *initialData; Me@178: Me@178: SchedSlot *schedSlot; Me@178: VMSReqst *requests; Me@178: Me@178: void *semanticData; //this livesUSE_GNU here for the life of VP Me@178: void *dataRetFromReq;//values returned from plugin to VP go here Me@178: Me@178: //=========== MEASUREMENT STUFF ========== Me@200: #ifdef MEAS__TIME_STAMP_SUSP Me@200: uint32 preSuspTSCLow; Me@200: uint32 postSuspTSCLow; Me@200: #endif Me@200: #ifdef MEAS__TIME_MASTER /* in VirtProcr because multiple masterVPs*/ Me@200: uint32 startMasterTSCLow;USE_GNU Me@200: uint32 endMasterTSCLow; Me@200: #endif Me@200: #ifdef MEAS__TIME_2011_SYS Me@200: TSCountLowHigh startSusp; Me@200: uint64 totalSuspCycles; Me@200: uint32 numGoodSusp; Me@200: #endif Me@178: //======================================== Me@178: Me@178: float64 createPtInSecs; //have space but don't use on some configs Me@178: }; Me@178: //VirtProcr Me@178: Me@178: Me@178: /*WARNING: re-arranging this data structure could cause VP-switching Me@178: * assembly code to fail -- hard-codes offsets of fields Me@178: * (because -O3 messes with things otherwise) Me@178: */ Me@178: typedef struct Me@178: { Me@200: union{ //adds padding to put masterLock on its own cache-line to elim Me@200: // false sharing (masterLock is most-accessed var in VMS) Me@200: volatile int32 masterLock; Me@200: char padding[CACHELINE_SIZE]; Me@200: } masterLockUnion; Me@178: SlaveScheduler slaveScheduler; Me@178: RequestHandler requestHandler; Me@178: Me@178: SchedSlot ***allSchedSlots; Me@178: VMSQueueStruc **readyToAnimateQs; Me@200: SlaveVP **masterVPs; Me@178: Me@178: void *semanticEnv; Me@178: void *OSEventStruc; //for future, when add I/O to BLIS Me@200: MallocArrays *freeLists; Me@178: int32 amtOfOutstandingMem; //total currently allocated Me@178: Me@178: void *coreLoopReturnPt;//addr to jump to to re-enter coreLoop Me@178: Me@178: int32 setupComplete; Me@200: //int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP Me@178: GateStruc *workStealingGates[ NUM_CORES ]; //concurrent work-steal Me@178: int32 workStealingLock; Me@178: Me@200: int32 numVPsCreated; //gives ordering to processor creation Me@178: Me@178: //=========== MEASUREMENT STUFF ============= Me@200: IntervalProbe **intervalProbes; Me@200: PrivDynArrayInfo *dynIntervalProbesInfo; Me@200: HashTable *probeNameHashTbl; Me@200: int32 masterCreateProbeID; Me@200: float64 createPtInSecs; Me@200: Histogram **measHists; Me@200: PrivDynArrayInfo *measHistsInfo; Me@200: #ifdef MEAS__TIME_PLUGIN Me@200: Histogram *reqHdlrLowTimeHist; Me@200: Histogram *reqHdlrHighTimeHist; Me@200: #endif Me@200: #ifdef MEAS__TIME_MALLOC Me@200: Histogram *mallocTimeHist; Me@200: Histogram *freeTimeHist; Me@200: #endif Me@200: #ifdef MEAS__TIME_MASTER_LOCK Me@200: Histogram *masterLockLowTimeHist; Me@200: Histogram *masterLockHighTimeHist; Me@200: #endif Me@200: #ifdef MEAS__TIME_2011_SYS Me@200: TSCountLowHigh startMaster; Me@200: uint64 totalMasterCycles; Me@200: uint32 numMasterAnimations; Me@200: TSCountLowHigh startReqHdlr; Me@200: uint64 totalPluginCycles; Me@200: uint32 numPluginAnimations; Me@200: uint64 cyclesTillStartMasterLoop; Me@200: TSCountLowHigh endMasterLoop; Me@200: #endif Me@200: //========================================== Me@178: } Me@178: MasterEnv; Me@178: Me@178: //========================= Extra Stuff Data Strucs ======================= Me@178: typedef struct Me@178: { Me@178: Me@178: } Me@178: VMSExcp; Me@178: Me@178: struct _GateStruc Me@178: { Me@178: int32 gateClosed; Me@178: int32 preGateProgress; Me@178: int32 waitProgress; Me@178: int32 exitProgress; Me@178: }; Me@178: //GateStruc Me@178: Me@178: //======================= OS Thread related =============================== Me@178: Me@178: void * coreLoop( void *paramsIn ); //standard PThreads fn prototype Me@178: void * coreLoop_Seq( void *paramsIn ); //standard PThreads fn prototype Me@200: void masterLoop( void *initData, SlaveVP *masterVP ); Me@178: Me@178: Me@178: typedef struct Me@178: { Me@178: void *endThdPt; Me@178: unsigned int coreNum; Me@178: } Me@178: ThdParams; Me@178: Me@178: pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state Me@178: ThdParams *coreLoopThdParams [ NUM_CORES ]; Me@178: pthread_mutex_t suspendLock; Me@178: pthread_cond_t suspend_cond; Me@178: Me@178: Me@178: Me@200: //============================= Global Vars ================================ Me@178: Me@200: volatile MasterEnv *_VMSMasterEnv __align_to_cacheline__; Me@178: Me@178: Me@178: Me@178: Me@200: //========================= Function Prototypes =========================== Me@178: Me@178: Me@178: //========== Setup and shutdown ========== Me@178: void Me@200: VMS_int__init(); Me@178: Me@178: void Me@200: VMS_int__init_Seq(); Me@178: Me@178: void Me@200: VMS_WL__start_the_work_then_wait_until_done(); Me@178: Me@178: void Me@200: VMS_WL__start_the_work_then_wait_until_done_Seq(); Me@178: Me@200: inline SlaveVP * Me@200: VMS_int__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); Me@178: Me@178: void Me@200: VMS_int__dissipate_procr( SlaveVP *procrToDissipate ); Me@178: Me@178: //Use this to create processor inside entry point & other places outside Me@178: // the VMS system boundary (IE, not run in slave nor Master) Me@200: SlaveVP * Me@178: VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); Me@178: Me@178: void Me@200: VMS_ext__dissipate_procr( SlaveVP *procrToDissipate ); Me@178: Me@178: void Me@200: VMS_PI__throw_exception( char *msgStr, SlaveVP *reqstPr, VMSExcp *excpData ); Me@178: Me@178: void Me@200: VMS_int__shutdown(); Me@178: Me@178: void Me@200: VMS_int__cleanup_at_end_of_shutdown(); Me@178: Me@178: void * Me@200: VMS_WL__give_sem_env_for( SlaveVP *animPr ); Me@178: Me@178: Me@178: //============== Request Related =============== Me@178: Me@178: void Me@200: VMS_int__suspend_procr( SlaveVP *callingPr ); Me@178: Me@178: inline void Me@200: VMS_WL__add_sem_request_in_mallocd_VMSReqst( void *semReqData, SlaveVP *callingPr ); Me@178: Me@178: inline void Me@200: VMS_WL__send_sem_request( void *semReqData, SlaveVP *callingPr ); Me@178: Me@178: void Me@200: VMS_WL__send_create_procr_req( void *semReqData, SlaveVP *reqstingPr ); Me@178: Me@178: void inline Me@200: VMS_WL__send_dissipate_req( SlaveVP *prToDissipate ); Me@178: Me@178: inline void Me@200: VMS_WL__send_VMSSem_request( void *semReqData, SlaveVP *callingPr ); Me@178: Me@178: VMSReqst * Me@200: VMS_PI__take_next_request_out_of( SlaveVP *procrWithReq ); Me@178: Me@178: inline void * Me@200: VMS_PI__take_sem_reqst_from( VMSReqst *req ); Me@178: Me@178: void inline Me@200: VMS_PI__handle_VMSSemReq( VMSReqst *req, SlaveVP *requestingPr, void *semEnv, Me@200: ResumeVPFnPtr resumePrFnPtr ); Me@178: Me@200: //======================== MEASUREMENT ====================== Me@200: uint64 Me@200: VMS_WL__give_num_plugin_cycles(); Me@200: uint32 Me@200: VMS_WL__give_num_plugin_animations(); Me@178: Me@178: Me@178: Me@178: #include "ProcrContext.h" Me@178: #include "probes.h" Me@178: #include "vutilities.h" Me@178: Me@178: #endif /* _VMS_H */ Me@178: