blob: 8b7c80da0edb57d10b2130ba902fc202412ad8f4 [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: 19 nov. 2014
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmCoverageTraceDriver.h"
#include <builder/analysis/TransitionReachability.h>
#include <fml/executable/AvmTransition.h>
#include <fml/runtime/ExecutionContext.h>
#include <fml/runtime/ExecutionData.h>
#include <fml/runtime/RuntimeID.h>
#include <fml/trace/TracePoint.h>
#include <fam/coverage/BaseCoverageFilter.h>
namespace sep
{
////////////////////////////////////////////////////////////////////////////////
// TRACE DRIVER API
////////////////////////////////////////////////////////////////////////////////
bool AvmCoverageTraceDriver::initialize(
ExecutionContext * aDirectiveEC, AvmTransition * aTransition)
{
if( mTransitionTargetHistory.contains( aTransition ) )
{
return( false );
}
mTransitionTargetHistory.push_front( aTransition );
mTransitionTarget = aTransition;
mDirectiveEC = aDirectiveEC;
mDirectiveTrace.points.clear();
mPendingTrace.points.clear();
RuntimeID aRID = mDirectiveEC->refExecutionData().getRuntimeID(
mTransitionTarget->getExecutable() );
TransitionReachability pathChecker(*mDirectiveEC, aRID, mTransitionTarget);
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_COUT << std::endl << REPEAT("<<<<<<<<<<", 10) << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
if( (mInitializationFlag = pathChecker.computePath(mDirectiveTrace)) )
{
mPendingTrace.copyTrace( mDirectiveTrace );
mPendingTraceSize = mPendingTrace.points.size();
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
pathChecker.report(AVM_OS_COUT);
AVM_OS_COUT << REPEAT(">>>>>>>>>>", 10) << std::endl << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
return( mInitializationFlag );
}
bool AvmCoverageTraceDriver::process(const ListOfExecutionContext & aResultQueue)
{
ListOfExecutionContext::const_iterator ecQueueIt = aResultQueue.begin();
ListOfExecutionContext::const_iterator ecQueueItEnd = aResultQueue.end();
for( ; ecQueueIt != ecQueueItEnd ; ++ecQueueIt )
{
if( (*ecQueueIt) == mDirectiveEC )
{
return( drive() );
}
}
return( false );
}
bool AvmCoverageTraceDriver::drive()
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_COUT << std::endl << REPEAT("==========", 10) << std::endl;
AVM_OS_COUT << "Directive Trace:>" << std::endl;
mPendingTrace.toStream(AVM_OS_COUT);
AVM_OS_COUT << "Directive EC:> " << mDirectiveEC->str_min() << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
ExecutionContext::child_iterator itEC = mDirectiveEC->begin();
ExecutionContext::child_iterator endEC = mDirectiveEC->end();
avm_size_t coverageMax = 0;
avm_size_t coverageCount = 0;
BFList::const_iterator itTP;
BFList::const_iterator endTP = mPendingTrace.points.end();
for( ; itEC != endEC ; ++itEC )
{
coverageCount = 0;
for( itTP = mPendingTrace.points.begin() ; itTP != endTP ; ++itTP )
{
if( mTraceChecker.isSatTransition(*(*itEC),
(*itTP).to_ptr< TracePoint >(),
(*itEC)->getRunnableElementTrace()) )
{
++coverageCount;
}
else
{
break;
}
}
if( coverageCount > coverageMax )
{
coverageMax = coverageCount;
mDirectiveEC = (*itEC);
mDirectiveEC->setWeight( WEIGHT_STRONGLY_ACHIEVABLE );
}
else
{
(*itEC)->setWeight( WEIGHT_NON_PRIORITY );
}
}
if( coverageMax > 0 )
{
if( coverageMax < mPendingTraceSize )
{
for( coverageCount = 0 ; coverageCount < coverageMax ; ++coverageCount )
{
mPendingTrace.points.pop_front();
}
mPendingTraceSize = mPendingTraceSize - coverageMax;
mDirectiveEC->setWeight( WEIGHT_CERTAINLY_ACHIEVABLE );
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_COUT << "HIT ! EC:> "; mDirectiveEC->traceDefault(AVM_OS_COUT);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
else
{
mTransitionTargetHistory.pop_front();
mPendingTrace.points.clear();
mPendingTraceSize = 0;
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_COUT << "GOAL ACHIEVED !!!" << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_COUT << REPEAT("==========", 10) << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
return( true );
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
AVM_OS_COUT << REPEAT("==========", 10) << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , PROCESSOR , TRANSITION )
return( false );
}
////////////////////////////////////////////////////////////////////////////////
// SERIALIZATION API
////////////////////////////////////////////////////////////////////////////////
void AvmCoverageTraceDriver::toStream(OutStream & os) const
{
os << "Transition to reach :> ";
mTransitionTarget->toStreamHeader(os);
if( mTransitionTarget->hasInternalCommunicationCode() )
{
os << " ";
BaseCompiledForm::toStreamStaticCom(os,
mTransitionTarget->getInternalCommunicationCode());
}
os << EOL_FLUSH;
os << "Computed trace to reach it :> ";
mDirectiveTrace.toStream(os);
AVM_OS_COUT << "GOAL " << ( goalAchieved() ? "ACHIEVED" : "FAILED" )
<< " !!!" << std::endl;
}
} /* namespace sep */