Me@0: /* Me@0: * Copyright 2009 OpenSourceStewardshipFoundation.org Me@0: * Licensed under GNU General Public License version 2 Me@0: * Me@0: * Author: seanhalle@yahoo.com Me@0: * Me@0: */ Me@0: Me@0: #ifndef _VMS_H Me@0: #define _VMS_H Me@0: Me@0: #include "VMS_primitive_data_types.h" Me@0: #include "Queue_impl/BlockingQueue.h" Me@7: #include Me@0: Me@0: //This value is the number of hardware threads in the shared memory Me@5: // machine -- make double that number scheduling slots, plus extra for master Me@7: #define NUM_CORES 4 Me@5: #define NUM_SCHED_SLOTS 9 Me@0: Me@0: #define SUCCESS 0 Me@0: Me@0: #define thdAttrs NULL Me@0: Me@5: typedef struct _WorkUnit WorkUnit; Me@5: typedef struct _VirtProcr VirtProcr; Me@5: typedef struct _SlaveReqst SlaveReqst; Me@5: typedef struct _SchedSlot SchedSlot; Me@0: Me@5: typedef bool8 (*SlaveScheduler) ( SchedSlot *, void * ); Me@0: typedef void (*RequestHandler) ( SlaveReqst * ); Me@5: typedef void (*VirtProcrFnPtr) ( void *, VirtProcr * ); Me@5: typedef void VirtProcrFn( void *, VirtProcr * ); Me@0: Me@0: typedef struct Me@0: { Me@7: void *endThdPt; Me@7: unsigned int coreNum; Me@0: } Me@0: ThdParams; Me@0: Me@5: struct _SchedSlot Me@5: { Me@5: int workIsDone; Me@5: int needsProcrAssigned; Me@5: VirtProcr *procrAssignedToSlot; Me@5: }; Me@5: Me@5: Me@5: struct _VirtProcr Me@5: { Me@5: void *stackPtr; Me@5: void *framePtr; Me@5: void *nextInstrPt; Me@5: void *coreLoopStartPt; //allows proto-runtime to be linked later Me@5: Me@5: void *initialData; Me@5: Me@5: SchedSlot *schedSlot; Me@5: SlaveReqst *requests; Me@5: Me@5: void *semanticData; Me@5: }; Me@5: Me@5: Me@5: //When optimize make a separate flat array in here for each flag in SchedSlot Me@5: //So that polling done flags is fast.. not sure even worth it, though.. Me@0: typedef struct Me@0: { Me@5: SlaveScheduler slaveScheduler; Me@5: RequestHandler requestHandler; Me@0: Me@5: SchedSlot **schedSlots; Me@5: SchedSlot **filledSlots; Me@5: int numFilled; Me@5: Me@0: int stillRunning; Me@0: Me@5: VirtProcr *masterVirtPr; Me@0: void *semanticEnv; Me@5: void *OSEventStruc; //for future, when add I/O to BLIS Me@0: } Me@0: MasterEnv; Me@0: Me@0: Me@5: Me@5: struct _SlaveReqst Me@0: { Me@5: VirtProcr *slaveFrom; Me@5: int reqType; //for future when have I/O and OS services Me@5: void *semReqData; Me@0: Me@0: SlaveReqst *nextRequest; Me@0: }; Me@0: Me@0: Me@7: DWORD WINAPI coreLoop( LPVOID paramsIn ); Me@7: //void * coreLoop( void *paramsIn ); //standard PThreads fn prototype Me@7: void masterLoop( void *initData, VirtProcr *masterPr ); Me@0: Me@0: Me@0: //===================== Global Vars =================== Me@0: Me@5: Me@7: HANDLE coreLoopThds[ NUM_CORES ]; //windows handle to thread Me@7: ThdParams *thdParams[ NUM_CORES ]; Me@7: DWORD thdIds[ NUM_CORES ]; Me@0: Me@5: volatile MasterEnv *_VMSMasterEnv; Me@5: Me@5: //workQ is global, static, and volatile so that core loop has its location Me@5: // hard coded, and reloads every time through the loop -- that way don't Me@5: // need to save any regs used by core loop (will see if this really works) Me@5: volatile QueueStruc *_VMSWorkQ; Me@0: Me@7: //========================== Me@7: void Me@7: VMS__init(); Me@7: Me@7: void Me@7: VMS__start(); Me@7: Me@7: VirtProcr * Me@7: VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); Me@7: Me@7: inline void Me@7: VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ); Me@7: Me@7: void Me@7: VMS__suspend_processor( VirtProcr *callingPr ); Me@7: Me@0: Me@0: #endif /* _VMS_H */ Me@0: