seanhalle@0: /* seanhalle@0: * Copyright 2009 OpenSourceStewardshipFoundation.org seanhalle@0: * Licensed under GNU General Public License version 2 seanhalle@0: * seanhalle@0: * Author: seanhalle@yahoo.com seanhalle@0: * seanhalle@0: */ seanhalle@0: seanhalle@0: #ifndef _VSs_H seanhalle@0: #define _VSs_H seanhalle@0: seanhalle@0: #include "Queue_impl/PrivateQueue.h" seanhalle@0: #include "Hash_impl/PrivateHash.h" seanhalle@0: #include "VMS_impl/VMS.h" seanhalle@0: #include "Measurement/dependency.h" seanhalle@0: seanhalle@0: seanhalle@0: //=========================================================================== seanhalle@0: #define NUM_STRUCS_IN_SEM_ENV 1000 seanhalle@0: seanhalle@0: //This is hardware dependent -- it's the number of cycles of scheduling seanhalle@0: // overhead -- if a work unit is fewer than this, it is better being seanhalle@0: // combined sequentially with other work seanhalle@0: //This value depends on both VMS overhead and VSs's plugin. At some point seanhalle@0: // it will be derived by perf-counter measurements during init of VSs seanhalle@0: #define MIN_WORK_UNIT_CYCLES 20000 seanhalle@0: seanhalle@0: //=========================================================================== seanhalle@0: /*This header defines everything specific to the VSs semantic plug-in seanhalle@0: */ seanhalle@0: typedef struct _VSsSemReq VSsSemReq; seanhalle@0: typedef void (*VSsTaskFnPtr ) ( void *, SlaveVP *); seanhalle@0: typedef void (*PtrToAtomicFn ) ( void * ); //executed atomically in master seanhalle@0: //=========================================================================== seanhalle@0: seanhalle@0: #define NONCTLD 0 seanhalle@0: #define IN 1 /*Trick -- READER same as IN*/ seanhalle@0: #define OUT 2 /*Trick -- WRITER same as OUT and INOUT*/ seanhalle@0: #define INOUT 2 /*Trick -- WRITER same as OUT and INOUT*/ seanhalle@0: seanhalle@0: #define READER 1 /*Trick -- READER same as IN*/ seanhalle@0: #define WRITER 2 /*Trick -- WRITER same as OUT and INOUT*/ seanhalle@0: seanhalle@0: #define IS_A_THREAD NULL seanhalle@0: #define IS_ENDED NULL seanhalle@0: #define SEED_SLV NULL seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: VSsTaskFnPtr fn; seanhalle@0: int32 numTotalArgs;//the number of inputs to function seanhalle@0: int32 numCtldArgs;//how many of args have dependencies seanhalle@0: int32 *argTypes; //says reader, writer, or non-ctld seanhalle@0: int32 *argSizes; //for detecting overlap seanhalle@0: int32 sizeOfArgs; //for memcpy of args struct seanhalle@0: } seanhalle@0: VSsTaskType; seanhalle@0: seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: bool32 hasEnabledNonFinishedWriter; seanhalle@0: int32 numEnabledNonDoneReaders; seanhalle@0: PrivQueueStruc *waitersQ; seanhalle@0: } seanhalle@0: VSsPointerEntry; seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: void **args; //ctld args must come first, as ptrs seanhalle@0: VSsTaskType *taskType; seanhalle@0: int32 *taskID; seanhalle@0: int32 numBlockingProp; seanhalle@0: SlaveVP *slaveAssignedTo; //only valid before end task (thread) seanhalle@0: VSsPointerEntry **ptrEntries; seanhalle@0: void* parentTaskStub; seanhalle@0: int32 numLiveChildTasks; seanhalle@0: int32 numLiveChildThreads; seanhalle@0: bool32 isWaitingForChildTasksToEnd; seanhalle@0: bool32 isWaitingForChildThreadsToEnd; seanhalle@0: bool32 isEnded; seanhalle@0: } seanhalle@0: VSsTaskStub; seanhalle@0: seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: VSsTaskStub *taskStub; seanhalle@0: int32 argNum; seanhalle@0: int32 isReader; seanhalle@0: } seanhalle@0: VSsTaskStubCarrier; seanhalle@0: seanhalle@0: seanhalle@0: /*Semantic layer-specific data sent inside a request from lib called in app seanhalle@0: * to request handler called in AnimationMaster seanhalle@0: */ seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: SlaveVP *VPCurrentlyExecuting; seanhalle@0: PrivQueueStruc *waitingVPQ; seanhalle@0: } seanhalle@0: VSsTrans; seanhalle@0: seanhalle@0: /*WARNING: assembly hard-codes position of endInstrAddr as first field seanhalle@0: */ seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: void *endInstrAddr; seanhalle@0: int32 hasBeenStarted; seanhalle@0: int32 hasFinished; seanhalle@0: PrivQueueStruc *waitQ; seanhalle@0: } seanhalle@0: VSsSingleton; seanhalle@0: seanhalle@0: enum VSsReqType seanhalle@0: { seanhalle@0: submit_task = 1, seanhalle@0: end_task, seanhalle@0: create_slave, seanhalle@0: create_slave_w_aff, seanhalle@0: dissipate_slave, seanhalle@0: //=============================== seanhalle@0: send_type_to, seanhalle@0: receive_type_to, seanhalle@0: send_from_to, seanhalle@0: receive_from_to, seanhalle@0: //=============================== seanhalle@0: taskwait, seanhalle@0: malloc_req, seanhalle@0: free_req, seanhalle@0: singleton_fn_start, seanhalle@0: singleton_fn_end, seanhalle@0: singleton_data_start, seanhalle@0: singleton_data_end, seanhalle@0: atomic, seanhalle@0: trans_start, seanhalle@0: trans_end seanhalle@0: }; seanhalle@0: seanhalle@0: struct _VSsSemReq seanhalle@0: { enum VSsReqType reqType; seanhalle@0: SlaveVP *callingSlv; seanhalle@0: VSsTaskType *taskType; seanhalle@0: void *args; seanhalle@0: VSsTaskStub *taskStub; seanhalle@0: seanhalle@0: SlaveVP *senderSlv; seanhalle@0: SlaveVP *receiverSlv; seanhalle@0: int32 *senderID; seanhalle@0: int32 *receiverID; seanhalle@0: int32 msgType; seanhalle@0: void *msg; seanhalle@0: VSsSemReq *nextReqInHashEntry; seanhalle@0: int32 *taskID; seanhalle@0: seanhalle@0: TopLevelFnPtr fnPtr; seanhalle@0: void *initData; seanhalle@0: int32 coreToAssignOnto; seanhalle@0: seanhalle@0: int32 sizeToMalloc; seanhalle@0: void *ptrToFree; seanhalle@0: seanhalle@0: int32 singletonID; seanhalle@0: VSsSingleton **singletonPtrAddr; seanhalle@0: seanhalle@0: PtrToAtomicFn fnToExecInMaster; seanhalle@0: void *dataForFn; seanhalle@0: seanhalle@0: int32 transID; seanhalle@0: } seanhalle@0: /* VSsSemReq */; seanhalle@0: seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) seanhalle@0: PrivQueueStruc *freeExtraTaskSlvQ; //Shared seanhalle@0: PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) seanhalle@0: SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; seanhalle@0: HashTable *argPtrHashTbl; seanhalle@0: HashTable *commHashTbl; seanhalle@0: int32 numLiveExtraTaskSlvs; seanhalle@0: int32 numLiveThreadSlvs; seanhalle@0: int32 nextCoreToGetNewSlv; seanhalle@0: int32 primitiveStartTime; seanhalle@0: seanhalle@0: //fix limit on num with dynArray seanhalle@0: VSsSingleton fnSingletons[NUM_STRUCS_IN_SEM_ENV]; seanhalle@0: VSsTrans transactionStrucs[NUM_STRUCS_IN_SEM_ENV]; seanhalle@0: seanhalle@0: bool32 *coreIsDone; seanhalle@0: int32 numCoresDone; seanhalle@0: seanhalle@0: #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC seanhalle@0: ListOfArrays* unitList; seanhalle@0: ListOfArrays* ctlDependenciesList; seanhalle@0: ListOfArrays* commDependenciesList; seanhalle@0: NtoN** ntonGroups; seanhalle@0: PrivDynArrayInfo* ntonGroupsInfo; seanhalle@0: ListOfArrays* dynDependenciesList; seanhalle@0: Unit last_in_slot[NUM_CORES * NUM_ANIM_SLOTS]; seanhalle@0: ListOfArrays* hwArcs; seanhalle@0: #endif seanhalle@0: seanhalle@0: #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS seanhalle@0: ListOfArrays* counterList[NUM_CORES]; seanhalle@0: #endif seanhalle@0: SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS]; seanhalle@0: int shutdownInitiated; seanhalle@0: } seanhalle@0: VSsSemEnv; seanhalle@0: seanhalle@0: seanhalle@0: typedef struct _TransListElem TransListElem; seanhalle@0: struct _TransListElem seanhalle@0: { seanhalle@0: int32 transID; seanhalle@0: TransListElem *nextTrans; seanhalle@0: }; seanhalle@0: //TransListElem seanhalle@0: seanhalle@0: enum VSsSlvType seanhalle@0: { ExtraTaskSlv = 1, seanhalle@0: SlotTaskSlv, seanhalle@0: ThreadSlv seanhalle@0: }; seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: int32 highestTransEntered; seanhalle@0: TransListElem *lastTransEntered; seanhalle@0: bool32 needsTaskAssigned; seanhalle@0: VSsTaskStub *taskStub; seanhalle@0: enum VSsSlvType slaveType; seanhalle@0: } seanhalle@0: VSsSemData; seanhalle@0: seanhalle@0: //=========================================================================== seanhalle@0: seanhalle@0: void seanhalle@0: VSs__create_seed_slave_and_do_work( TopLevelFnPtr fn, void *initData ); seanhalle@0: seanhalle@0: int32 seanhalle@0: VSs__giveMinWorkUnitCycles( float32 percentOverhead ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__start_primitive(); seanhalle@0: seanhalle@0: int32 seanhalle@0: VSs__end_primitive_and_give_cycles(); seanhalle@0: seanhalle@0: int32 seanhalle@0: VSs__giveIdealNumWorkUnits(); seanhalle@0: seanhalle@0: int32 seanhalle@0: VSs__give_number_of_cores_to_schedule_onto(); seanhalle@0: seanhalle@0: //======================= seanhalle@0: seanhalle@0: void seanhalle@0: VSs__init(); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__cleanup_after_shutdown(); seanhalle@0: seanhalle@0: //======================= seanhalle@0: seanhalle@0: SlaveVP * seanhalle@0: VSs__create_thread( TopLevelFnPtr fnPtr, void *initData, seanhalle@0: SlaveVP *creatingThd ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__end_thread( SlaveVP *thdToEnd ); seanhalle@0: seanhalle@0: //======================= seanhalle@0: seanhalle@0: #define VSs__malloc( numBytes, callingSlave ) VMS_App__malloc( numBytes, callingSlave) seanhalle@0: seanhalle@0: #define VSs__free(ptrToFree, callingSlave ) VMS_App__free( ptrToFree, callingSlave ) seanhalle@0: seanhalle@0: seanhalle@0: //======================= seanhalle@0: void seanhalle@0: VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv); seanhalle@0: seanhalle@0: inline int32 * seanhalle@0: VSs__create_taskID_of_size( int32 numInts, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, seanhalle@0: SlaveVP *animSlv); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__end_task( SlaveVP *animSlv ); seanhalle@0: seanhalle@0: //========================= seanhalle@0: void seanhalle@0: VSs__taskwait(SlaveVP *animSlv); seanhalle@0: seanhalle@0: seanhalle@0: inline int32 * seanhalle@0: VSs__give_self_taskID( SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID, seanhalle@0: SlaveVP *senderSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ); seanhalle@0: seanhalle@0: void * seanhalle@0: VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ); seanhalle@0: seanhalle@0: void * seanhalle@0: VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ); seanhalle@0: seanhalle@0: //======================= Concurrency Stuff ====================== seanhalle@0: void seanhalle@0: VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__start_data_singleton( VSsSingleton **singeltonAddr, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__end_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, seanhalle@0: void *data, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@0: VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: seanhalle@0: //========================= Internal use only ============================= seanhalle@0: void seanhalle@0: VSs__Request_Handler( SlaveVP *requestingSlv, void *_semEnv ); seanhalle@0: seanhalle@0: SlaveVP * seanhalle@0: VSs__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot ); seanhalle@0: seanhalle@0: SlaveVP* seanhalle@0: VSs__create_slave_helper( TopLevelFnPtr fnPtr, void *initData, seanhalle@0: VSsSemEnv *semEnv, int32 coreToAssignOnto ); seanhalle@0: seanhalle@0: VSsTaskStub * seanhalle@0: create_thread_task_stub( void *initData ); seanhalle@0: seanhalle@0: seanhalle@0: SlaveVP * seanhalle@0: VSs__create_slave_with( TopLevelFnPtr fnPtr, void *initData, seanhalle@0: SlaveVP *creatingSlv ); seanhalle@0: seanhalle@0: SlaveVP * seanhalle@0: VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, seanhalle@0: SlaveVP *creatingSlv, int32 coreToAssignOnto); seanhalle@0: seanhalle@0: void seanhalle@0: idle_fn(void* data, SlaveVP *animatingSlv); seanhalle@0: seanhalle@0: //===================== Measurement of Lang Overheads ===================== seanhalle@0: #include "Measurement/VSs_Measurement.h" seanhalle@0: seanhalle@0: //=========================================================================== seanhalle@0: #endif /* _VSs_H */ seanhalle@0: