// Initialize algorithm GaMultithreadingAlgorithm::GaMultithreadingAlgorithm(const GaMultithreadingAlgorithmParams& parameters) : _parametersChange(false), _workerIdCounter(0) { _numberOfThreads = parameters.GetNumberOfWorkers() + 1; // make thread pool _threads = new GaThread*[ _numberOfThreads ]; // defalut thread parameters GaThreadParameter p; p._functionParameters = this; // initialize control and worker threads for( int i = 0; i < _numberOfThreads; i++ ) { p._functionPointer = !i ? ControlFlowWrapper : WorkFlowWrapper; _threads[ i ] = new GaThread( p, false ); } // initialize of semaphores for synchronization of worker threads MakeSemaphore( _workerForkSync, _numberOfThreads - 1, 0 ); MakeSemaphore( _workerJoinSync, _numberOfThreads - 1, 0 ); MakeEvent( _controlSync, 0 ); }
RageSemaphore::RageSemaphore( CString sName, int iInitialValue ): m_sName( sName ) { m_pSema = MakeSemaphore( iInitialValue ); }
// Sets new parameters for algorithm void GaMultithreadingAlgorithm::SetAlgorithmParameters(const GaAlgorithmParams& parameters) { int newCount = ( (const GaMultithreadingAlgorithmParams&)parameters ).GetNumberOfWorkers(); // state of algorithm couldnot be changed during parameter change BlockStateChange(); int oldCount = _numberOfThreads - 1; // nothing changed? if( oldCount == newCount ) { // now it safe to change state of algorithm ReleaseStateChange(); return; } // if algorithm is running - stop all worker threads if( _state == GAS_RUNNING ) { _parametersChange = true; // release working threads _workersThreadOut = _workersThreadIn = oldCount; UnlockSemaphore( _workerForkSync, oldCount ); // wait for working threads to be closed for( int i = 1; i <= oldCount; i++ ) _threads[ i ]->Join(); _parametersChange = false; } // remove synchronization objects DeleteSemaphore( _workerForkSync ); DeleteSemaphore( _workerJoinSync ); // make new synchronization object MakeSemaphore( _workerForkSync, newCount, 0 ); MakeSemaphore( _workerJoinSync, newCount, 0 ); // new thread pool GaThread** newThreads = new GaThread*[ newCount + 1 ]; // copy old needed threads int lim = min( oldCount, newCount ) + 1; for( int i = 0; i < lim; i++ ) newThreads[ i ] = _threads[ i ]; if( oldCount < newCount ) { // new threads should be added // new worker threads' parameters GaThreadParameter p; p._functionPointer = WorkFlowWrapper; p._functionParameters = this; // make new threads for( int i = newCount - oldCount + 1; i < newCount; i++ ) newThreads[ i ] = new GaThread( p, false ); } else { // threads should be remove // free old threads for( int i = oldCount - newCount + 1; i < oldCount; i++ ) delete _threads[ i ]; } // swap pool of threads delete[] _threads; _threads = newThreads; _numberOfThreads = newCount + 1; // restart working threads if they were running if( _state == GAS_RUNNING ) { for( int i = 1; i <= newCount; i++ ) _threads[ i ]->Start(); } // now it safe to change state of algorithm ReleaseStateChange(); }