blob: 3fc30e8989d0a5c6b2004b24ea113e064199b100 [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: 26 févr. 2014
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmInputEnabledPrimitive.h"
#include <builder/analysis/CommunicationDependency.h>
#include <computer/ExecutionEnvironment.h>
#include <computer/primitive/AvmCommunicationFactory.h>
#include <fml/executable/RoutingData.h>
namespace sep
{
/**
***************************************************************************
* execution of a INPUT_ENABLED program
***************************************************************************
*/
bool AvmPrimitive_InputEnabled::run(ExecutionEnvironment & ENV)
{
APExecutionData outED = ENV.inED;
ListOfInstanceOfPort * ieComs = NULL;
ListOfInstanceOfPort * ieSaves = NULL;
ListOfInstanceOfPort ieMutableComs;
ListOfInstanceOfPort ieMutableSaves;
// case of a composite machine
if( outED->mRID.getExecutable()->isMutableCommunication() )
{
CommunicationDependency::computeInputEnabledCom((* outED), outED->mRID,
ieMutableComs, ENV.inCODE->first().to_ptr< AvmCode >() );
if( ieMutableComs.empty() )
{
return( ENV.run(ENV.inCODE->first().bfCode()) );
}
CommunicationDependency::computeInputEnabledSave((* outED), outED->mRID,
ieMutableSaves, ENV.inCODE->first().to_ptr< AvmCode >() );
ieComs = & ieMutableComs;
ieSaves = & ieMutableSaves;
//!!! DEBUG TRACE
AVM_IF_DEBUG_FLAG( STATEMENT_SCHEDULING )
AVM_OS_TRACE << std::endl << "InputEnabled:mutable> " << outED->mRID.str()
<< std::endl;
outED->mRID.getExecutable()->getOnRun()->toStream(AVM_OS_TRACE);
outED->mRID.getExecutable()->toStreamStaticCom(AVM_OS_TRACE);
AVM_OS_TRACE << "com#input_enabled{" << std::endl;
BaseCompiledForm::toStreamStaticCom(AVM_OS_TRACE, ieMutableComs);
AVM_OS_TRACE << "}" << std::endl;
if( ieMutableSaves.nonempty() )
{
AVM_OS_TRACE << "com#input_enabled#save{" << std::endl;
BaseCompiledForm::toStreamStaticCom(AVM_OS_TRACE, ieMutableSaves);
AVM_OS_TRACE << "}" << std::endl;
}
AVM_ENDIF_DEBUG_FLAG( STATEMENT_SCHEDULING )
//!!! END DEBUG TRACE
}
else
{
// the expected (input) communication element
ieComs = &( outED->mRID.getExecutable()->getInputEnabledCom() );
// the save (input) communication element
ieSaves = &( outED->mRID.getExecutable()->getInputEnabledSave() );
//!!! DEBUG TRACE
AVM_IF_DEBUG_FLAG( STATEMENT_SCHEDULING )
AVM_OS_TRACE << std::endl << "InputEnabled:final> " << outED->mRID.str()
<< std::endl;
outED->mRID.getExecutable()->getOnRun()->toStream(AVM_OS_TRACE);
outED->mRID.getExecutable()->toStreamStaticCom(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_FLAG( STATEMENT_SCHEDULING )
//!!! END DEBUG TRACE
}
ListOfMessage saveMessages;
// the Buffer Instance
InstanceOfBuffer * ieBuffer =
outED->mRID.getExecutable()->getInputEnabledBuffer().front();
// the runtime buffer machine RID
RuntimeID tmpRID = outED->getRuntimeContainerRID(ieBuffer);
// the runtime (reading) buffer
const BaseBufferForm & readableBuffer =
outED->getRuntime(tmpRID).getBuffer( ieBuffer );
//!!! DEBUG TRACE
AVM_IF_DEBUG_FLAG( STATEMENT_SCHEDULING )
AVM_OS_TRACE << ieBuffer->getNameID() << ":>" << std::endl;
readableBuffer.toFscn(AVM_OS_TRACE, tmpRID);
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_FLAG( STATEMENT_SCHEDULING )
//!!! END DEBUG TRACE
if( readableBuffer.nonempty() )
{
// the runtime non-empty (writing) buffer
BaseBufferForm & writableBuffer = outED.getWritableRuntime(
tmpRID ).getWritableBuffer( ieBuffer );
//!!! DEBUG TRACE
AVM_IF_DEBUG_FLAG( STATEMENT_SCHEDULING )
AVM_OS_TRACE << std::endl << "InputEnabled:av> " << outED->mRID.str()
<< std::endl;
outED->mRID.getExecutable()->getOnRun()->toStream(AVM_OS_TRACE);
AVM_OS_TRACE << "com#input_enabled<mutable>{" << std::endl;
BaseCompiledForm::toStreamStaticCom(AVM_OS_TRACE, *ieComs);
AVM_OS_TRACE << "}" << std::endl;
if( ieSaves->nonempty() )
{
AVM_OS_TRACE << "com#input_enabled#save<mutable>{" << std::endl;
BaseCompiledForm::toStreamStaticCom(AVM_OS_TRACE, *ieSaves);
AVM_OS_TRACE << "}" << std::endl;
}
AVM_OS_TRACE << ieBuffer->getNameID() << ":>" << std::endl;
writableBuffer.toFscn(AVM_OS_TRACE, tmpRID);
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_FLAG( STATEMENT_SCHEDULING )
//!!! END DEBUG TRACE
ListOfSizeT ieMidComs;
RuntimeID aRoutingRID = outED->mRID;
ListOfInstanceOfPort::const_iterator itPort = ieComs->begin();
ListOfInstanceOfPort::const_iterator enItPort = ieComs->end();
for( ; itPort != enItPort ; ++itPort )
{
if( (*itPort)->hasInputRoutingData() )
{
ieMidComs.append( (*itPort)->getInputRoutingData().getMID() );
}
else
{
const RoutingData & aRoutingData = AvmCommunicationFactory::
searchInputRoutingData( outED, (*itPort), aRoutingRID );
if( aRoutingData.valid() )
{
ieMidComs.append( aRoutingData.getMID() );
}
}
}
if( ieSaves->empty() )
{
if( ieMidComs.nonempty() )
{
writableBuffer.popBefore( ieMidComs , outED->mRID);
}
else if( (*ieComs).nonempty() )
{
writableBuffer.popBefore( *ieComs , outED->mRID);
}
else
{
writableBuffer.popBefore( outED->mRID);
}
}
else
{
ListOfSizeT ieMidSaves;
enItPort = ieSaves->end();
for( itPort = ieSaves->begin() ; itPort != enItPort ; ++itPort )
{
if( (*itPort)->hasInputRoutingData() )
{
ieMidSaves.append(
(*itPort)->getInputRoutingData().getMID() );
}
}
while( writableBuffer.nonempty() )
{
if( ieMidComs.nonempty() )
{
if( ieMidComs.contains( writableBuffer.top().getMID() ) )
{
break;
}
}
else if( ieComs->contains( writableBuffer.top().getPort() ) )
{
break;
}
else if( ieMidSaves.nonempty() )
{
if( ieMidSaves.contains( writableBuffer.top().getMID() ) )
{
saveMessages.push_back( writableBuffer.pop() );
}
else
{
writableBuffer.pop();
}
}
else
{
if( ieSaves->contains( writableBuffer.top().getPort() ) )
{
saveMessages.push_back( writableBuffer.pop() );
}
else
{
writableBuffer.pop();
}
}
}
}
if( writableBuffer.nonempty() )
{
//!!! DEBUG TRACE
AVM_IF_DEBUG_FLAG( STATEMENT_SCHEDULING )
AVM_OS_TRACE << "InputEnabled:ap> FOUND COM !!!" << std::endl;
AVM_OS_TRACE << ieBuffer->getNameID() << ":>" << std::endl;
writableBuffer.toFscn(AVM_OS_TRACE, tmpRID);
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_FLAG( STATEMENT_SCHEDULING )
//!!! END DEBUG TRACE
}
ExecutionEnvironment tmpENV(ENV, outED, ENV.inCODE->first().bfCode());
if( tmpENV.run() )
{
if( saveMessages.nonempty() )
{
restoreMessage(tmpRID, ieBuffer, saveMessages, tmpENV.outEDS );
restoreMessage(tmpRID, ieBuffer, saveMessages, tmpENV.syncEDS);
restoreMessage(tmpRID, ieBuffer, saveMessages, tmpENV.irqEDS );
restoreMessage(tmpRID, ieBuffer, saveMessages, tmpENV.exitEDS);
}
ENV.spliceOutput( tmpENV );
return( true );
}
else
{
return( false );
}
}
else
{
return( ENV.run(ENV.inCODE->first().bfCode()) );
}
}
void AvmPrimitive_InputEnabled::restoreMessage(
const RuntimeID & rieRID, InstanceOfBuffer * ieBuffer,
ListOfMessage & saveMessages, ListOfAPExecutionData EDS)
{
ListOfAPExecutionData::iterator itED = EDS.begin();
ListOfAPExecutionData::iterator endED = EDS.end();
for( ; itED != endED ; ++itED )
{
(*itED).getWritableRuntime( rieRID ).getWritableBuffer(
ieBuffer ).restore( saveMessages );
}
}
} /* namespace sep */