blob: 6d556dd7b1aead583894048ab0dadf3516d6541c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Created on: 20 mai 2010
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmConcurrencyPrimitive.h"
#include <computer/ExecutionEnvironment.h>
#include <computer/primitive/AvmCommunicationRdvPrimitive.h>
#include <computer/primitive/AvmSynchronizationFactory.h>
#include <fml/expression/AvmCode.h>
#include <fml/runtime/RuntimeID.h>
namespace sep
{
/**
***************************************************************************
* execution of an INTERLEAVING program
***************************************************************************
*/
bool AvmPrimitive_Interleaving::run(ExecutionEnvironment & ENV)
{
AvmCode::const_iterator it = ENV.inCODE->begin();
AvmCode::const_iterator endIt = ENV.inCODE->end();
for( ; it != endIt ; ++it )
{
ENV.run( *it );
}
return( true );
}
bool AvmPrimitive_RdvInterleaving::run(ExecutionEnvironment & ENV)
{
ExecutionEnvironment tmpENV(ENV, BFCode::REF_NULL);
APExecutionData tmpED;
RdvConfigurationData aRdvConf(ENV, ENV.inCODE->size());
bool checkRdv = false;
bool checkMultiRdv = false;
bool hasCom = false;
avm_offset_t idx = 0;
ListOfAPExecutionData listofRDV;
AvmCode::const_iterator it = ENV.inCODE->begin();
AvmCode::const_iterator endIt = ENV.inCODE->end();
for( ; it != endIt ; ++it )
{
if( not tmpENV.run(*it) )
{
return( false );
}
// AVM_OS_COUT << "AvmPrimitive_RdvInterleaving::run :>" << std::endl;
// tmpENV.toStream(AVM_OS_COUT);
while( tmpENV.syncEDS.nonempty() )
{
tmpENV.syncEDS.pop_first_to( tmpED );
switch( tmpED->mAEES )
{
case AEES_WAITING_INCOM_RDV:
{
hasCom = true;
if( tmpED->mEXEC_SYNC_POINT->mRoutingData.isProtocolRDV() )
{
aRdvConf.IN_ED_RDV[ idx ].append( tmpED );
aRdvConf.mAwaitingOutputRdvFlag[ idx ] = true;
checkRdv = true;
}
else if( tmpED->mEXEC_SYNC_POINT->mRoutingData.
isProtocolMULTI_RDV() )
{
aRdvConf.ED_MULTIRDV[ idx ].append( tmpED );
aRdvConf.mAwaitingOutputMultiRdvFlag[ idx ] = true;
checkMultiRdv = true;
}
break;
}
case AEES_WAITING_OUTCOM_RDV:
{
hasCom = true;
if( tmpED->mEXEC_SYNC_POINT->mRoutingData.isProtocolRDV() )
{
aRdvConf.OUT_ED_RDV[ idx ].append( tmpED );
aRdvConf.mAwaitingInputRdvFlag[ idx ] = true;
checkRdv = true;
}
else if( tmpED->mEXEC_SYNC_POINT->mRoutingData.
isProtocolMULTI_RDV() )
{
aRdvConf.ED_MULTIRDV[ idx ].append( tmpED );
aRdvConf.mAwaitingInputMultiRdvFlag[ idx ] = true;
checkMultiRdv = true;
}
break;
}
default:
{
AVM_OS_FATAL_ERROR_EXIT
<< "Unexpected ENDIND EXECUTION STATUS :> "
<< RuntimeDef::strAEES( tmpED->mAEES ) << " !!!"
<< SEND_EXIT;
return( false );
}
}
}
if( hasCom )
{
idx = idx + 1;
hasCom = false;
}
}
// output EDS traitement
ENV.spliceOutput(tmpENV);
// Sync EDS traitement
if( idx > 1 )
{
aRdvConf.resize( idx );
if( checkRdv )
{
aRdvConf.updatePossibleInternalRdvFlag();
}
if( checkMultiRdv )
{
aRdvConf.updatePossibleInternalMultiRdvFlag();
}
if( aRdvConf.hasPossibleInternalRdvFlag || aRdvConf.hasPossibleInternalMultiRdvFlag )
{
AvmCommunicationRdvPrimitive rdvComputer(PRIMITIVE_PROCESSOR, aRdvConf, checkRdv, checkMultiRdv);
if( rdvComputer.resume_rdv(listofRDV) )
{
ENV.outEDS.splice( listofRDV );
}
}
}
return( true );
}
/**
***************************************************************************
* execution of an ASYNCHRONOUS program
***************************************************************************
*/
bool AvmPrimitive_Asynchronous::run(ExecutionEnvironment & ENV)
{
AVM_OS_FATAL_ERROR_EXIT
<< "TODO Primitive< |a| >::run( ENV )"
" a.k.a ASynchronous::run( ENV ) !!!"
<< SEND_EXIT;
AvmCode::const_iterator endIt = ENV.inCODE->end();
for( AvmCode::const_iterator it = ENV.inCODE->begin() ; it != endIt ; ++it )
{
ENV.run( *it );
}
return( true );
}
bool AvmPrimitive_RdvAsynchronous::run(ExecutionEnvironment & ENV)
{
AVM_OS_FATAL_ERROR_EXIT
<< "TODO Primitive< ||a|| >::run( ENV )"
" a.k.a RDV< ASynchronous >::run( ENV ) !!!"
<< SEND_EXIT;
AvmCode::const_iterator endIt = ENV.inCODE->end();
for( AvmCode::const_iterator it = ENV.inCODE->begin() ; it != endIt ; ++it )
{
ENV.run( *it );
}
return( true );
}
/**
***************************************************************************
* execution of a STRONG SYNCHRONOUS program
***************************************************************************
*/
bool AvmPrimitive_StrongSynchronous::run(ExecutionEnvironment & ENV)
{
ListOfAPExecutionData tmpListOfED;
ListOfAPExecutionData fusionListOfOutputED;
ListOfAPExecutionData::iterator itED;
ListOfAPExecutionData::iterator endItED;
APExecutionData tmpED;
APExecutionData anED;
AvmCode::const_iterator itEnd = ENV.inCODE->end();
AvmCode::const_iterator it = ENV.inCODE->begin();
// Initialisation du process
ExecutionEnvironment tmpENV(ENV, *it);
if( not tmpENV.run() )
{
return( false );
}
if( tmpENV.outEDS.nonempty() )
{
tmpListOfED.splice( tmpENV.outEDS );
}
else
{
// if an execution fail, this execution fail to!!!!!
return( false );
}
for( ++it ; it != itEnd ; ++it )
{
if( not tmpENV.run(*it) )
{
return( false );
}
if( tmpENV.outEDS.empty() )
{
// if a local execution fail, this global execution fail to!!!!!
return( false );
}
// COMPUTE STRONG FUSION
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
AVM_OS_TRACE << "<< " << ENV.inED->mRID.strUniqId()
<< " |=> strong fusion for ED :> "
<< "frstList( " << tmpENV.outEDS.size() << " )" << " with "
<< "scndList( " << tmpListOfED.size() << " )" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
if( tmpListOfED.empty() )
{
tmpListOfED.splice(tmpENV.outEDS);
}
else if( tmpENV.outEDS.nonempty() )
{
do
{
tmpENV.outEDS.pop_first_to( tmpED );
endItED = tmpListOfED.end();
for ( itED = tmpListOfED.begin() ; itED != endItED ; ++itED )
{
anED = AvmSynchronizationFactory::fusion(
ENV.inED, tmpED, (*itED));
if( anED.valid() )
{
fusionListOfOutputED.append( anED );
}
}
}
while( tmpENV.outEDS.nonempty() );
tmpListOfED.clear();
tmpListOfED.splice(fusionListOfOutputED);
}
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
AVM_OS_TRACE << ">> " << ENV.inED->mRID.strUniqId()
<< " |=> result( " << tmpListOfED.size() << " )" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
}
ENV.outEDS.splice( tmpListOfED );
return( true );
}
bool AvmPrimitive_RdvStrongSynchronous::run(ExecutionEnvironment & ENV)
{
AVM_OS_FATAL_ERROR_EXIT
<< "TODO Primitive< ||and|| >::run( ENV )"
" a.k.a RDV< StrongSynchronous >::run( ENV ) !!!"
<< SEND_EXIT;
AvmCode::const_iterator endIt = ENV.inCODE->end();
for( AvmCode::const_iterator it = ENV.inCODE->begin() ; it != endIt ; ++it )
{
ENV.run( *it );
}
return( true );
}
/**
***************************************************************************
* execution of a WEAK SYNCHRONOUS program
***************************************************************************
*/
bool AvmPrimitive_WeakSynchronous::run(ExecutionEnvironment & ENV)
{
ENV.inED->setEnabledLocalNodeCondition( true );
ListOfAPExecutionData oneListOfED;
ListOfAPExecutionData otherListOfED;
ListOfAPExecutionData resultListOfED;
AvmCode::const_iterator it = ENV.inCODE->begin();
AvmCode::const_iterator itEnd = ENV.inCODE->end();
// Initialisation du process
ExecutionEnvironment tmpENV(ENV, *it);
if( not tmpENV.run() )
{
return( false );
}
oneListOfED.splice( tmpENV.outEDS );
// Recurrence
for( ++it ; it != itEnd ; ++it )
{
if( not tmpENV.run(*it) )
{
return( false );
}
computeWeakSynchronous(ENV.inED,
oneListOfED, tmpENV.outEDS, resultListOfED);
oneListOfED.clear();
otherListOfED.clear();
while( resultListOfED.nonempty() )
{
resultListOfED.last()->setEnabledLocalNodeCondition( false );
oneListOfED.append( resultListOfED.pop_last() );
}
}
ENV.inED->setEnabledLocalNodeCondition( false );
ENV.outEDS.splice( oneListOfED );
return( true );
}
bool AvmPrimitive_WeakSynchronous::computeWeakSynchronous(
APExecutionData & anInputED, ListOfAPExecutionData & oneListOfED,
ListOfAPExecutionData & otherListOfED,
ListOfAPExecutionData & resultListOfED)
{
if( otherListOfED.empty() )
{
resultListOfED.splice( oneListOfED );
}
else if( oneListOfED.empty() )
{
resultListOfED.splice( otherListOfED );
}
else
{
ListOfAPExecutionData::iterator itOther = otherListOfED.begin();
ListOfAPExecutionData::iterator endOther = otherListOfED.end();
for( ; itOther != endOther ; ++itOther )
{
if( not computeWeakSynchronous(anInputED,
*itOther, oneListOfED, resultListOfED) )
{
return( false );
}
}
}
resultListOfED.makeUnique();
return( true );
}
bool AvmPrimitive_WeakSynchronous::computeWeakSynchronous(
APExecutionData & anInputED, APExecutionData & oneED,
ListOfAPExecutionData & listOfOtherED,
CollectionOfAPExecutionData & listOfOutputED)
{
APExecutionData anED;
ListOfAPExecutionData::iterator itOther;
ListOfAPExecutionData::iterator endOther = listOfOtherED.end();
// Fusion with OTHERS
for( itOther = listOfOtherED.begin() ; itOther != endOther ; ++itOther )
{
anED = AvmSynchronizationFactory::fusion(anInputED, oneED, *itOther);
if( anED != NULL )
{
listOfOutputED.append( anED );
}
}
// Compute OTHER where NOT ONE
if( not evalExclusive(anInputED, listOfOtherED, oneED, listOfOutputED) )
{
return( false );
}
// Compute ONE where NOT OTHERS
return( evalExclusive(anInputED, oneED, listOfOtherED, listOfOutputED) );
}
bool AvmPrimitive_WeakSynchronous::computeWeakSynchronous(
APExecutionData & anInputED, APExecutionData & oneED,
APExecutionData & otherED,
CollectionOfAPExecutionData & listOfOutputED)
{
APExecutionData anED = AvmSynchronizationFactory::fusion(
anInputED, oneED, otherED);
if( anED.valid() )
{
listOfOutputED.append( anED );
}
// Compute OTHER where NOT ONE
if( not evalExclusive(anInputED, otherED, oneED, listOfOutputED) )
{
return( false );
}
// Compute ONE where NOT OTHERS
return( evalExclusive(anInputED, oneED, otherED, listOfOutputED) );
}
bool AvmPrimitive_RdvWeakSynchronous::run(ExecutionEnvironment & ENV)
{
AVM_OS_FATAL_ERROR_EXIT
<< "TODO Primitive< ||or|| >::run( ENV )"
" a.k.a RDV< WeakSynchronous >::run( ENV ) !!!"
<< SEND_EXIT;
AvmCode::const_iterator endIt = ENV.inCODE->end();
for( AvmCode::const_iterator it = ENV.inCODE->begin() ; it != endIt ; ++it )
{
ENV.run( *it );
}
return( true );
}
/**
***************************************************************************
* execution of a PARALLEL program
***************************************************************************
*/
bool AvmPrimitive_Parallel::run(ExecutionEnvironment & ENV)
{
// avm_offset_t idx;
//
// std::vector< ExecutionEnvironment > tabOfENV(
// ENV.inCODE->size(), ExecutionEnvironment(ENV, ENV.inED) );
//
// AvmCode::const_iterator it = ENV.inCODE->begin();
// AvmCode::const_iterator itEnd = ENV.inCODE->end();
//
// // Cas de l'éventuel premier exitEDS
// for( idx = 0 ; it != itEnd ; ++it, ++idx )
// {
// if( not tabOfENV[idx].run(*it) )
// {
// return( false );
// }
// }
ListOfAPExecutionData fusionListOfOutputED;
ListOfAPExecutionData parallelOutputED;
ListOfAPExecutionData fusionListOfExitED;
ListOfAPExecutionData parallelExitED;
AvmCode::const_iterator it = ENV.inCODE->begin();
AvmCode::const_iterator itEnd = ENV.inCODE->end();
// Cas de l'éventuel premier exitEDS
for( ; (it != itEnd) && parallelExitED.empty() ; ++it )
{
ExecutionEnvironment tmpENV(ENV, *it);
if( tmpENV.run() )
{
ENV.spliceNotOutputExit(tmpENV);
if( tmpENV.exitEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelOutputED, parallelExitED);
}
if( tmpENV.outEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.outEDS,
parallelOutputED, fusionListOfOutputED);
parallelOutputED.clear();
parallelOutputED.splice(fusionListOfOutputED);
}
else if( tmpENV.exitEDS.nonempty() )
{
parallelOutputED.clear();
}
}
else
{
return( false );
}
}
// Cas de cohabitation outEDS et exitEDS
for( ; (it != itEnd) && parallelOutputED.nonempty() ; ++it )
{
ExecutionEnvironment tmpENV(ENV, *it);
if( tmpENV.run() )
{
ENV.spliceNotOutputExit(tmpENV);
if( tmpENV.outEDS.nonempty() )
{
// Composition entre << purs Output >>
computeParallel(ENV.inED, tmpENV.outEDS,
parallelOutputED, fusionListOfOutputED);
// Composition avec les << Exit précédents >>
computeParallel(ENV.inED, tmpENV.outEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.exitEDS.nonempty() )
{
// Composition avec les << Output précédents >>
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelOutputED, fusionListOfExitED);
// Composition entre << purs Exit >>
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.outEDS.nonempty() || tmpENV.exitEDS.nonempty() )
{
parallelOutputED.clear();
parallelOutputED.splice(fusionListOfOutputED);
parallelExitED.clear();
parallelExitED.splice(fusionListOfExitED);
}
}
else
{
return( false );
}
}
// Cas ou tout le monde est contaminé par exitEDS
for( ; it != itEnd ; ++it )
{
ExecutionEnvironment tmpENV(ENV, *it);
if( tmpENV.run() )
{
ENV.spliceNotOutputExit(tmpENV);
if( tmpENV.outEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.outEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.exitEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.outEDS.nonempty() || tmpENV.exitEDS.nonempty() )
{
parallelExitED.clear();
parallelExitED.splice(fusionListOfExitED);
}
}
else
{
return( false );
}
}
ENV.outEDS.splice( parallelOutputED );
ENV.exitEDS.splice( parallelExitED );
return( true );
}
void AvmPrimitive_Parallel::computeParallel(APExecutionData & refED,
ListOfAPExecutionData & outEDS,
ListOfAPExecutionData & prevParallelListOfOutputED,
ListOfAPExecutionData & listOfOutputED)
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
AVM_OS_TRACE << "<< " << refED->mRID.strUniqId()
<< " |=> parallel fusion for ED :> "
<< "frstList( " << outEDS.size() << " ) with "
<< "scndList( " << prevParallelListOfOutputED.size()
<< " )" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
if( prevParallelListOfOutputED.empty() )
{
listOfOutputED.splice(outEDS);
}
else if( outEDS.empty() )
{
listOfOutputED.splice(prevParallelListOfOutputED);
}
else
{
ListOfAPExecutionData::iterator itOutED;
ListOfAPExecutionData::iterator endOutED;
APExecutionData anED;
ListOfAPExecutionData::iterator itParallelED =
prevParallelListOfOutputED.begin();
ListOfAPExecutionData::iterator endParallelED =
prevParallelListOfOutputED.end();
endOutED = outEDS.end();
for( ; itParallelED != endParallelED ; ++itParallelED )
{
for( itOutED = outEDS.begin() ; itOutED != endOutED ; ++itOutED )
{
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
AVM_OS_TRACE << "ED<frst> "
<< (*itParallelED)->getRunnableElementTrace().str()
<< std::endl << "ED<scnd> "
<< (*itOutED)->getRunnableElementTrace().str()
<< std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
anED = AvmSynchronizationFactory::fusion(
refED, *itParallelED, *itOutED);
if( anED.valid() )
{
listOfOutputED.append( anED );
}
}
}
}
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
AVM_OS_TRACE << ">> " << refED->mRID.strUniqId() << " |=> result( "
<< listOfOutputED.size() << " )" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , COMPUTING , STATEMENT )
}
bool AvmPrimitive_RdvParallel::run(ExecutionEnvironment & ENV)
{
// avm_offset_t idx;
//
// std::vector< ExecutionEnvironment > tabOfENV(
// ENV.inCODE->size(), ExecutionEnvironment(ENV, ENV.inED) );
//
// AvmCode::const_iterator it = ENV.inCODE->begin();
// AvmCode::const_iterator itEnd = ENV.inCODE->end();
//
// // Cas de l'éventuel premier exitEDS
// for( idx = 0 ; it != itEnd ; ++it, ++idx )
// {
// if( not tabOfENV[idx].run(*it) )
// {
// return( false );
// }
// }
//
// if( AvmCommunicationRdvPrimitive::computeRdv(PRIMITIVE_PROCESSOR, tabOfENV) )
// {
// computeParallel(ENV.inED, listofRDV,
// parallelOutputED, fusionListOfOutputED);
//
// parallelOutputED.clear();
// parallelOutputED.splice(fusionListOfOutputED);
// }
// else
// {
// return( false );
// }
ListOfAPExecutionData fusionListOfOutputED;
ListOfAPExecutionData parallelOutputED;
ListOfAPExecutionData fusionListOfExitED;
ListOfAPExecutionData parallelExitED;
RdvConfigurationData aRdvConf(ENV, ENV.inCODE->size());
bool checkRdv = false;
bool checkMultiRdv = false;
bool hasCom = false;
avm_offset_t idx = 0;
ListOfAPExecutionData listofRDV;
AvmCode::const_iterator it = ENV.inCODE->begin();
AvmCode::const_iterator itEnd = ENV.inCODE->end();
// Cas de l'éventuel premier exitEDS
for( ; (it != itEnd) && parallelExitED.empty() ; ++it )
{
ExecutionEnvironment tmpENV(ENV, *it);
if( tmpENV.run() )
{
if( tmpENV.exitEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelOutputED, parallelExitED);
}
if( tmpENV.outEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.outEDS,
parallelOutputED, fusionListOfOutputED);
parallelOutputED.clear();
parallelOutputED.splice(fusionListOfOutputED);
}
else if( tmpENV.exitEDS.nonempty() )
{
parallelOutputED.clear();
}
if( tmpENV.syncEDS.nonempty() )
{
configureRdv(aRdvConf, tmpENV.syncEDS,
checkRdv, checkMultiRdv, hasCom, idx);
}
ENV.spliceNotOutputExit(tmpENV);
}
else
{
return( false );
}
}
// Cas de cohabitation outEDS et exitEDS
for( ; (it != itEnd) && parallelOutputED.nonempty() ; ++it )
{
ExecutionEnvironment tmpENV(ENV, *it);
if( tmpENV.run() )
{
if( tmpENV.outEDS.nonempty() )
{
// Composition entre << purs Output >>
computeParallel(ENV.inED, tmpENV.outEDS,
parallelOutputED, fusionListOfOutputED);
// Composition avec les << Exit précédents >>
computeParallel(ENV.inED, tmpENV.outEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.exitEDS.nonempty() )
{
// Composition avec les << Output précédents >>
computeParallel(ENV.inED, tmpENV.outEDS,
parallelOutputED, fusionListOfExitED);
// Composition entre << purs Exit >>
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.outEDS.nonempty() || tmpENV.exitEDS.nonempty() )
{
parallelOutputED.clear();
parallelOutputED.splice(fusionListOfOutputED);
parallelExitED.clear();
parallelExitED.splice(fusionListOfExitED);
}
if( tmpENV.syncEDS.nonempty() )
{
configureRdv(aRdvConf, tmpENV.syncEDS,
checkRdv, checkMultiRdv, hasCom, idx);
}
ENV.spliceNotOutputExit(tmpENV);
}
else
{
return( false );
}
}
// Cas ou tout le monde est contaminé par exitEDS
for( ; it != itEnd ; ++it )
{
ExecutionEnvironment tmpENV(ENV, *it);
if( tmpENV.run() )
{
if( tmpENV.outEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.outEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.exitEDS.nonempty() )
{
computeParallel(ENV.inED, tmpENV.exitEDS,
parallelExitED, fusionListOfExitED);
}
if( tmpENV.outEDS.nonempty() || tmpENV.exitEDS.nonempty() )
{
parallelExitED.clear();
parallelExitED.splice(fusionListOfExitED);
}
if( tmpENV.syncEDS.nonempty() )
{
configureRdv(aRdvConf, tmpENV.syncEDS,
checkRdv, checkMultiRdv, hasCom, idx);
}
ENV.spliceNotOutputExit(tmpENV);
}
else
{
return( false );
}
}
if( idx > 1 )
{
aRdvConf.resize( idx );
if( checkRdv )
{
aRdvConf.updatePossibleInternalRdvFlag();
}
if( checkMultiRdv )
{
aRdvConf.updatePossibleInternalMultiRdvFlag();
}
if( aRdvConf.hasPossibleInternalRdvFlag ||
aRdvConf.hasPossibleInternalMultiRdvFlag )
{
AvmCommunicationRdvPrimitive rdvComputer(PRIMITIVE_PROCESSOR,
aRdvConf, checkRdv, checkMultiRdv);
if( rdvComputer.resume_rdv(listofRDV) )
{
computeParallel(ENV.inED, listofRDV,
parallelOutputED, fusionListOfOutputED);
parallelOutputED.clear();
parallelOutputED.splice(fusionListOfOutputED);
}
}
}
ENV.outEDS.splice( parallelOutputED );
ENV.exitEDS.splice( parallelExitED );
return( true );
}
void AvmPrimitive_RdvParallel::configureRdv(RdvConfigurationData & aRdvConf,
ListOfAPExecutionData & syncEDS, bool & checkRdv,
bool & checkMultiRdv, bool & hasCom, avm_offset_t & idx)
{
APExecutionData tmpED;
while( syncEDS.nonempty() )
{
syncEDS.pop_first_to( tmpED );
switch( tmpED->mAEES )
{
case AEES_WAITING_INCOM_RDV:
{
hasCom = true;
if( tmpED->mEXEC_SYNC_POINT->mRoutingData.isProtocolRDV() )
{
aRdvConf.IN_ED_RDV[ idx ].append( tmpED );
aRdvConf.mAwaitingOutputRdvFlag[ idx ] = true;
checkRdv = true;
}
else if( tmpED->mEXEC_SYNC_POINT->mRoutingData.isProtocolMULTI_RDV() )
{
aRdvConf.ED_MULTIRDV[ idx ].append( tmpED );
aRdvConf.mAwaitingOutputMultiRdvFlag[ idx ] = true;
checkMultiRdv = true;
}
break;
}
case AEES_WAITING_OUTCOM_RDV:
{
hasCom = true;
if( tmpED->mEXEC_SYNC_POINT->mRoutingData.isProtocolRDV() )
{
aRdvConf.OUT_ED_RDV[ idx ].append( tmpED );
aRdvConf.mAwaitingInputRdvFlag[ idx ] = true;
checkRdv = true;
}
else if( tmpED->mEXEC_SYNC_POINT->mRoutingData.isProtocolMULTI_RDV() )
{
aRdvConf.ED_MULTIRDV[ idx ].append( tmpED );
aRdvConf.mAwaitingInputMultiRdvFlag[ idx ] = true;
checkMultiRdv = true;
}
break;
}
default:
{
AVM_OS_FATAL_ERROR_EXIT
<< "Unexpected ENDIND EXECUTION STATUS :> "
<< RuntimeDef::strAEES( tmpED->mAEES ) << " !!!"
<< SEND_EXIT;
}
}
}
if( hasCom )
{
idx = idx + 1;
hasCom = false;
}
}
/**
***************************************************************************
* execution of a PRODUCT program
***************************************************************************
*/
bool AvmPrimitive_Product::run(ExecutionEnvironment & ENV)
{
ENV.inED->setEnabledLocalNodeCondition( true );
ListOfAPExecutionData oneListOfED;
ListOfAPExecutionData otherListOfED;
ListOfAPExecutionData resultListOfED;
AvmCode::const_iterator it = ENV.inCODE->begin();
AvmCode::const_iterator itEnd = ENV.inCODE->end();
// Initialisation du process
ExecutionEnvironment tmpENV(ENV, *it);
if( not tmpENV.run() )
{
return( false );
}
oneListOfED.splice( tmpENV.outEDS );
// Recurrence
for( ++it ; it != itEnd ; ++it )
{
if( not tmpENV.run(*it) )
{
return( false );
}
computeProduct(ENV.inED, oneListOfED, tmpENV.outEDS, resultListOfED);
oneListOfED.clear();
otherListOfED.clear();
while( resultListOfED.nonempty() )
{
resultListOfED.last()->setEnabledLocalNodeCondition( false );
oneListOfED.append( resultListOfED.pop_last() );
}
}
ENV.inED->setEnabledLocalNodeCondition( false );
ENV.outEDS.splice( oneListOfED );
return( true );
}
bool AvmPrimitive_Product::computeProduct(APExecutionData & anInputED,
ListOfAPExecutionData & oneListOfED,
ListOfAPExecutionData & otherListOfED,
ListOfAPExecutionData & resultListOfED)
{
if( otherListOfED.empty() )
{
resultListOfED.splice( oneListOfED );
}
else if( oneListOfED.empty() )
{
resultListOfED.splice( otherListOfED );
}
else
{
ListOfAPExecutionData::iterator itOther = otherListOfED.begin();
ListOfAPExecutionData::iterator endOther = otherListOfED.end();
for( ; itOther != endOther ; ++itOther )
{
if( not computeProduct(anInputED,
*itOther, oneListOfED, resultListOfED) )
{
return( false );
}
}
}
resultListOfED.makeUnique();
return( true );
}
bool AvmPrimitive_Product::computeProduct(
APExecutionData & anInputED, APExecutionData & oneED,
ListOfAPExecutionData & listOfOtherED,
CollectionOfAPExecutionData & listOfOutputED)
{
APExecutionData anED;
ListOfAPExecutionData::iterator itOther;
ListOfAPExecutionData::iterator endOther = listOfOtherED.end();
// Fusion with OTHERS
for( itOther = listOfOtherED.begin() ; itOther != endOther ; ++itOther )
{
anED = AvmSynchronizationFactory::fusion(anInputED, oneED, *itOther);
if( anED.valid() )
{
listOfOutputED.append( anED );
}
}
// Compute OTHER where NOT ONE
if( not evalExclusive(anInputED, listOfOtherED, oneED, listOfOutputED) )
{
return( false );
}
// Compute ONE where NOT OTHERS
return( evalExclusive(anInputED, oneED, listOfOtherED, listOfOutputED) );
}
bool AvmPrimitive_Product::computeProduct(APExecutionData & anInputED,
APExecutionData & oneED, APExecutionData & otherED,
CollectionOfAPExecutionData & listOfOutputED)
{
APExecutionData anED = AvmSynchronizationFactory::fusion(
anInputED, oneED, otherED);
if( anED.valid() )
{
listOfOutputED.append( anED );
}
// Compute OTHER where NOT ONE
if( not evalExclusive(anInputED, otherED, oneED, listOfOutputED) )
{
return( false );
}
// Compute ONE where NOT OTHERS
return( evalExclusive(anInputED, oneED, otherED, listOfOutputED) );
}
/**
***************************************************************************
* execution of a SYNCHRONIZE program
***************************************************************************
*/
bool AvmPrimitive_Synchronize::run(ExecutionEnvironment & ENV)
{
ExecutionEnvironment tmpENV(ENV, ENV.inCODE->first());
if( not tmpENV.run( ENV.inCODE->first() ) )
{
return( false );
}
APExecutionData tmpED;
while( tmpENV.syncEDS.nonempty() )
{
tmpENV.syncEDS.pop_first_to( tmpED );
switch( tmpED->mAEES )
{
case AEES_WAITING_INCOM_RDV:
case AEES_WAITING_OUTCOM_RDV:
case AEES_WAITING_JOIN_FORK:
{
break;
}
default:
{
ENV.outEDS.append(tmpED);
break;
}
}
}
ENV.spliceOutput(tmpENV);
ENV.spliceNotOutput(tmpENV);
return( true );
}
}