| /******************************************************************************* |
| * 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 */ |