Me@42: /* Me@42: * Copyright 2009 OpenSourceStewardshipFoundation.org Me@42: * Licensed under GNU General Public License version 2 Me@42: * Me@42: * Author: seanhalle@yahoo.com Me@42: * Me@42: */ Me@42: Me@42: #ifndef _VMS_H Me@42: #define _VMS_H Me@42: #define __USE_GNU Me@42: Me@42: #include "VMS_primitive_data_types.h" Me@42: #include "Queue_impl/BlockingQueue.h" Me@42: #include "Histogram/Histogram.h" Me@50: #include "DynArray/DynArray.h" Me@50: #include "Hash_impl/PrivateHash.h" Me@50: #include "vmalloc.h" Me@50: Me@42: #include Me@50: #include Me@42: Me@50: Me@50: //=============================== Debug =================================== Me@45: //When SEQUENTIAL is defined, VMS does sequential exe in the main thread Me@42: // It still does co-routines and all the mechanisms are the same, it just Me@42: // has only a single thread and animates VPs one at a time Me@45: //#define SEQUENTIAL Me@42: Me@50: #define PRINT_DEBUG(msg)// printf(msg); fflush(stdin); Me@45: #define PRINT1_DEBUG(msg, param) //printf(msg, param); fflush(stdin); Me@45: #define PRINT2_DEBUG(msg, p1, p2) //printf(msg, p1, p2); fflush(stdin); Me@45: Me@50: #define PRINT_ERROR(msg) printf(msg); fflush(stdin); Me@50: #define PRINT1_ERROR(msg, param) printf(msg, param); fflush(stdin); Me@50: #define PRINT2_ERROR(msg, p1, p2) printf(msg, p1, p2); fflush(stdin); Me@50: Me@50: Me@50: //=========================== STATS ======================= Me@50: Me@45: //when MEAS__TIME_STAMP_SUSP is defined, causes code to be inserted and Me@42: // compiled-in that saves the low part of the time stamp count just before Me@42: // suspending a processor and just after resuming that processor. It is Me@42: // saved into a field added to VirtProcr. Have to sanity-check for Me@42: // rollover of low portion into high portion. Me@42: #define MEAS__TIME_STAMP_SUSP Me@42: #define MEAS__TIME_MASTER Me@42: #define MEAS__NUM_TIMES_TO_RUN 100000 Me@42: Me@45: #define NUM_TSC_ROUND_TRIPS 10 Me@45: Me@50: Me@50: //========================= Hardware related Constants ===================== Me@42: //This value is the number of hardware threads in the shared memory Me@42: // machine Me@42: #define NUM_CORES 4 Me@42: Me@45: // balance amortizing master fixed overhead vs imbalance potential Me@42: #define NUM_SCHED_SLOTS 3 Me@42: Me@45: #define MIN_WORK_UNIT_CYCLES 20000 Me@45: Me@42: #define READYTOANIMATE_RETRIES 10000 Me@42: Me@42: // stack Me@50: #define VIRT_PROCR_STACK_SIZE 0x4000 Me@42: Me@50: // memory for VMS__malloc -- 256M Me@50: #define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x10000000 Me@42: Me@50: Me@50: //============================== Me@42: Me@42: #define SUCCESS 0 Me@42: Me@50: #define writeVMSQ writeSRSWQ Me@50: #define readVMSQ readSRSWQ Me@50: #define makeVMSQ makeSRSWQ Me@50: #define VMSQueueStruc SRSWQueueStruc Me@42: Me@42: Me@50: Me@50: //=========================================================================== Me@50: typedef unsigned long long TSCount; Me@50: Me@50: typedef struct _SchedSlot SchedSlot; Me@50: typedef struct _VMSReqst VMSReqst; Me@50: typedef struct _VirtProcr VirtProcr; Me@50: typedef struct _IntervalProbe IntervalProbe; Me@42: Me@42: typedef VirtProcr * (*SlaveScheduler) ( void *, int ); //semEnv, coreIdx Me@42: typedef void (*RequestHandler) ( VirtProcr *, void * ); //prWReqst, semEnv Me@42: typedef void (*VirtProcrFnPtr) ( void *, VirtProcr * ); //initData, animPr Me@42: typedef void VirtProcrFn ( void *, VirtProcr * ); //initData, animPr Me@50: typedef void (*ResumePrFnPtr) ( VirtProcr *, void * ); Me@50: Me@50: Me@50: //============= Requests =========== Me@50: // Me@50: Me@50: enum VMSReqstType //avoid starting enums at 0, for debug reasons Me@50: { Me@50: semantic = 1, Me@50: createReq, Me@50: dissipate, Me@50: VMSSemantic //goes with VMSSemReqst below Me@50: }; Me@50: Me@50: struct _VMSReqst Me@50: { Me@50: enum VMSReqstType reqType;//used for dissipate and in future for IO requests Me@50: void *semReqData; Me@50: Me@50: VMSReqst *nextReqst; Me@50: }; Me@50: //VMSReqst Me@50: Me@50: enum VMSSemReqstType //These are equivalent to semantic requests, but for Me@50: { // VMS's services available directly to app, like OS Me@50: createProbe = 1, // and probe services -- like a VMS-wide built-in lang Me@50: openFile, Me@50: otherIO Me@50: }; Me@42: Me@42: typedef struct Me@50: { enum VMSSemReqstType reqType; Me@50: VirtProcr *requestingPr; Me@50: char *nameStr; //for create probe Me@42: } Me@50: VMSSemReq; Me@42: Me@42: Me@50: //==================== Core data structures =================== Me@50: Me@42: struct _SchedSlot Me@42: { Me@42: int workIsDone; Me@42: int needsProcrAssigned; Me@42: VirtProcr *procrAssignedToSlot; Me@42: }; Me@42: //SchedSlot Me@42: Me@42: struct _VirtProcr Me@42: { int procrID; //for debugging -- count up each time create Me@42: int coreAnimatedBy; Me@42: void *startOfStack; Me@42: void *stackPtr; Me@42: void *framePtr; Me@42: void *nextInstrPt; Me@42: Me@42: void *coreLoopStartPt; //allows proto-runtime to be linked later Me@42: void *coreLoopFramePtr; //restore before jmp back to core loop Me@42: void *coreLoopStackPtr; //restore before jmp back to core loop Me@42: Me@42: void *initialData; Me@42: Me@42: SchedSlot *schedSlot; Me@42: VMSReqst *requests; Me@42: Me@50: void *semanticData; //this lives here for the life of VP Me@50: void *dataReturnedFromReq;//values returned from plugin to VP go here Me@42: Me@50: //=========== MEASUREMENT STUFF ========== Me@42: #ifdef MEAS__TIME_STAMP_SUSP Me@42: unsigned int preSuspTSCLow; Me@42: unsigned int postSuspTSCLow; Me@42: #endif Me@42: #ifdef MEAS__TIME_MASTER Me@42: unsigned int startMasterTSCLow; Me@42: unsigned int endMasterTSCLow; Me@42: #endif Me@50: Me@50: float64 createPtInSecs; //have space but don't use on some configs Me@42: }; Me@42: //VirtProcr Me@42: Me@42: Me@42: typedef struct Me@42: { Me@42: SlaveScheduler slaveScheduler; Me@42: RequestHandler requestHandler; Me@42: Me@42: SchedSlot ***allSchedSlots; Me@42: SRSWQueueStruc **readyToAnimateQs; Me@42: VirtProcr **masterVPs; Me@42: Me@42: void *semanticEnv; Me@42: void *OSEventStruc; //for future, when add I/O to BLIS Me@50: MallocProlog *freeListHead; Me@50: int32 amtOfOutstandingMem; //total currently allocated Me@42: Me@42: void *coreLoopStartPt;//addr to jump to to re-enter coreLoop Me@42: void *coreLoopEndPt; //addr to jump to to shut down a coreLoop Me@42: Me@50: int32 setupComplete; Me@50: int32 masterLock; Me@42: Me@50: int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP Me@50: int32 numProcrsCreated; //gives ordering to processor creation Me@50: Me@50: //=========== MEASUREMENT STUFF ============= Me@50: IntervalProbe **intervalProbes; Me@50: DynArrayInfo *dynIntervalProbesInfo; Me@50: HashTable *probeNameHashTbl; Me@50: int32 masterCreateProbeID; Me@50: float64 createPtInSecs; Me@42: } Me@42: MasterEnv; Me@42: Me@42: Me@50: Me@50: Me@50: //======================= OS Thread related =============================== Me@42: Me@42: void * coreLoop( void *paramsIn ); //standard PThreads fn prototype Me@42: void * coreLoop_Seq( void *paramsIn ); //standard PThreads fn prototype Me@42: void masterLoop( void *initData, VirtProcr *masterPr ); Me@42: Me@42: Me@50: typedef struct Me@50: { Me@50: void *endThdPt; Me@50: unsigned int coreNum; Me@50: } Me@50: ThdParams; Me@42: Me@42: pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state Me@42: ThdParams *coreLoopThdParams [ NUM_CORES ]; Me@42: pthread_mutex_t suspendLock; Me@42: pthread_cond_t suspend_cond; Me@42: Me@50: Me@50: Me@50: //===================== Global Vars =================== Me@50: Me@42: volatile MasterEnv *_VMSMasterEnv; Me@42: Me@50: Me@50: Me@50: Me@50: //=========================== Function Prototypes ========================= Me@50: Me@50: //============== Setup and shutdown ============= Me@42: void Me@42: VMS__init(); Me@42: Me@42: void Me@42: VMS__init_Seq(); Me@42: Me@42: void Me@42: VMS__start_the_work_then_wait_until_done(); Me@42: Me@42: void Me@42: VMS__start_the_work_then_wait_until_done_Seq(); Me@42: Me@42: VirtProcr * Me@42: VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); Me@42: Me@50: //Use this to create processor inside entry point & other places outside Me@50: // the VMS system boundary (IE, not run in slave nor Master) Me@50: VirtProcr * Me@50: VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); Me@50: Me@42: VirtProcr * Me@42: VMS__create_the_shutdown_procr(); Me@42: Me@50: void Me@50: VMS__cleanup_after_shutdown(); Me@50: Me@50: Me@50: //============== Request Related =============== Me@50: Me@50: void Me@50: VMS__suspend_procr( VirtProcr *callingPr ); Me@50: Me@42: inline void Me@42: VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ); Me@42: Me@42: void Me@50: VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr ); Me@42: Me@42: void Me@42: VMS__free_request( VMSReqst *req ); Me@42: Me@42: void Me@42: VMS__remove_and_free_top_request( VirtProcr *reqstingPr ); Me@42: Me@42: VMSReqst * Me@42: VMS__take_top_request_from( VirtProcr *reqstingPr ); Me@42: Me@42: VMSReqst * Me@50: VMS__take_next_request_out_of( VirtProcr *procrWithReq ); Me@42: Me@42: inline void * Me@42: VMS__take_sem_reqst_from( VMSReqst *req ); Me@42: Me@42: inline int Me@42: VMS__isSemanticReqst( VMSReqst *req ); Me@42: Me@42: inline int Me@42: VMS__isDissipateReqst( VMSReqst *req ); Me@42: Me@42: inline int Me@42: VMS__isCreateReqst( VMSReqst *req ); Me@42: Me@42: //========================== Me@42: Me@50: void inline Me@42: VMS__dissipate_procr( VirtProcr *prToDissipate ); Me@42: Me@42: void Me@42: VMS__handle_dissipate_reqst( VirtProcr *procrToDissipate ); Me@42: Me@42: Me@42: Me@50: //===================== RDTSC wrapper ================== Me@42: Me@42: #define saveTimeStampCountInto(low, high) \ Me@42: asm volatile("RDTSC; \ Me@42: movl %%eax, %0; \ Me@42: movl %%edx, %1;" \ Me@42: /* outputs */ : "=m" (low), "=m" (high)\ Me@42: /* inputs */ : \ Me@42: /* clobber */ : "%eax", "%edx" \ Me@42: ); Me@42: Me@42: #define saveLowTimeStampCountInto(low) \ Me@42: asm volatile("RDTSC; \ Me@42: movl %%eax, %0;" \ Me@42: /* outputs */ : "=m" (low) \ Me@42: /* inputs */ : \ Me@42: /* clobber */ : "%eax", "%edx" \ Me@42: ); Me@42: Me@50: //======================== STATS ====================== Me@42: Me@50: #include "probes.h" Me@42: Me@42: #endif /* _VMS_H */ Me@42: