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@223: #include "Services_Offered_by_VMS/Memory_Handling/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@223: #include "Defines/VMS_defs.h" seanhalle@208: seanhalle@208: seanhalle@208: //================================ Typedefs ================================= seanhalle@208: // seanhalle@233: typedef unsigned long long TSCount; seanhalle@208: seanhalle@235: typedef struct _AnimSlot AnimSlot; 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: seanhalle@208: seanhalle@235: typedef SlaveVP *(*SlaveAssigner) ( void *, AnimSlot*); //semEnv, slot for HW info seanhalle@223: typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv seanhalle@223: typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv seanhalle@223: typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv seanhalle@223: typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); nengel@228: //=========== MEASUREMENT STUFF ========== nengel@228: MEAS__Insert_Counter_Handler nengel@228: //======================================== 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: 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@231: typedef struct seanhalle@231: { seanhalle@231: //for future expansion seanhalle@231: } seanhalle@231: SlotPerfInfo; seanhalle@231: seanhalle@235: struct _AnimSlot seanhalle@208: { seanhalle@230: int workIsDone; seanhalle@230: int needsSlaveAssigned; seanhalle@230: SlaveVP *slaveAssignedToSlot; seanhalle@230: seanhalle@230: int slotIdx; //needed by Holistic Model's data gathering seanhalle@230: int coreOfSlot; seanhalle@230: SlotPerfInfo *perfInfo; //used by assigner to pick best slave for core seanhalle@208: }; seanhalle@235: //AnimSlot seanhalle@208: nengel@228: enum VPtype { nengel@228: Slave = 1, //default nengel@228: Master, nengel@228: Shutdown nengel@228: }; nengel@228: seanhalle@233: /*This structure embodies the state of a slaveVP. It is reused for masterVP seanhalle@233: * and shutdownVPs. seanhalle@208: */ seanhalle@208: struct _SlaveVP seanhalle@233: { //The offsets of these fields are hard-coded into assembly seanhalle@233: void *stackPtr; //save the core's stack ptr when suspend seanhalle@233: void *framePtr; //save core's frame ptr when suspend seanhalle@233: void *resumeInstrPtr; //save core's program-counter when suspend seanhalle@216: void *coreCtlrFramePtr; //restore before jmp back to core controller seanhalle@216: void *coreCtlrStackPtr; //restore before jmp back to core controller seanhalle@233: seanhalle@233: //============ below this, no fields are used in asm ============= seanhalle@235: seanhalle@235: int slaveID; //each slave given a globally unique ID seanhalle@235: int coreAnimatedBy; seanhalle@233: void *startOfStack; //used to free, and to point slave to Fn seanhalle@235: enum VPtype typeOfVP; //Slave vs Master vs Shutdown.. seanhalle@235: int assignCount; //Each assign is for one work-unit, so IDs it seanhalle@235: //note, a scheduling decision is uniquely identified by the triple: seanhalle@235: // -- used in record & replay seanhalle@233: seanhalle@233: //for comm -- between master and coreCtlr & btwn wrapper lib and plugin seanhalle@235: AnimSlot *animSlotAssignedTo; seanhalle@233: VMSReqst *requests; //wrapper lib puts in requests, plugin takes out seanhalle@233: void *dataRetFromReq;//Return vals from plugin to Wrapper Lib seanhalle@208: seanhalle@235: //For using Slave as carrier for data seanhalle@233: void *semanticData; //Lang saves lang-specific things in slave here seanhalle@208: seanhalle@235: //=========== MEASUREMENT STUFF ========== seanhalle@235: MEAS__Insert_Meas_Fields_into_Slave; seanhalle@235: float64 createPtInSecs; //time VP created, in seconds seanhalle@235: //======================================== seanhalle@208: }; seanhalle@208: //SlaveVP seanhalle@208: seanhalle@233: seanhalle@233: /* The one and only global variable, holds many odds and ends seanhalle@208: */ seanhalle@208: typedef struct seanhalle@230: { //The offsets of these fields are hard-coded into assembly seanhalle@226: void *coreCtlrReturnPt; //offset of field used in asm seanhalle@235: int8 falseSharePad1[256 - sizeof(void*)]; seanhalle@235: int32 masterLock; //offset of field used in asm seanhalle@235: int8 falseSharePad2[256 - sizeof(int32)]; seanhalle@233: //============ below this, no fields are used in asm ============= seanhalle@230: seanhalle@230: //Basic VMS infrastructure seanhalle@230: SlaveVP **masterVPs; seanhalle@235: AnimSlot ***allAnimSlots; seanhalle@230: seanhalle@230: //plugin related seanhalle@225: SlaveAssigner slaveAssigner; seanhalle@208: RequestHandler requestHandler; seanhalle@230: void *semanticEnv; seanhalle@208: seanhalle@230: //Slave creation seanhalle@230: int32 numSlavesCreated; //gives ordering to processor creation seanhalle@230: int32 numSlavesAlive; //used to detect fail-safe shutdown seanhalle@208: seanhalle@230: //Initialization related seanhalle@230: int32 setupComplete; //use while starting up coreCtlr seanhalle@230: seanhalle@230: //Memory management related seanhalle@223: MallocArrays *freeLists; seanhalle@230: int32 amtOfOutstandingMem;//total currently allocated seanhalle@232: seanhalle@208: //=========== MEASUREMENT STUFF ============= seanhalle@208: IntervalProbe **intervalProbes; seanhalle@208: PrivDynArrayInfo *dynIntervalProbesInfo; seanhalle@208: HashTable *probeNameHashTbl; seanhalle@208: int32 masterCreateProbeID; seanhalle@230: float64 createPtInSecs; //real-clock time VMS initialized 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; nengel@228: MEAS__Insert_Counter_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: //======================= 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@230: void animationMaster( 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@233: //these are global, but only used for startup and shutdown seanhalle@222: pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state seanhalle@216: ThdParams *coreCtlrThdParams [ NUM_CORES ]; seanhalle@222: seanhalle@222: pthread_mutex_t suspendLock; seanhalle@222: pthread_cond_t suspendCond; seanhalle@208: seanhalle@208: //========================= Function Prototypes =========================== seanhalle@233: /* MEANING OF WL PI SS int VMSOS seanhalle@209: * These indicate which places the function is safe to use. They stand for: seanhalle@233: * seanhalle@233: * WL Wrapper Library -- wrapper lib code should only use these seanhalle@233: * PI Plugin -- plugin code should only use these seanhalle@233: * SS Startup and Shutdown -- designates these relate to startup & shutdown seanhalle@233: * int internal to VMS -- should not be used in wrapper lib or plugin seanhalle@233: * VMSOS means "OS functions for applications to use" seanhalle@233: * seanhalle@233: * VMS_int__ functions touch internal VMS data structs and are only safe seanhalle@233: * to be used inside the master lock. However, occasionally, they appear seanhalle@233: * in wrapper-lib or plugin code. In those cases, very careful analysis seanhalle@233: * has been done to be sure no concurrency issues could arise. seanhalle@233: * seanhalle@233: * VMS_WL__ functions are all safe for use outside the master lock. seanhalle@233: * seanhalle@233: * VMSOS are only safe for applications to use -- they're like a second seanhalle@233: * language mixed in -- but they can't be used inside plugin code, and seanhalle@233: * aren't meant for use in wrapper libraries, because they are themselves seanhalle@233: * wrapper-library calls! seanhalle@209: */ seanhalle@233: //========== Startup and shutdown ========== seanhalle@208: void seanhalle@209: VMS_SS__init(); seanhalle@208: seanhalle@208: void seanhalle@209: VMS_SS__start_the_work_then_wait_until_done(); seanhalle@208: nengel@228: SlaveVP* nengel@228: VMS_SS__create_shutdown_slave(); nengel@228: 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@219: 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@223: #include "Services_Offered_by_VMS/Measurement_and_Stats/probes.h" seanhalle@210: seanhalle@210: //================================================ seanhalle@208: #endif /* _VMS_H */ seanhalle@208: