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@2: #ifndef _VSs_H seanhalle@2: #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@3: #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@2: //This value depends on both VMS overhead and VSs's plugin. At some point seanhalle@2: // 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@2: /*This header defines everything specific to the VSs semantic plug-in seanhalle@0: */ seanhalle@2: typedef struct _VSsSemReq VSsSemReq; seanhalle@3: typedef void (*VSsTaskFnPtr ) ( void *, SlaveVP *); seanhalle@2: typedef void (*PtrToAtomicFn ) ( void * ); //executed atomically in master seanhalle@0: //=========================================================================== seanhalle@0: seanhalle@4: #define NONCTLD 0 seanhalle@4: #define IN 1 /*Trick -- READER same as IN*/ seanhalle@4: #define OUT 2 /*Trick -- WRITER same as OUT and INOUT*/ seanhalle@4: #define INOUT 2 /*Trick -- WRITER same as OUT and INOUT*/ seanhalle@2: seanhalle@4: #define READER 1 /*Trick -- READER same as IN*/ seanhalle@4: #define WRITER 2 /*Trick -- WRITER same as OUT and INOUT*/ seanhalle@1: seanhalle@8: #define IS_A_THREAD NULL seanhalle@8: #define IS_ENDED NULL seanhalle@8: #define SEED_SLV NULL seanhalle@8: seanhalle@1: typedef struct seanhalle@1: { seanhalle@1: VSsTaskFnPtr fn; seanhalle@2: int32 numTotalArgs;//the number of inputs to function seanhalle@2: int32 numCtldArgs;//how many of args have dependencies seanhalle@2: int32 *argTypes; //says reader, writer, or non-ctld seanhalle@2: int32 *argSizes; //for detecting overlap seanhalle@2: int32 sizeOfArgs; //for memcpy of args struct seanhalle@1: } seanhalle@1: VSsTaskType; seanhalle@1: seanhalle@1: seanhalle@2: typedef struct seanhalle@2: { seanhalle@3: bool32 hasEnabledNonFinishedWriter; seanhalle@3: int32 numEnabledNonDoneReaders; seanhalle@3: PrivQueueStruc *waitersQ; seanhalle@3: } seanhalle@3: VSsPointerEntry; seanhalle@3: seanhalle@6: typedef struct seanhalle@3: { seanhalle@2: void **args; //ctld args must come first, as ptrs seanhalle@2: VSsTaskType *taskType; seanhalle@4: int32 *taskID; seanhalle@2: int32 numBlockingProp; seanhalle@10: SlaveVP *slaveAssignedTo; //only valid before end task (thread) seanhalle@3: VSsPointerEntry **ptrEntries; nengel@11: void* parentTaskStub; seanhalle@8: int32 numLiveChildTasks; seanhalle@8: int32 numLiveChildThreads; seanhalle@8: bool32 isWaitingForChildTasksToEnd; seanhalle@8: bool32 isWaitingForChildThreadsToEnd; seanhalle@8: bool32 isEnded; seanhalle@2: } seanhalle@6: VSsTaskStub; nengel@5: seanhalle@2: seanhalle@2: typedef struct seanhalle@2: { seanhalle@2: VSsTaskStub *taskStub; seanhalle@2: int32 argNum; seanhalle@2: int32 isReader; seanhalle@2: } seanhalle@2: VSsTaskStubCarrier; seanhalle@2: seanhalle@2: seanhalle@2: typedef struct seanhalle@2: { seanhalle@2: int32 type; seanhalle@2: VSsTaskStub *taskStub; seanhalle@2: } seanhalle@2: VSsWaiterCarrier; seanhalle@1: 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@2: 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@2: VSsSingleton; seanhalle@0: seanhalle@2: enum VSsReqType seanhalle@0: { seanhalle@2: submit_task = 1, seanhalle@2: end_task, seanhalle@2: create_slave, seanhalle@2: create_slave_w_aff, seanhalle@2: dissipate_slave, seanhalle@2: //=============================== seanhalle@4: send_type_to, seanhalle@4: receive_type_to, seanhalle@4: send_from_to, seanhalle@4: receive_from_to, seanhalle@4: //=============================== nengel@5: 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@2: struct _VSsSemReq seanhalle@2: { enum VSsReqType reqType; seanhalle@2: SlaveVP *callingSlv; seanhalle@2: VSsTaskType *taskType; seanhalle@2: void *args; seanhalle@2: VSsTaskStub *taskStub; seanhalle@2: seanhalle@4: SlaveVP *senderSlv; seanhalle@4: SlaveVP *receiverSlv; seanhalle@4: int32 *senderID; seanhalle@4: int32 *receiverID; seanhalle@4: int32 msgType; seanhalle@4: void *msg; seanhalle@4: VSsSemReq *nextReqInHashEntry; seanhalle@4: int32 *taskID; seanhalle@4: seanhalle@2: 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@2: VSsSingleton **singletonPtrAddr; seanhalle@0: seanhalle@0: PtrToAtomicFn fnToExecInMaster; seanhalle@0: void *dataForFn; seanhalle@0: seanhalle@0: int32 transID; seanhalle@0: } seanhalle@2: /* VSsSemReq */; seanhalle@0: seanhalle@0: seanhalle@0: typedef struct seanhalle@0: { seanhalle@9: PrivQueueStruc *slavesReadyToResumeQ; //Shared (slaves not pinned) seanhalle@9: PrivQueueStruc *freeExtraTaskSlvQ; //Shared seanhalle@9: PrivQueueStruc *taskReadyQ; //Shared (tasks not pinned) seanhalle@10: SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; seanhalle@2: HashTable *argPtrHashTbl; seanhalle@4: HashTable *commHashTbl; seanhalle@8: int32 numLiveExtraTaskSlvs; seanhalle@8: int32 numLiveThreadSlvs; seanhalle@3: int32 nextCoreToGetNewSlv; seanhalle@0: int32 primitiveStartTime; seanhalle@0: seanhalle@0: //fix limit on num with dynArray seanhalle@2: VSsSingleton fnSingletons[NUM_STRUCS_IN_SEM_ENV]; seanhalle@2: VSsTrans transactionStrucs[NUM_STRUCS_IN_SEM_ENV]; seanhalle@3: seanhalle@3: bool32 *coreIsDone; seanhalle@3: 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@3: SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS]; seanhalle@0: int shutdownInitiated; seanhalle@0: } seanhalle@2: 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@8: enum VSsSlvType seanhalle@10: { ExtraTaskSlv = 1, seanhalle@10: SlotTaskSlv, seanhalle@10: ThreadSlv seanhalle@8: }; nengel@5: seanhalle@0: typedef struct seanhalle@0: { seanhalle@0: int32 highestTransEntered; seanhalle@0: TransListElem *lastTransEntered; seanhalle@2: bool32 needsTaskAssigned; seanhalle@2: VSsTaskStub *taskStub; seanhalle@9: enum VSsSlvType slaveType; seanhalle@0: } seanhalle@2: VSsSemData; seanhalle@0: seanhalle@0: //=========================================================================== seanhalle@0: seanhalle@0: void seanhalle@2: VSs__create_seed_slave_and_do_work( TopLevelFnPtr fn, void *initData ); seanhalle@0: seanhalle@0: int32 seanhalle@2: VSs__giveMinWorkUnitCycles( float32 percentOverhead ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__start_primitive(); seanhalle@0: seanhalle@0: int32 seanhalle@2: VSs__end_primitive_and_give_cycles(); seanhalle@0: seanhalle@0: int32 seanhalle@2: VSs__giveIdealNumWorkUnits(); seanhalle@0: seanhalle@0: int32 seanhalle@2: VSs__give_number_of_cores_to_schedule_onto(); seanhalle@0: seanhalle@0: //======================= seanhalle@0: seanhalle@0: void seanhalle@2: VSs__init(); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__cleanup_after_shutdown(); seanhalle@0: seanhalle@0: //======================= seanhalle@0: seanhalle@4: SlaveVP * seanhalle@7: VSs__create_thread( TopLevelFnPtr fnPtr, void *initData, seanhalle@7: SlaveVP *creatingThd ); seanhalle@0: seanhalle@0: void seanhalle@7: VSs__end_thread( SlaveVP *thdToEnd ); seanhalle@0: seanhalle@0: //======================= seanhalle@2: seanhalle@2: #define VSs__malloc( numBytes, callingSlave ) VMS_App__malloc( numBytes, callingSlave) seanhalle@2: seanhalle@2: #define VSs__free(ptrToFree, callingSlave ) VMS_App__free( ptrToFree, callingSlave ) seanhalle@2: seanhalle@2: seanhalle@2: //======================= seanhalle@4: void seanhalle@3: VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv); seanhalle@2: seanhalle@4: inline int32 * seanhalle@4: VSs__create_taskID_of_size( int32 numInts, SlaveVP *animSlv ); seanhalle@4: seanhalle@4: void seanhalle@4: VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, seanhalle@4: SlaveVP *animSlv); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__end_task( SlaveVP *animSlv ); seanhalle@0: seanhalle@4: //========================= nengel@5: void nengel@5: VSs__taskwait(SlaveVP *animSlv); nengel@5: seanhalle@4: seanhalle@4: inline int32 * seanhalle@4: VSs__give_self_taskID( SlaveVP *animSlv ); seanhalle@4: seanhalle@4: void seanhalle@4: VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID, seanhalle@4: SlaveVP *senderSlv ); seanhalle@4: seanhalle@4: void seanhalle@4: VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ); seanhalle@4: seanhalle@4: void * seanhalle@4: VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ); seanhalle@4: seanhalle@4: void * seanhalle@4: VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ); seanhalle@0: seanhalle@0: //======================= Concurrency Stuff ====================== seanhalle@0: void seanhalle@2: VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__start_data_singleton( VSsSingleton **singeltonAddr, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__end_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, seanhalle@0: void *data, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: void seanhalle@2: VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ); seanhalle@0: seanhalle@0: seanhalle@0: //========================= Internal use only ============================= seanhalle@0: void seanhalle@3: VSs__Request_Handler( SlaveVP *requestingSlv, void *_semEnv ); seanhalle@0: seanhalle@0: SlaveVP * seanhalle@2: VSs__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot ); seanhalle@0: seanhalle@0: SlaveVP* seanhalle@2: VSs__create_slave_helper( TopLevelFnPtr fnPtr, void *initData, seanhalle@2: VSsSemEnv *semEnv, int32 coreToAssignOnto ); seanhalle@0: seanhalle@7: VSsTaskStub * seanhalle@8: create_thread_task_stub( void *initData ); seanhalle@7: seanhalle@7: seanhalle@7: SlaveVP * seanhalle@7: VSs__create_slave_with( TopLevelFnPtr fnPtr, void *initData, seanhalle@7: SlaveVP *creatingSlv ); seanhalle@7: seanhalle@7: SlaveVP * seanhalle@7: VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, seanhalle@7: SlaveVP *creatingSlv, int32 coreToAssignOnto); seanhalle@7: seanhalle@9: void seanhalle@9: idle_fn(void* data, SlaveVP *animatingSlv); seanhalle@7: seanhalle@0: //===================== Measurement of Lang Overheads ===================== seanhalle@3: #include "Measurement/VSs_Measurement.h" seanhalle@0: seanhalle@0: //=========================================================================== seanhalle@2: #endif /* _VSs_H */ seanhalle@0: