blob: f7941b16e38092fda2ea7c4defbe57d3c0088ad1 [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: 28 nov. 2011
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AbstractProcessorUnit.h"
#include <fml/executable/ExecutableForm.h>
#include <fml/executable/ExecutableSystem.h>
#include <fml/runtime/ExecutionContext.h>
#include <fml/workflow/Query.h>
#include <fml/workflow/WObject.h>
#include <fam/queue/WaitingStrategy.h>
#include <sew/SymbexDispatcher.h>
#include <sew/SymbexEngine.h>
#include <sew/SymbexEventManager.h>
#include <boost/format.hpp>
namespace sep
{
/*
* Precedence for processor, based on resource consumption,
* used to order processor in the Diversity process !
* For info: 0 for minimum resource requirement reserved by the main processor,
* the STOP CRITERIA, and a great number for example REDUNDANCY processor !
* {
* preProcessing , postProcessing ,
* filteringInitialize , filteringFinalize
* preFiltering , postFiltering
* }
*/
const avm_uint8_t AbstractProcessorUnit::DEFAULT_PRECEDENCE_OF_PROCESSOR[5] =
{ 50 , 50 , 50 , 50 , 50 };
const avm_uint8_t AbstractProcessorUnit::DEFAULT_PRECEDENCE_OF_MAIN_PROCESSOR[5] =
{ 40 , 40 , 40 , 40 , 40 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_ACTIVE_COVERAGE_PROCESSOR[5] =
{ 40 , 40 , 40 , 40 , 40 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_PASSIVE_COVERAGE_PROCESSOR[5] =
{ 60 , 60 , 60 , 60 , 60 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_MAIN_PROCESSOR[5] =
{ 0 , 0 , 0 , 0 , 0 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_EXTENDER_PROCESSOR[5] =
{ 10 , 10 , 10 , 10 , 10 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_REDUNDANCY[5] =
{ 100 , 100 , 100 , 100 , 100 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_TRANSITION_COVERAGE[5] =
{ 40 , 40 , 40 , 40 , 40 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_HIT_OR_JUMP[5] =
{ 40 , 40 , 40 , 40 , 40 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_FORMULA_COVERAGE[5] =
{ 60 , 60 , 60 , 60 , 60 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_MACHINE_COVERAGE[5] =
{ 60 , 60 , 60 , 60 , 60 };
const avm_uint8_t AbstractProcessorUnit::PRECEDENCE_OF_TEST_OFFLINE[5] =
{ 40 , 40 , 40 , 40 , 40 };
const avm_uint8_t AbstractProcessorUnit::DEFAULT_PRECEDENCE_OF_SERIALIZER_PROCESSOR[5] =
{ 75 , 75 , 75 , 75 , 75 };
/**
* CONSTRUCTOR
* Default
*/
AbstractProcessorUnit::AbstractProcessorUnit(SymbexControllerUnitManager & aManager,
WObject * wfParameterObject, avm_computing_process_stage_t requiredStage,
const avm_uint8_t * aPrecedence)
: RunnableElement( CLASS_KIND_T( AbstractProcessorUnit ) , wfParameterObject ),
IProcessorUnitTest( *this ),
mControllerUnitManager( aManager ),
ENV( aManager.getPrimitiveProcessor() ),
mComputingStageRequired( requiredStage ),
mComputingStageEnabled( AVM_UNDEFINED_STAGE ),
mAutoConfigure( false ),
mAutoStart( false ),
mPrecedenceOfPreProcess( aPrecedence[0] ),
mPrecedenceOfPostProcess( aPrecedence[1] ),
mPrecedenceOfInitFilter( aPrecedence[2] ),
mPrecedenceOfPreFilter( aPrecedence[3] ),
mPrecedenceOfPostFilter( aPrecedence[4] ),
mBeginningStepTimout( 0 ),
mSliceCount( 0 ),
mPreEvalTraceFormatter( ),
mPostEvalTraceFormatter( ),
mBoundEvalTraceFormatter( ),
mReportEvalTraceFormatter( ),
////////////////////////////////////////////////////////////////////////////////
// Computing Variables
ecQueue( NULL ),
ecQueueIt( ),
ecQueueItEnd( ),
ecChildIt( ),
ecChildItEnd( )
{
//!! NOTHING
}
AbstractProcessorUnit::AbstractProcessorUnit(SymbexControllerUnitManager & aManager,
WObject * wfParameterObject, const avm_uint8_t * aPrecedence)
: RunnableElement( CLASS_KIND_T( AbstractProcessorUnit ) , wfParameterObject ),
IProcessorUnitTest( *this ),
mControllerUnitManager( aManager ),
ENV( aManager.getPrimitiveProcessor() ),
mComputingStageRequired( AVM_UNDEFINED_STAGE ),
mComputingStageEnabled( AVM_UNDEFINED_STAGE ),
mAutoConfigure( false ),
mAutoStart( false ),
mPrecedenceOfPreProcess( aPrecedence[0] ),
mPrecedenceOfPostProcess( aPrecedence[1] ),
mPrecedenceOfInitFilter( aPrecedence[2] ),
mPrecedenceOfPreFilter( aPrecedence[3] ),
mPrecedenceOfPostFilter( aPrecedence[4] ),
mBeginningStepTimout( 0 ),
mSliceCount( 0 ),
mPreEvalTraceFormatter( ),
mPostEvalTraceFormatter( ),
mBoundEvalTraceFormatter( ),
mReportEvalTraceFormatter( ),
////////////////////////////////////////////////////////////////////////////////
// Computing Variables
ecQueue( NULL ),
ecQueueIt( ),
ecQueueItEnd( ),
ecChildIt( ),
ecChildItEnd( )
{
//!! NOTHING
}
/**
* CONSTRUCTOR
* Other
*/
AbstractProcessorUnit::AbstractProcessorUnit(class_kind_t aClassKind,
SymbexControllerUnitManager & aManager, WObject * wfParameterObject)
: RunnableElement( aClassKind , wfParameterObject ),
IProcessorUnitTest( *this ),
mControllerUnitManager( aManager ),
ENV( aManager.getPrimitiveProcessor() ),
mComputingStageRequired( AVM_UNDEFINED_STAGE ),
mComputingStageEnabled( AVM_UNDEFINED_STAGE ),
mAutoConfigure( false ),
mAutoStart( false ),
mPrecedenceOfPreProcess( 0 ),
mPrecedenceOfPostProcess( 0 ),
mPrecedenceOfInitFilter( 0 ),
mPrecedenceOfPreFilter( 0 ),
mPrecedenceOfPostFilter( 0 ),
mBeginningStepTimout( 0 ),
mSliceCount( 0 ),
mPreEvalTraceFormatter( ),
mPostEvalTraceFormatter( ),
mBoundEvalTraceFormatter( ),
mReportEvalTraceFormatter( ),
////////////////////////////////////////////////////////////////////////////////
// Computing Variables
ecQueue( NULL ),
ecQueueIt( ),
ecQueueItEnd( ),
ecChildIt( ),
ecChildItEnd( )
{
//!! NOTHING
}
AbstractProcessorUnit::AbstractProcessorUnit(class_kind_t aClassKind,
SymbexEngine & anEngine, SymbexControllerUnitManager & aManager,
WObject * wfParameterObject)
: RunnableElement( aClassKind, wfParameterObject ),
IProcessorUnitTest( *this ),
mControllerUnitManager( aManager ),
ENV( anEngine.getPrimitiveProcessor() ),
mComputingStageRequired( AVM_UNDEFINED_STAGE ),
mComputingStageEnabled( AVM_UNDEFINED_STAGE ),
mAutoConfigure( false ),
mAutoStart( false ),
mPrecedenceOfPreProcess( 0 ),
mPrecedenceOfPostProcess( 0 ),
mPrecedenceOfInitFilter( 0 ),
mPrecedenceOfPreFilter( 0 ),
mPrecedenceOfPostFilter( 0 ),
mBeginningStepTimout( 0 ),
mSliceCount( 0 ),
mPreEvalTraceFormatter( ),
mPostEvalTraceFormatter( ),
mBoundEvalTraceFormatter( ),
mReportEvalTraceFormatter( ),
////////////////////////////////////////////////////////////////////////////////
// Computing Variables
ecQueue( NULL ),
ecQueueIt( ),
ecQueueItEnd( ),
ecChildIt( ),
ecChildItEnd( )
{
//!! NOTHING
}
/**
* GETTER
* SymbexEngine
* Configuration
* SymbexDispatcher
*
*/
SymbexEngine & AbstractProcessorUnit::getSymbexEngine() const
{
return( mControllerUnitManager.getSymbexEngine() );
}
Configuration & AbstractProcessorUnit::getConfiguration() const
{
return( mControllerUnitManager.getSymbexEngine().getConfiguration() );
}
SymbexDispatcher & AbstractProcessorUnit::getSymbexDispatcher() const
{
return( mControllerUnitManager.getSymbexEngine().getSymbexDispatcher() );
}
SymbexEventManager & AbstractProcessorUnit::getSymbexEventManager() const
{
return( getSymbexDispatcher().getSymbexEventManager() );
}
SymbexControllerRequestManager &
AbstractProcessorUnit::getSymbexRequestManager() const
{
return( getSymbexDispatcher().getSymbexControllerRequestManager() );
}
/**
* new local ExecutableForm for Processor usage
*/
ExecutableForm * AbstractProcessorUnit::newLocalExecutableForm()
{
ExecutableForm * localExec = new ExecutableForm(
getConfiguration().getExecutableSystem() , 0 );
if( hasParameterWObject() )
{
localExec->updateFullyQualifiedNameID(
getParameterWObject()->getFullyQualifiedNameID() );
}
return( localExec );
}
///**
// * GETTER
// * mProcessorManager
// */
//MainProcessorUnit & AbstractProcessorUnit::getMainProcessor()
//{
// return( mProcessorManager.getMainProcessor() );
//}
//
//const MainProcessorUnit & AbstractProcessorUnit::getMainProcessor() const
//{
// return( mProcessorManager.getMainProcessor() );
//}
//
//
///**
// * GETTER
// * the Builder
// */
//Builder & AbstractProcessorUnit::getBuilder()
//{
// return( mProcessorManager.getBuilder() );
//}
//
//
///**
// * GETTER
// * AvmPrimitiveProcessor
// */
//AvmPrimitiveProcessor & AbstractProcessorUnit::getPrimitiveProcessor()
//{
// return( mProcessorManager.getPrimitiveProcessor() );
//}
/**
* GETTER
* theExecutionQueue
*/
ExecutionQueue & AbstractProcessorUnit::getExecutionQueue()
{
return( mControllerUnitManager.getExecutionQueue() );
}
////////////////////////////////////////////////////////////////////////////////
// CONFIGURE API
////////////////////////////////////////////////////////////////////////////////
bool AbstractProcessorUnit::preConfigure()
{
WObject * theCONFIG = getParameterWObject();
theCONFIG = Query::getRegexWSequence(theCONFIG,
OR_WID2("manifest", "MANIFEST"), theCONFIG);
if( theCONFIG != WObject::_NULL_ )
{
mAutoStart = mControllerUnitManager.isAutoStart()
|| Query::getRegexWPropertyBoolean(theCONFIG,
CONS_WID2("auto", "start"), false);
mAutoConfigure = mAutoStart
|| mControllerUnitManager.isAutoConfigure()
|| Query::getRegexWPropertyBoolean(theCONFIG,
CONS_WID2("auto", "conf(igure)?"), false);
}
return( mAutoConfigure || mAutoStart || isEnablePlugin() );
}
bool AbstractProcessorUnit::configure()
{
// INITIALIZATION
mConfigFlag = RunnableElement::configure();
// For common parameters configuration
mConfigFlag = configureCommon() && mConfigFlag;
// standard processor user configuration
mConfigFlag = configureImpl() && mConfigFlag;
// auto registration
mConfigFlag = autoConfigureMOE() && mConfigFlag;
// scheduling configuration
mConfigFlag = configureLifecycleState() && mConfigFlag;
return( mConfigFlag );
}
bool AbstractProcessorUnit::configureCommon()
{
bool isOK = true;
// For Eval Trace format
isOK = configureLog() && isOK;
return( isOK );
}
bool AbstractProcessorUnit::configureLog()
{
bool isOK = true;
mPreEvalTraceFormatter = getDefaultPreEvalTraceFormatter();
mPostEvalTraceFormatter = getDefaultPostEvalTraceFormatter();
mBoundEvalTraceFormatter = getDefaultBoundEvalTraceFormatter();
mReportEvalTraceFormatter = getDefaultReportEvalTraceFormatter();
WObject * theLOG = Query::getWSequenceOrElse(
getParameterWObject(), "console", "LOG");
if( theLOG != WObject::_NULL_ )
{
mPreEvalTraceFormatter = Query::getWPropertyStringOrElse( theLOG,
"step", "eval", Query::getWPropertyString( theLOG, "format",
mPreEvalTraceFormatter) );
StringTools::replaceAll(mPreEvalTraceFormatter, "\\t", "\t");
StringTools::replaceAll(mPreEvalTraceFormatter, "\\n", "\n");
mPostEvalTraceFormatter = Query::getWPropertyStringOrElse( theLOG,
"result", "format", mPostEvalTraceFormatter );
StringTools::replaceAll(mPostEvalTraceFormatter, "\\t", "\t");
StringTools::replaceAll(mPostEvalTraceFormatter, "\\n", "\n");
mBoundEvalTraceFormatter = Query::getWPropertyStringOrElse( theLOG,
"bound", "format", mBoundEvalTraceFormatter );
StringTools::replaceAll(mBoundEvalTraceFormatter, "\\t", "\t");
StringTools::replaceAll(mBoundEvalTraceFormatter, "\\n", "\n");
mReportEvalTraceFormatter = Query::getWPropertyStringOrElse( theLOG,
"report", "format", mReportEvalTraceFormatter );
StringTools::replaceAll(mReportEvalTraceFormatter, "\\t", "\t");
StringTools::replaceAll(mReportEvalTraceFormatter, "\\n", "\n");
}
if( theLOG == NULL )
{
theLOG = getParameterWObject();
}
try
{
boost::format formatter(mPreEvalTraceFormatter);
}
catch(const boost::io::bad_format_string & bfs)
{
Query::reportErrorAttribute( theLOG, "eval", bfs.what());
isOK = false;
}
try
{
boost::format formatter(mPreEvalTraceFormatter);
}
catch(const boost::io::bad_format_string & bfs)
{
Query::reportErrorAttribute( theLOG, "result", bfs.what());
isOK = false;
}
try
{
boost::format formatter(mBoundEvalTraceFormatter);
}
catch(const boost::io::bad_format_string & bfs)
{
Query::reportErrorAttribute( theLOG, "bound", bfs.what());
isOK = false;
}
try
{
boost::format formatter(mReportEvalTraceFormatter);
}
catch(const boost::io::bad_format_string & bfs)
{
Query::reportErrorAttribute( theLOG, "report", bfs.what());
isOK = false;
}
return( isOK );
}
bool AbstractProcessorUnit::checkingConfiguration()
{
if( requiresStrongEnableFilter() && (not isStrongEnableFilter()) )
{
AVM_OS_CLOG << strTypeId()
<< ":> Failed to configure the CONTROLLER UNIT << "
<< strUniqId() << " >> " << std::endl;
if( isEnablePrefilter() )
{
AVM_OS_CLOG << "This CONTROLLER UNIT must be "
"in the POST-FILTER scheduler also !"
<< std::endl;
}
else
{
AVM_OS_CLOG << "This CONTROLLER UNIT must be "
"in the PRE-FILTER scheduler also !"
<< std::endl;
}
return( false );
}
return true;
}
/**
* API
* Auto configure Model Of Execution in CPU
*/
bool AbstractProcessorUnit::autoConfigureMOE()
{
bool isOK = true;
if( mAutoConfigure )
{
isOK = autoConfigureMOEImpl();
}
// checking of model of execution for processor
isOK = checkingConfiguration() && isOK;
return( isOK );
}
bool AbstractProcessorUnit::autoConfigureMOEImpl()
{
bool isOK = true;
if( mComputingStageRequired != AVM_UNDEFINED_STAGE )
{
mComputingStageEnabled = mComputingStageRequired;
//!![DEBUG]
//mProcessorManager.toStream(
// AVM_OS_DEBUG << "before autoConfigureMOEImpl< " << this->strUniqId()
// << " >" << std::endl );
if( (mComputingStageRequired & AVM_PRE_PROCESSING_STAGE) != 0 )
{
if( not mControllerUnitManager.registerPreprocessor( this ) )
{
isOK = false;
}
}
if( (mComputingStageRequired & AVM_POST_PROCESSING_STAGE) != 0 )
{
if( not mControllerUnitManager.registerPostprocessor( this ) )
{
isOK = false;
}
}
if( (mComputingStageRequired & AVM_PRE_FILTERING_STAGE) != 0 )
{
if( not mControllerUnitManager.registerPrefilter( this ) )
{
isOK = false;
}
}
if( (mComputingStageRequired & AVM_POST_FILTERING_STAGE) != 0 )
{
if( not mControllerUnitManager.registerPostfilter( this ) )
{
isOK = false;
}
}
//!![DEBUG]
//mProcessorManager.toStream(
// AVM_OS_DEBUG << std::endl << "after autoConfigureMOEImpl< "
// << this->strUniqId() << " >" << std::endl );
}
else
{
AVM_OS_DEBUG << "TODO autoConfigureMOEImpl< "
<< this->strUniqId() << " >" << std::endl;
}
return( isOK );
}
////////////////////////////////////////////////////////////////////////////////
// ENABLE & REGISTER PROCESS PLUGIN
////////////////////////////////////////////////////////////////////////////////
void AbstractProcessorUnit::enablePreprocess(AbstractProcessorUnit * aProcessor)
{
enablePreprocess();
mControllerUnitManager.addPreprocessor( aProcessor );
}
void AbstractProcessorUnit::enablePostprocess(AbstractProcessorUnit * aProcessor)
{
enablePostprocess();
mControllerUnitManager.addPostprocessor( aProcessor );
}
void AbstractProcessorUnit::enablePrefilter(AbstractProcessorUnit * aProcessor)
{
enablePrefilter();
mControllerUnitManager.addPrefilter( aProcessor );
}
void AbstractProcessorUnit::enablePostfilter(AbstractProcessorUnit * aProcessor)
{
enablePostfilter();
mControllerUnitManager.addPostfilter( aProcessor );
}
////////////////////////////////////////////////////////////////////////////////
// FILTER API
////////////////////////////////////////////////////////////////////////////////
bool AbstractProcessorUnit::prefilter()
{
ecQueue = &( getExecutionQueue().getReadyQueue() );
ecQueueIt = ecQueue->begin();
ecQueueItEnd = ecQueue->end();
for( ; ecQueueIt != ecQueueItEnd ; )
{
if( not prefilter(* (*ecQueueIt)) )
{
getExecutionQueue().appendFailed( *ecQueueIt );
ecQueueIt = ecQueue->erase(ecQueueIt);
}
else
{
++ecQueueIt;
}
}
return( getExecutionQueue().hasReady() );
}
bool AbstractProcessorUnit::postfilter()
{
ecQueue = &( getExecutionQueue().getResultQueue() );
ecQueueIt = ecQueue->begin();
ecQueueItEnd = ecQueue->end();
for( ; ecQueueIt != ecQueueItEnd ; )
{
if( mBeginningStepTimout > 0 )
{
++ecQueueIt;
--mBeginningStepTimout;
}
else
{
if( not postfilter(* (*ecQueueIt)) )
{
getExecutionQueue().appendFailed( *ecQueueIt );
ecQueueIt = ecQueue->erase(ecQueueIt);
}
else
{
++ecQueueIt;
}
}
}
return( getExecutionQueue().hasResult() );
}
/**
* REPORT
*/
void AbstractProcessorUnit::reportHeader(
OutStream & os, const std::string & processorName) const
{
os << TAB << processorName << " PROCESSOR";
AVM_IF_DEBUG_FLAG( CONFIGURING )
if( isWeakEnableFilter() )
{
os << " using as ";
if( isStrongEnableFilter() )
{
os << "(PRE & POST)";
}
if( isEnablePrefilter() )
{
os << "PRE";
}
else if( isEnablePostfilter() )
{
os << "POST";
}
os << "-FILTER";
}
if( isWeakEnableProcess() )
{
os << (isWeakEnableFilter() ? " &" : " using" ) << " as ";
if( isStrongEnableProcess() )
{
os << "(PRE & POST)";
}
else if( isEnablePreprocess() )
{
os << "PRE";
}
else if( isEnablePostprocess() )
{
os << "POST";
}
os << "-PROCESS";
}
AVM_ENDIF_DEBUG_FLAG_AND( CONFIGURING )
os << EOL;
}
void AbstractProcessorUnit::reportDefault(OutStream & os) const
{
AVM_OS_VERBOSITY_MEDIUM( os )
<< TAB << "FORMAL MODULE ANALYSIS< "
<< ( isNamed() ? strFQN() : strUniqId() )
<< " > DONE !!!" << EOL_FLUSH;
}
////////////////////////////////////////////////////////////////////////////////
// PROCESSOR REQUEST API
////////////////////////////////////////////////////////////////////////////////
/**
* REQUEUE_RESERVE
*/
void AbstractProcessorUnit::handleRequestRequeueReserveTable(
WaitingStrategy & aWaitingStrategy,
ListOfExecutionContext & aReserveQueue,
avm_uint8_t aWeightMin, avm_uint8_t aWeightMax)
{
aWaitingStrategy.pushChild( aReserveQueue );
}
////////////////////////////////////////////////////////////////////////////////
// PREFILTER REMOVE EC TOOLS
////////////////////////////////////////////////////////////////////////////////
avm_size_t AbstractProcessorUnit::remove(ExecutionContext * anEC,
OutStream & logger, const std::string & msg)
{
avm_size_t ecCount = 1; // 1 for sep::destroyElement( anEC );
// First remove child
if( anEC->hasNext() )
{
ExecutionContext::rw_child_iterator itEC = anEC->begin();
for( ExecutionContext * tmpEC = NULL ; itEC != anEC->end() ; )
{
tmpEC = (*itEC);
tmpEC->setContainer( NULL );
itEC = anEC->eraseChildContext( itEC );
ecCount += AbstractProcessorUnit::remove( tmpEC , logger , msg );
}
anEC->clearChildContext();
}
// Effective remove
if( anEC->hasPrevious() )
{
anEC->getPrevious()->removeChildContext(anEC);
}
getSymbexEventManager().notifyEventDestroyCtx( anEC );
AVM_IF_DEBUG_LEVEL_GTE_MEDIUM
logger << (( msg.empty() ) ? "A Plugin Processor remove the" : msg)
<< " EC:> " << anEC->str_min() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_GTE_MEDIUM
sep::destroyElement( anEC );
return( ecCount );
}
////////////////////////////////////////////////////////////////////////////////
// FINAL SLICING TOOLS
////////////////////////////////////////////////////////////////////////////////
bool AbstractProcessorUnit::isSliceableContext(ExecutionContext & anEC) const
{
return( anEC.noneInfo(*this) );
}
void AbstractProcessorUnit::computeLeafEC(
const ListOfExecutionContext & listOfRootEC,
ListOfExecutionContext & listOfLeafEC)
{
ListOfExecutionContext tmpListOfEC;
ListOfExecutionContext::const_iterator itEC = listOfRootEC.begin();
ListOfExecutionContext::const_iterator endEC = listOfRootEC.end();
for( ; itEC != endEC ; ++itEC )
{
if( (*itEC)->isLeafNode() )
{
listOfLeafEC.append( *itEC );
}
else
{
tmpListOfEC.append( (*itEC)->getNext() );
}
}
if( tmpListOfEC.nonempty() )
{
computeLeafEC(tmpListOfEC, listOfLeafEC);
}
}
void AbstractProcessorUnit::slice(ListOfExecutionContext & listOfLeafEC)
{
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_TRACE << getParameterWObject()->getFullyQualifiedNameID()
<< " :> CUT BACK" << std::endl;
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
while( listOfLeafEC.nonempty() )
{
slice(listOfLeafEC, listOfLeafEC.pop_last());
}
AVM_IF_DEBUG_FLAG( PROCESSOR )
AVM_OS_TRACE << getParameterWObject()->getFullyQualifiedNameID()
<< " :> CUT BACK END ( count: " << mSliceCount << " )"
<< std::endl;
AVM_ENDIF_DEBUG_FLAG( PROCESSOR )
}
void AbstractProcessorUnit::slice(
ListOfExecutionContext & listOfLeafEC,
ExecutionContext * leafEC)
{
if( (leafEC != NULL) && leafEC->isLeafNode()
&& isSliceableContext(* leafEC) )
{
ExecutionContext * containerEC = leafEC->getContainer();
if( containerEC != NULL )
{
ExecutionContext * tmpEC = NULL;
// Destroy des fils de theFatherEC sauf targetEC
ExecutionContext::rw_child_iterator it = containerEC->begin();
for( ; it != containerEC->end() ; )
{
tmpEC = (*it);
if( tmpEC->isLeafNode() && isSliceableContext(* tmpEC) )
{
AVM_IF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
tmpEC->traceMinimum(AVM_OS_TRACE << "\t");
AVM_ENDIF_DEBUG_LEVEL_FLAG( HIGH , PROCESSOR )
it = containerEC->eraseChildContext(it);
++mSliceCount;
listOfLeafEC.remove(tmpEC);
getSymbexEventManager().notifyEventDestroyCtx( tmpEC );
sep::destroyElement( tmpEC );
}
else
{
++it;
}
}
slice(listOfLeafEC, containerEC);
}
}
else
{
}
}
} /* namespace sep */