コード例 #1
0
void PreDistributeWorkSync( CDSInfo *pInfo )
{
    if ( g_bMPIMaster )
    {
        // Send a message telling all the workers we're ready to go on this DistributeWork call.
        MessageBuffer mb;
        PrepareDistributeWorkHeader( &mb, DW_SUBPACKETID_MASTER_READY );
        VMPI_SendData( mb.data, mb.getLen(), VMPI_PERSISTENT );
    }
    else
    {
        if ( g_iVMPIVerboseLevel >= 1 )
            Msg( "PreDistributeWorkSync: waiting for master\n" );

        // Wait for the master's message saying it's ready to go.
        while ( g_iMasterReadyForDistributeWorkCall < g_iCurDSInfo )
        {
            VMPI_DispatchNextMessage();
        }

        if ( g_iVMPIVerboseLevel >= 1 )
            Msg( "PreDistributeWorkSync: master ready\n" );

        // Now tell the master we're ready.
        MessageBuffer mb;
        PrepareDistributeWorkHeader( &mb, DW_SUBPACKETID_WORKER_READY );
        VMPI_SendData( mb.data, mb.getLen(), VMPI_MASTER_ID );
    }
}
コード例 #2
0
void TellMasterThatWorkerStartedAWorkUnit( MessageBuffer &mb, CDSInfo *pInfo, WUIndexType iWU )
{
    mb.setLen( 0 );
    PrepareDistributeWorkHeader( &mb, DW_SUBPACKETID_WU_STARTED );
    mb.write( &iWU, sizeof( iWU ) );
    VMPI_SendData( mb.data, mb.getLen(), VMPI_MASTER_ID, k_eVMPISendFlags_GroupPackets );
}
コード例 #3
0
void SendQDirInfo()
{
	char cPacketID[2] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_DIRECTORIES };

	MessageBuffer mb;
	mb.write( cPacketID, 2 );
	mb.write( gamedir, strlen( gamedir ) + 1 );
	mb.write( qdir, strlen( qdir ) + 1 );

	VMPI_SendData( mb.data, mb.getLen(), VMPI_PERSISTENT );
}
コード例 #4
0
void DistributeWork_Master( CDSInfo *pInfo, ProcessWorkUnitFn processFn, ReceiveWorkUnitFn receiveFn )
{
    pInfo->m_WorkerInfo.m_pProcessFn = processFn;
    pInfo->m_MasterInfo.m_ReceiveFn = receiveFn;

    VMPITracker_Start( (int) pInfo->m_nWorkUnits );

    g_bMasterDistributingWork = true;
    g_pCurDistributorMaster->DistributeWork_Master( pInfo );
    g_bMasterDistributingWork = false;

    VMPITracker_End();

    // Tell all workers to move on.
    MessageBuffer mb;
    PrepareDistributeWorkHeader( &mb, DW_SUBPACKETID_MASTER_FINISHED );
    VMPI_SendData( mb.data, mb.getLen(), VMPI_PERSISTENT );

    // Clear the master's local completed work unit list.
    CMasterWorkUnitCompletedList *pList = g_MasterWorkUnitCompletedList.Lock();
    pList->m_CompletedWUs.RemoveAll();
    g_MasterWorkUnitCompletedList.Unlock();
}
コード例 #5
0
void VMPI_WorkerThread( int iThread, void *pUserData )
{
    CDSInfo *pInfo = (CDSInfo*)pUserData;
    CWorkerInfo *pWorkerInfo = &pInfo->m_WorkerInfo;


    // Get our index for running work units
    uint64 idxRunningWorkUnit = (uint64) iThread;
    {
        CCriticalSectionLock csLock( &pWorkerInfo->m_WorkUnitsRunningCS );
        csLock.Lock();
        pWorkerInfo->m_WorkUnitsRunning.ExpandWindow( idxRunningWorkUnit, ~0ull );
        csLock.Unlock();
    }


    MessageBuffer mb;
    PrepareDistributeWorkHeader( &mb, DW_SUBPACKETID_WU_RESULTS );

    MessageBuffer mbStartedWorkUnit;	// Special messagebuffer used to tell the master when we started a work unit.

    while ( g_iMasterFinishedDistributeWorkCall < g_iCurDSInfo && !g_bVMPIEarlyExit )
    {
        WUIndexType iWU;

        // Quit out when there are no more work units.
        if ( !g_pCurDistributorWorker->GetNextWorkUnit( &iWU ) )
        {
            // Wait until there are some WUs to do. This should probably use event handles.
            VMPI_Sleep( 10 );
            continue;
        }

        CCriticalSectionLock csLock( &pWorkerInfo->m_WorkUnitsRunningCS );
        csLock.Lock();

        // Check if this WU is not running
        WUIndexType const *pBegin = &pWorkerInfo->m_WorkUnitsRunning.Get( 0ull ), *pEnd = pBegin + pWorkerInfo->m_WorkUnitsRunning.PastVisibleIndex();
        WUIndexType const *pRunningWu = GenericFind( pBegin, pEnd, iWU );
        if ( pRunningWu != pEnd )
            continue;

        // We are running it
        pWorkerInfo->m_WorkUnitsRunning.Get( idxRunningWorkUnit ) = iWU;

        csLock.Unlock();


        // Process this WU and send the results to the master.
        mb.setLen( 4 );
        mb.write( &iWU, sizeof( iWU ) );

        // Set the current WU for the stats database.
        if ( iThread >= 0 && iThread < 4 )
        {
            g_ThreadWUs[iThread] = iWU;
        }

        // Tell the master we're starting on this WU.
        TellMasterThatWorkerStartedAWorkUnit( mbStartedWorkUnit, pInfo, iWU );


        pWorkerInfo->m_pProcessFn( iThread, iWU, &mb );
        g_pCurDistributorWorker->NoteLocalWorkUnitCompleted( iWU );

        VMPI_SendData( mb.data, mb.getLen(), VMPI_MASTER_ID, /*k_eVMPISendFlags_GroupPackets*/0 );

        // Flush grouped packets every once in a while.
        //VMPI_FlushGroupedPackets( 1000 );
    }

    if ( g_iVMPIVerboseLevel >= 1 )
        Msg( "Worker thread exiting.\n" );
}