seanhalle@208: /* seanhalle@208: * Copyright 2009 OpenSourceStewardshipFoundation.org seanhalle@208: * Licensed under GNU General Public License version 2 seanhalle@208: * seanhalle@208: * Author: seanhalle@yahoo.com seanhalle@208: * seanhalle@208: */ seanhalle@208: seanhalle@208: #ifndef _VMS_H seanhalle@208: #define _VMS_H seanhalle@208: #define _GNU_SOURCE seanhalle@208: seanhalle@208: #include "VMS_primitive_data_types.h" seanhalle@215: #include "DynArray/DynArray.h" seanhalle@215: #include "Hash_impl/PrivateHash.h" seanhalle@215: #include "Histogram/Histogram.h" seanhalle@215: #include "Queue_impl/PrivateQueue.h" seanhalle@208: #include "vmalloc.h" seanhalle@208: seanhalle@208: #include seanhalle@208: #include seanhalle@208: seanhalle@208: //================= Defines: included from separate files ================= seanhalle@208: // seanhalle@208: // Note: ALL defines are in other files, none are in here seanhalle@208: // seanhalle@210: #include "Defines/VMS_defs__main.h" seanhalle@208: seanhalle@208: seanhalle@208: //================================ Typedefs ================================= seanhalle@208: // seanhalle@208: typedef unsigned long long TSCount; seanhalle@208: typedef union seanhalle@208: { uint32 lowHigh[2]; seanhalle@208: uint64 longVal; seanhalle@208: } seanhalle@208: TSCountLowHigh; seanhalle@208: seanhalle@208: typedef struct _SchedSlot SchedSlot; seanhalle@208: typedef struct _VMSReqst VMSReqst; seanhalle@208: typedef struct _SlaveVP SlaveVP; seanhalle@208: typedef struct _MasterVP MasterVP; seanhalle@208: typedef struct _IntervalProbe IntervalProbe; seanhalle@208: typedef struct _GateStruc GateStruc; seanhalle@208: seanhalle@208: seanhalle@209: typedef SlaveVP * (*Sched_Assigner) ( void *, int ); //semEnv, coreIdx seanhalle@209: typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv seanhalle@209: typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv seanhalle@209: typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv seanhalle@209: typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); seanhalle@209: seanhalle@209: //============================ HW Dependent Fns ================================ seanhalle@209: seanhalle@216: #include "Hardware_Dependent/VMS__HW_measurement.h" seanhalle@216: #include "Hardware_Dependent/VMS__primitives.h" seanhalle@208: seanhalle@208: //============================= Statistics ================================== seanhalle@208: seanhalle@208: inline TSCount getTSCount(); seanhalle@208: seanhalle@208: //============= Request Related =========== seanhalle@208: // seanhalle@208: seanhalle@208: enum VMSReqstType //avoid starting enums at 0, for debug reasons seanhalle@208: { seanhalle@208: semantic = 1, seanhalle@208: createReq, seanhalle@208: dissipate, seanhalle@208: VMSSemantic //goes with VMSSemReqst below seanhalle@208: }; seanhalle@208: seanhalle@208: struct _VMSReqst seanhalle@208: { seanhalle@208: enum VMSReqstType reqType;//used for dissipate and in future for IO requests seanhalle@208: void *semReqData; seanhalle@208: seanhalle@208: VMSReqst *nextReqst; seanhalle@208: }; seanhalle@208: //VMSReqst seanhalle@208: seanhalle@208: enum VMSSemReqstType //These are equivalent to semantic requests, but for seanhalle@208: { // VMS's services available directly to app, like OS seanhalle@208: createProbe = 1, // and probe services -- like a VMS-wide built-in lang seanhalle@208: openFile, seanhalle@208: otherIO seanhalle@208: }; seanhalle@208: seanhalle@208: typedef struct seanhalle@208: { enum VMSSemReqstType reqType; seanhalle@209: SlaveVP *requestingSlv; seanhalle@208: char *nameStr; //for create probe seanhalle@208: } seanhalle@208: VMSSemReq; seanhalle@208: seanhalle@208: seanhalle@208: //==================== Core data structures =================== seanhalle@208: seanhalle@208: struct _SchedSlot seanhalle@208: { seanhalle@208: int workIsDone; seanhalle@209: int needsSlaveAssigned; seanhalle@209: SlaveVP *slaveAssignedToSlot; seanhalle@208: }; seanhalle@208: //SchedSlot seanhalle@208: seanhalle@209: /*WARNING: re-arranging this data structure could cause Slv switching seanhalle@208: * assembly code to fail -- hard-codes offsets of fields seanhalle@208: */ seanhalle@208: struct _SlaveVP seanhalle@215: { int slaveID; //each slave given a unique ID seanhalle@208: int coreAnimatedBy; seanhalle@208: void *startOfStack; seanhalle@208: void *stackPtr; seanhalle@208: void *framePtr; seanhalle@208: void *resumeInstrPtr; seanhalle@208: seanhalle@216: void *coreCtlrStartPt; //allows proto-runtime to be linked later seanhalle@216: void *coreCtlrFramePtr; //restore before jmp back to core controller seanhalle@216: void *coreCtlrStackPtr; //restore before jmp back to core controller seanhalle@208: seanhalle@208: SchedSlot *schedSlot; seanhalle@208: VMSReqst *requests; seanhalle@208: seanhalle@210: void *semanticData; //this is live for the life of Slv seanhalle@210: void *dataRetFromReq;//Used to return vals from plugin to Wrapper Lib seanhalle@208: seanhalle@208: //=========== MEASUREMENT STUFF ========== seanhalle@209: MEAS__Insert_Meas_Fields_into_Slave; seanhalle@208: //======================================== seanhalle@208: seanhalle@208: float64 createPtInSecs; //have space but don't use on some configs seanhalle@208: }; seanhalle@208: //SlaveVP seanhalle@208: seanhalle@208: seanhalle@209: /*WARNING: re-arranging this data structure could cause Slv-switching seanhalle@208: * assembly code to fail -- hard-codes offsets of fields seanhalle@208: * (because -O3 messes with things otherwise) seanhalle@208: */ seanhalle@208: typedef struct seanhalle@208: { seanhalle@209: Sched_Assigner slaveAssigner; seanhalle@208: RequestHandler requestHandler; seanhalle@208: seanhalle@208: SchedSlot ***allSchedSlots; seanhalle@210: VMSQueueStruc **readyToAnimateQs; seanhalle@210: SlaveVP **masterVPs; seanhalle@208: seanhalle@208: void *semanticEnv; seanhalle@208: void *OSEventStruc; //for future, when add I/O to BLIS seanhalle@209: MallocArrays *freeLists; seanhalle@208: int32 amtOfOutstandingMem; //total currently allocated seanhalle@208: seanhalle@216: void *coreCtlrReturnPt;//addr to jump to to re-enter coreCtlr seanhalle@208: seanhalle@208: int32 setupComplete; seanhalle@209: int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP seanhalle@209: int32 masterLock __align_to_cacheline__; seanhalle@208: GateStruc *workStealingGates[ NUM_CORES ]; //concurrent work-steal seanhalle@208: int32 workStealingLock; seanhalle@208: seanhalle@209: int32 numSlavesCreated; //gives ordering to processor creation seanhalle@209: int32 numSlavesAlive; //used to detect when to shutdown seanhalle@208: seanhalle@208: //=========== MEASUREMENT STUFF ============= seanhalle@208: IntervalProbe **intervalProbes; seanhalle@208: PrivDynArrayInfo *dynIntervalProbesInfo; seanhalle@208: HashTable *probeNameHashTbl; seanhalle@208: int32 masterCreateProbeID; seanhalle@208: float64 createPtInSecs; seanhalle@208: Histogram **measHists; seanhalle@208: PrivDynArrayInfo *measHistsInfo; seanhalle@209: MEAS__Insert_Susp_Meas_Fields_into_MasterEnv; seanhalle@209: MEAS__Insert_Master_Meas_Fields_into_MasterEnv; seanhalle@209: MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv; seanhalle@209: MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv; seanhalle@209: MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv; seanhalle@209: MEAS__Insert_System_Meas_Fields_into_MasterEnv; seanhalle@208: //========================================== seanhalle@208: } seanhalle@208: MasterEnv; seanhalle@208: seanhalle@208: //========================= Extra Stuff Data Strucs ======================= seanhalle@208: typedef struct seanhalle@208: { seanhalle@208: seanhalle@208: } seanhalle@208: VMSExcp; seanhalle@208: seanhalle@208: struct _GateStruc seanhalle@208: { seanhalle@208: int32 gateClosed; seanhalle@208: int32 preGateProgress; seanhalle@208: int32 waitProgress; seanhalle@208: int32 exitProgress; seanhalle@208: }; seanhalle@208: //GateStruc seanhalle@208: seanhalle@208: //======================= OS Thread related =============================== seanhalle@208: seanhalle@216: void * coreController( void *paramsIn ); //standard PThreads fn prototype seanhalle@216: void * coreCtlr_Seq( void *paramsIn ); //standard PThreads fn prototype seanhalle@208: void masterLoop( void *initData, SlaveVP *masterVP ); seanhalle@208: seanhalle@208: seanhalle@208: typedef struct seanhalle@208: { seanhalle@208: void *endThdPt; seanhalle@208: unsigned int coreNum; seanhalle@208: } seanhalle@208: ThdParams; seanhalle@208: seanhalle@209: //============================= Global Vars ================================ seanhalle@209: seanhalle@215: volatile MasterEnv *_VMSMasterEnv __align_to_cacheline__; seanhalle@215: seanhalle@216: pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state seanhalle@216: ThdParams *coreCtlrThdParams [ NUM_CORES ]; seanhalle@215: pthread_mutex_t suspendLock = PTHREAD_MUTEX_INITIALIZER; seanhalle@215: pthread_cond_t suspendCond = PTHREAD_COND_INITIALIZER; seanhalle@208: seanhalle@208: //========================= Function Prototypes =========================== seanhalle@208: seanhalle@209: /* MEANING OF WL PI SS int seanhalle@209: * These indicate which places the function is safe to use. They stand for: seanhalle@209: * WL: Wrapper Library seanhalle@209: * PI: Plugin seanhalle@209: * SS: Startup and Shutdown seanhalle@209: * int: internal to the VMS implementation seanhalle@209: */ seanhalle@208: seanhalle@208: //========== Setup and shutdown ========== seanhalle@208: void seanhalle@209: VMS_SS__init(); seanhalle@208: seanhalle@209: //Fix; seanhalle@215: /*seed-slaveVP creation -- put box around language, have lang register stuff seanhalle@208: with VMS. seanhalle@208: have main program explicitly INIT Lang! -- makes more sense to seanhalle@208: C programmers -- makes it clear that there's a transition. seanhalle@208: (might need to have the pthreads remain waiting for seanhalle@208: cond until work is scheduled) seanhalle@208: Have main do call to tell language to perform work -- like did with DKU seanhalle@208: seanhalle@208: Ex: "HWSim__run_a_simulation(netlist, paramBag);" seanhalle@208: "processID = SSR__run_program(seed_fn, seedData); " seanhalle@208: "SSR__Wait_for_program_to_end(processID);" seanhalle@208: "SSR__run_program_and_wait_till_it_ends(seed_fn, seedData);" seanhalle@208: seanhalle@208: allows multiple languages to be started, and programs run in several, seanhalle@208: overlapped, or one program to be run that uses multiple langs..? seanhalle@208: So, each program is in separate directory: seanhalle@208: "HWSim_ArchDef__PingPong" "SSR_Program__Blocked_Matrix_Mult" seanhalle@208: seanhalle@208: Those programs can talk to each other, via VMS, by handles they each seanhalle@208: return seanhalle@208: "processIDs[0] = SSR__run_program(seed_fn1, seedData1);" seanhalle@208: "processIDs[1] = SSR__run_program(seed_fn2, seedData2);" seanhalle@208: "SSR__link_programs(processIDs, 2);" seanhalle@208: or even seanhalle@208: "processIDs[0] = Vthread__run_program(seed_fn1, seedData1);" seanhalle@208: "processIDs[1] = SSR__run_program(seed_fn2, seedData2);" seanhalle@208: "VMS__link_programs(processIDs, 2);" seanhalle@208: Then, the programs just know they sync with other prog, but use own seanhalle@208: lang's sync constructs -- VMS uses message system to establish tie-pt, seanhalle@208: each lang defines what a tie-point means to it.. (work with the seanhalle@208: diff semantics?) seanhalle@209: */ seanhalle@208: void seanhalle@209: VMS_SS__start_the_work_then_wait_until_done(); seanhalle@208: seanhalle@208: void seanhalle@209: VMS_SS__shutdown(); seanhalle@208: seanhalle@208: void seanhalle@209: VMS_SS__cleanup_at_end_of_shutdown(); seanhalle@208: seanhalle@208: seanhalle@208: //============== =============== seanhalle@208: seanhalle@208: inline SlaveVP * seanhalle@209: VMS_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam ); seanhalle@209: #define VMS_PI__create_slaveVP VMS_int__create_slaveVP seanhalle@209: #define VMS_WL__create_slaveVP VMS_int__create_slaveVP seanhalle@208: seanhalle@210: //Use this to create processor inside entry point & other places outside seanhalle@210: // the VMS system boundary (IE, don't animate with a SlaveVP or MasterVP) seanhalle@210: SlaveVP * seanhalle@210: VMS_ext__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam ); seanhalle@210: seanhalle@210: inline SlaveVP * seanhalle@210: VMS_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr, seanhalle@210: void *dataParam, void *stackLocs ); seanhalle@210: seanhalle@208: inline void seanhalle@209: VMS_int__point_slaveVP_to_Fn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr, seanhalle@208: void *dataParam); seanhalle@208: seanhalle@208: void seanhalle@210: VMS_int__dissipate_slaveVP( SlaveVP *slaveToDissipate ); seanhalle@210: #define VMS_PI__dissipate_slaveVP VMS_int__dissipate_slaveVP seanhalle@210: //WL: dissipate a SlaveVP by sending a request seanhalle@208: seanhalle@208: void seanhalle@209: VMS_ext__dissipate_slaveVP( SlaveVP *slaveToDissipate ); seanhalle@208: seanhalle@208: void seanhalle@209: VMS_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, VMSExcp *excpData ); seanhalle@209: #define VMS_PI__throw_exception VMS_int__throw_exception seanhalle@209: #define VMS_WL__throw_exception VMS_int__throw_exception seanhalle@208: seanhalle@208: void * seanhalle@209: VMS_int__give_sem_env_for( SlaveVP *animSlv ); seanhalle@209: #define VMS_PI__give_sem_env_for VMS_int__give_sem_env_for seanhalle@209: #define VMS_SS__give_sem_env_for VMS_int__give_sem_env_for seanhalle@209: //No WL version -- not safe! if use in WL, be sure data rd & wr is stable seanhalle@208: seanhalle@208: //============== Request Related =============== seanhalle@208: seanhalle@208: void seanhalle@209: VMS_int__suspend_slaveVP_and_send_req( SlaveVP *callingSlv ); seanhalle@208: seanhalle@208: inline void seanhalle@209: VMS_WL__add_sem_request_in_mallocd_VMSReqst( void *semReqData, SlaveVP *callingSlv ); seanhalle@208: seanhalle@208: inline void seanhalle@209: VMS_WL__send_sem_request( void *semReqData, SlaveVP *callingSlv ); seanhalle@208: seanhalle@208: void seanhalle@209: VMS_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv ); seanhalle@208: seanhalle@208: void inline seanhalle@208: VMS_WL__send_dissipate_req( SlaveVP *prToDissipate ); seanhalle@208: seanhalle@208: inline void seanhalle@209: VMS_WL__send_VMSSem_request( void *semReqData, SlaveVP *callingSlv ); seanhalle@208: seanhalle@208: VMSReqst * seanhalle@209: VMS_PI__take_next_request_out_of( SlaveVP *slaveWithReq ); seanhalle@208: seanhalle@208: inline void * seanhalle@208: VMS_PI__take_sem_reqst_from( VMSReqst *req ); seanhalle@208: seanhalle@208: void inline seanhalle@209: VMS_PI__handle_VMSSemReq( VMSReqst *req, SlaveVP *requestingSlv, void *semEnv, seanhalle@209: ResumeSlvFnPtr resumeSlvFnPtr ); seanhalle@208: seanhalle@208: //======================== MEASUREMENT ====================== seanhalle@208: uint64 seanhalle@208: VMS_WL__give_num_plugin_cycles(); seanhalle@208: uint32 seanhalle@208: VMS_WL__give_num_plugin_animations(); seanhalle@208: seanhalle@208: seanhalle@210: //========================= Utilities ======================= seanhalle@210: inline char * seanhalle@210: VMS_int__strDup( char *str ); seanhalle@208: seanhalle@210: seanhalle@210: //========================= Probes ======================= seanhalle@210: #include "Probes/probes.h" seanhalle@210: seanhalle@210: //================================================ seanhalle@208: #endif /* _VMS_H */ seanhalle@208: