diff options
Diffstat (limited to 'utils/vmpi/vmpi_distribute_work.h')
| -rw-r--r-- | utils/vmpi/vmpi_distribute_work.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_distribute_work.h b/utils/vmpi/vmpi_distribute_work.h new file mode 100644 index 0000000..0435460 --- /dev/null +++ b/utils/vmpi/vmpi_distribute_work.h @@ -0,0 +1,89 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef VMPI_DISTRIBUTE_WORK_H +#define VMPI_DISTRIBUTE_WORK_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "messbuf.h" +#include "utlvector.h" + + +class IWorkUnitDistributorCallbacks +{ +public: + // Called every 200ms or so as it does the work. + // Return true to stop distributing work. + virtual bool Update() { return false; } + + // Called when a subsequent number of work units is completed. + // e.g. results received in the following order will trigger + // the following calls to OnWorkUnitsCompleted: + // Work unit numbers: wu2 wu4 wu5 wu1 wu0 wu6 wu3 + // Calling OnWorkUnitsCompleted with arg: - - - - 3 - 7 + // because when wu0 is received we already have { wu0, wu1, wu2 } so we signal + // that 3 subsequent work units completed, like wise by the time when wu3 is + // received we already have a full set { wu0, wu1, wu2, wu3, wu4, wu5, wu6 } + // and signal that 7 work units completed. + virtual void OnWorkUnitsCompleted( uint64 numWorkUnits ) { return; } +}; + + +enum EWorkUnitDistributor +{ + k_eWorkUnitDistributor_Default, + k_eWorkUnitDistributor_SDK +}; + +// Tells which work unit distributor is going to be used. +EWorkUnitDistributor VMPI_GetActiveWorkUnitDistributor(); + + +// Before calling DistributeWork, you can set this and it'll call your virtual functions. +extern IWorkUnitDistributorCallbacks *g_pDistributeWorkCallbacks; + + +// You must append data to pBuf with the work unit results. +// Note: pBuf will be NULL if this is a local thread doing work on the master. +typedef void (*ProcessWorkUnitFn)( int iThread, uint64 iWorkUnit, MessageBuffer *pBuf ); + +// pBuf is ready to read the results written to the buffer in ProcessWorkUnitFn. +typedef void (*ReceiveWorkUnitFn)( uint64 iWorkUnit, MessageBuffer *pBuf, int iWorker ); + + +// Use a CDispatchReg to register this function with whatever packet ID you give to DistributeWork. +bool DistributeWorkDispatch( MessageBuffer *pBuf, int iSource, int iPacketID ); + + + +// This is the function vrad and vvis use to divide the work units and send them out. +// It maintains a sliding window of work units so it can always keep the clients busy. +// +// The workers implement processFn to do the job work in a work unit. +// This function must send back a packet formatted with: +// cPacketID (char), cSubPacketID (char), iWorkUnit (int), (app-specific data for the results) +// +// The masters implement receiveFn to receive a work unit's results. +// +// Returns time it took to finish the work. +double DistributeWork( + uint64 nWorkUnits, // how many work units to dole out + char cPacketID, // This packet ID must be reserved for DistributeWork and DistributeWorkDispatch + // must be registered with it. + ProcessWorkUnitFn processFn, // workers implement this to process a work unit and send results back + ReceiveWorkUnitFn receiveFn // the master implements this to receive a work unit + ); + + +// VMPI calls this before shutting down because any threads that DistributeWork has running must stop, +// otherwise it can crash if a thread tries to send data in the middle of shutting down. +void DistributeWork_Cancel(); + + +#endif // VMPI_DISTRIBUTE_WORK_H |