From 3fe3a2dc5307ca82fbe3774559dbac406134ae13 Mon Sep 17 00:00:00 2001
From: apvrille <ludovic.apvrille@eurecom.fr>
Date: Thu, 2 Feb 2017 14:03:28 +0100
Subject: [PATCH] Resolving bug on RG generation by the SystemC simulator

---
 .../c++2/src_simulator/app/TMLCommand.cpp     | 488 +++++++++---------
 .../c++2/src_simulator/sim/Simulator.cpp      |  46 +-
 simulators/c++2/src_simulator/sim/Simulator.h |   3 +
 3 files changed, 282 insertions(+), 255 deletions(-)

diff --git a/simulators/c++2/src_simulator/app/TMLCommand.cpp b/simulators/c++2/src_simulator/app/TMLCommand.cpp
index 305d6e3800..ed36d7d1a5 100755
--- a/simulators/c++2/src_simulator/app/TMLCommand.cpp
+++ b/simulators/c++2/src_simulator/app/TMLCommand.cpp
@@ -1,42 +1,42 @@
 /*Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Daniel Knorreck,
-Ludovic Apvrille, Renaud Pacalet
- *
- * ludovic.apvrille AT telecom-paristech.fr
- *
- * This software is a computer program whose purpose is to allow the
- * edition of TURTLE analysis, design and deployment diagrams, to
- * allow the generation of RT-LOTOS or Java code from this diagram,
- * and at last to allow the analysis of formal validation traces
- * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
- * from INRIA Rhone-Alpes.
- *
- * This software is governed by the CeCILL  license under French law and
- * abiding by the rules of distribution of free software.  You can  use,
- * modify and/ or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
- *
- * As a counterpart to the access to the source code and  rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty  and the software's author,  the holder of the
- * economic rights,  and the successive licensors  have only  limited
- * liability.
- *
- * In this respect, the user's attention is drawn to the risks associated
- * with loading,  using,  modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean  that it is complicated to manipulate,  and  that  also
- * therefore means  that it is reserved for developers  and  experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and,  more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms.
- *
- */
+  Ludovic Apvrille, Renaud Pacalet
+  *
+  * ludovic.apvrille AT telecom-paristech.fr
+  *
+  * This software is a computer program whose purpose is to allow the
+  * edition of TURTLE analysis, design and deployment diagrams, to
+  * allow the generation of RT-LOTOS or Java code from this diagram,
+  * and at last to allow the analysis of formal validation traces
+  * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
+  * from INRIA Rhone-Alpes.
+  *
+  * This software is governed by the CeCILL  license under French law and
+  * abiding by the rules of distribution of free software.  You can  use,
+  * modify and/ or redistribute the software under the terms of the CeCILL
+  * license as circulated by CEA, CNRS and INRIA at the following URL
+  * "http://www.cecill.info".
+  *
+  * As a counterpart to the access to the source code and  rights to copy,
+  * modify and redistribute granted by the license, users are provided only
+  * with a limited warranty  and the software's author,  the holder of the
+  * economic rights,  and the successive licensors  have only  limited
+  * liability.
+  *
+  * In this respect, the user's attention is drawn to the risks associated
+  * with loading,  using,  modifying and/or developing or reproducing the
+  * software by the user in light of its specific status of free software,
+  * that may mean  that it is complicated to manipulate,  and  that  also
+  * therefore means  that it is reserved for developers  and  experienced
+  * professionals having in-depth computer knowledge. Users are therefore
+  * encouraged to load and test the software's suitability as regards their
+  * requirements in conditions enabling the security of their systems and/or
+  * data to be ensured and,  more generally, to use and operate it in the
+  * same conditions as regards security.
+  *
+  * The fact that you are presently reading this means that you have had
+  * knowledge of the CeCILL license and that you accept its terms.
+  *
+  */
 
 #include <TMLCommand.h>
 #include <TMLTask.h>
@@ -58,248 +58,248 @@ SimComponents* TMLCommand::_simComp=0;
 unsigned int TMLCommand::_branchNo=0;
 
 TMLCommand::TMLCommand(ID iID, TMLTask* iTask, TMLLength iLength, unsigned int iNbOfNextCmds, const char* iLiveVarList, bool iCheckpoint): _ID(iID), _length(iLength), _type(NONE), _progress(0), _currTransaction(0), _task(iTask), _nextCommand(0), /*_paramFunc(iParamFunc),*/ _nbOfNextCmds(iNbOfNextCmds), _breakpoint(0), _justStarted(true), _commandStartTime(-1), _liveVarList(iLiveVarList), _checkpoint(iCheckpoint), _execTimes(0), _coveredBranchMap(0){
-	if (dynamic_cast<TMLStopCommand*>(this)==0){
-		_instanceList.push_back(this);
-		_task->addCommand(iID, this);
-		if (_nbOfNextCmds>1){
-			//std::cout << "** " << this->toShortString() << " has " << _nbOfNextCmds << " branches.\n";
-			_branchNo+=_nbOfNextCmds;
-		}
-		
-	}
+  if (dynamic_cast<TMLStopCommand*>(this)==0){
+    _instanceList.push_back(this);
+    _task->addCommand(iID, this);
+    if (_nbOfNextCmds>1){
+      //std::cout << "** " << this->toShortString() << " has " << _nbOfNextCmds << " branches.\n";
+      _branchNo+=_nbOfNextCmds;
+    }
+
+  }
 }
 
 TMLCommand::~TMLCommand(){
-	//if (_currTransaction!=0) delete _currTransaction;  NEW
-	//if (_currTransaction!=0) std::cout << "transaction not yet deleted: " << getCommandStr() << std::endl;
-	if (_nextCommand!=0) delete[] _nextCommand;
-	_instanceList.remove(this);
-	removeBreakpoint();
+  //if (_currTransaction!=0) delete _currTransaction;  NEW
+  //if (_currTransaction!=0) std::cout << "transaction not yet deleted: " << getCommandStr() << std::endl;
+  if (_nextCommand!=0) delete[] _nextCommand;
+  _instanceList.remove(this);
+  removeBreakpoint();
 }
 
 TMLCommand* TMLCommand::prepare(bool iInit){
-	//Do not set _currTransaction=0 as specialized commands access the variable in the scope of the execute method (set terminated flag) 
-	//std::cout << "Prepare command ID: " << _ID << "\n";
-	if(_length==_progress){
-		TMLCommand* aNextCommand;
+  //Do not set _currTransaction=0 as specialized commands access the variable in the scope of the execute method (set terminated flag)
+  //std::cout << "Prepare command ID: " << _ID << "\n";
+  if(_length==_progress){
+    TMLCommand* aNextCommand;
 #ifdef STATE_HASH_ENABLED
-		if (_liveVarList!=0) _task->refreshStateHash(_liveVarList);
-		if(!_simComp->getOnKnownPath()){
-			//_task->refreshStateHash(_liveVarList);
-			if(_checkpoint){
-				ID aStateID=0;
-				aStateID = _simComp->checkForRecurringSystemState();
-				if (_currTransaction!=0) _currTransaction->setStateID(aStateID);
-			}
-		}
+    if (_liveVarList!=0) _task->refreshStateHash(_liveVarList);
+    if(!_simComp->getOnKnownPath()){
+      //_task->refreshStateHash(_liveVarList);
+      if(_checkpoint){
+        ID aStateID=0;
+        aStateID = _simComp->checkForRecurringSystemState();
+        if (_currTransaction!=0) _currTransaction->setStateID(aStateID);
+      }
+    }
 #endif
-		//std::cout << "COMMAND FINISHED!!n";
+    //std::cout << "COMMAND FINISHED!!n";
 #ifdef LISTENERS_ENABLED
-		NOTIFY_CMD_FINISHED(this);
-		//NOTIFY_CMD_FINISHED(_currTransaction);
-		if (_justStarted) NOTIFY_CMD_STARTED(this);
-		//if (_justStarted) NOTIFY_CMD_STARTED(_currTransaction);
+    NOTIFY_CMD_FINISHED(this);
+    //NOTIFY_CMD_FINISHED(_currTransaction);
+    if (_justStarted) NOTIFY_CMD_STARTED(this);
+    //if (_justStarted) NOTIFY_CMD_STARTED(_currTransaction);
 #endif
-		_progress=0;
-		_currTransaction=0;  //NEW!!!!!!!!!!!
-		_commandStartTime=-1; //NEW
-		_execTimes++;
-		//std::cerr << "Prepare command, get next command 1" << std::endl;
-		aNextCommand=getNextCommand();
-		//std::cerr << "Prepare command, get next command 2" << std::endl;
-		//std::cout << "Prepare command, to next command" << std::endl;
-		_task->setCurrCommand(aNextCommand);
-		if (aNextCommand==0){
-			return 0;
-		}else{
-			//std::cout << "Prepare command, prepare next command" << std::endl;
-			return aNextCommand->prepare(false);
-		}
-	}else{
-		if (_commandStartTime==((TMLTime)-1)){
-			_commandStartTime = SchedulableDevice::getSimulatedTime();
-		}
-		//std::cout << "Prepare next transaction TMLCmd " << _listeners.size() << std::endl;
-		TMLCommand* result;
-		if (iInit){
-			//if (_currTransaction!=0) delete _currTransaction;   NEW!!!!!!!!!!!!!!!!!!
-			if (_currTransaction==0){
-				//std::cout << "currTrans==0 " << std::endl;
-				result = prepareNextTransaction();  //NEW!!!!!!!!!!!!!!!!!!!!!!!!
-				//std::cout << "end prepare " << std::endl;
-			}else{
-				//std::cout << "currTrans!=0 " << std::endl;
-				result = _currTransaction->getCommand();
-				//std::cout << "end get cmd " << std::endl;
-			}
-			if (_progress==0) _justStarted=true;
-			//result=0; ///////////NEW
-		}else{
-			if (_progress==0){
+    _progress=0;
+    _currTransaction=0;  //NEW!!!!!!!!!!!
+    _commandStartTime=-1; //NEW
+    _execTimes++;
+    //std::cerr << "Prepare command, get next command 1" << std::endl;
+    aNextCommand=getNextCommand();
+    //std::cerr << "Prepare command, get next command 2" << std::endl;
+    //std::cout << "Prepare command, to next command" << std::endl;
+    _task->setCurrCommand(aNextCommand);
+    if (aNextCommand==0){
+      return 0;
+    }else{
+      //std::cout << "Prepare command, prepare next command" << std::endl;
+      return aNextCommand->prepare(false);
+    }
+  }else{
+    if (_commandStartTime==((TMLTime)-1)){
+      _commandStartTime = SchedulableDevice::getSimulatedTime();
+    }
+    //std::cout << "Prepare next transaction TMLCmd " << _listeners.size() << std::endl;
+    TMLCommand* result;
+    if (iInit){
+      //if (_currTransaction!=0) delete _currTransaction;   NEW!!!!!!!!!!!!!!!!!!
+      if (_currTransaction==0){
+        //std::cout << "currTrans==0 " << std::endl;
+        result = prepareNextTransaction();  //NEW!!!!!!!!!!!!!!!!!!!!!!!!
+        //std::cout << "end prepare " << std::endl;
+      }else{
+        //std::cout << "currTrans!=0 " << std::endl;
+        result = _currTransaction->getCommand();
+        //std::cout << "end get cmd " << std::endl;
+      }
+      if (_progress==0) _justStarted=true;
+      //result=0; ///////////NEW
+    }else{
+      if (_progress==0){
 #ifdef LISTENERS_ENABLED
-				NOTIFY_CMD_ENTERED(this);
+        NOTIFY_CMD_ENTERED(this);
 #else
 #ifdef EXPLO_ENABLED
-				if (dynamic_cast<IndeterminismSource*>(this)!=0) NOTIFY_CMD_ENTERED(this);
-				//if (dynamic_cast<TMLRandomCommand*>(this)!=0) NOTIFY_CMD_ENTERED(this);
+        if (dynamic_cast<IndeterminismSource*>(this)!=0) NOTIFY_CMD_ENTERED(this);
+        //if (dynamic_cast<TMLRandomCommand*>(this)!=0) NOTIFY_CMD_ENTERED(this);
 #endif
 #endif
-				_justStarted=true;
-			}else{
+        _justStarted=true;
+      }else{
 #ifdef LISTENERS_ENABLED
-				//NOTIFY_CMD_EXECUTED(this);
-				NOTIFY_CMD_EXECUTED(_currTransaction);
+        //NOTIFY_CMD_EXECUTED(this);
+        NOTIFY_CMD_EXECUTED(_currTransaction);
 #endif
-				if (_justStarted){
+        if (_justStarted){
 #ifdef LISTENERS_ENABLED
-					//NOTIFY_CMD_STARTED(_currTransaction);
-					NOTIFY_CMD_STARTED(this);
+          //NOTIFY_CMD_STARTED(_currTransaction);
+          NOTIFY_CMD_STARTED(this);
 #endif
-					_justStarted=false;
-				}
-			}
-			//std::cout << "Prepare next transaction" << std::endl;
-			result = prepareNextTransaction(); //NEW!!!!!!!!!!!!!!!!!!!!!!!!
-		}
-		//TMLCommand* result = prepareNextTransaction();   NEW!!!!!!!!!!!!!!!!!
-/*#ifdef REGISTER_TRANS_AT_CPU 
-		if (_currTransaction!=0 && _currTransaction->getVirtualLength()!=0){
-			_task->getCPU()->registerTransaction(_currTransaction,0);
-		}
-#endif*/
-		return result;
-	}
-	return 0;
-}
+          _justStarted=false;
+        }
+      }
+      //std::cout << "Prepare next transaction" << std::endl;
+      result = prepareNextTransaction(); //NEW!!!!!!!!!!!!!!!!!!!!!!!!
+    }
+    //TMLCommand* result = prepareNextTransaction();   NEW!!!!!!!!!!!!!!!!!
+    /*#ifdef REGISTER_TRANS_AT_CPU
+      if (_currTransaction!=0 && _currTransaction->getVirtualLength()!=0){
+      _task->getCPU()->registerTransaction(_currTransaction,0);
+      }
+      #endif*/
+    return result;
+  }
+    return 0;
+  }
 
-TMLCommand** TMLCommand::getNextCommands(unsigned int& oNbOfCmd) const{
-	//returned number is not correct for composite choice/choice commands and composite action/choice commands !!!!
-	oNbOfCmd=_nbOfNextCmds;
-	return _nextCommand;
-}
+    TMLCommand** TMLCommand::getNextCommands(unsigned int& oNbOfCmd) const{
+    //returned number is not correct for composite choice/choice commands and composite action/choice commands !!!!
+    oNbOfCmd=_nbOfNextCmds;
+    return _nextCommand;
+  }
 
-std::string TMLCommand::toString() const{
-	std::ostringstream outp;	
-	outp << _task->toString() << " len:" << _length << " progress:" << _progress << " ID:" << _ID;
-	return outp.str();
-}
+    std::string TMLCommand::toString() const{
+    std::ostringstream outp;
+    outp << _task->toString() << " len:" << _length << " progress:" << _progress << " ID:" << _ID;
+    return outp.str();
+  }
 
-void TMLCommand::setBreakpoint(GeneralListener* iBreakp){
-	removeBreakpoint();
-	_breakpoint=iBreakp;
-	registerListener(iBreakp);
-}
+    void TMLCommand::setBreakpoint(GeneralListener* iBreakp){
+    removeBreakpoint();
+    _breakpoint=iBreakp;
+    registerListener(iBreakp);
+  }
 
-void TMLCommand::removeBreakpoint(){	
-	if (_breakpoint!=0){
-		removeListener(_breakpoint);
-		delete _breakpoint;
-		_breakpoint=0;
-	}
-}
+    void TMLCommand::removeBreakpoint(){
+    if (_breakpoint!=0){
+    removeListener(_breakpoint);
+    delete _breakpoint;
+    _breakpoint=0;
+  }
+  }
 
-std::ostream& TMLCommand::writeObject(std::ostream& s){
-	WRITE_STREAM(s,_progress);
+    std::ostream& TMLCommand::writeObject(std::ostream& s){
+    WRITE_STREAM(s,_progress);
 #ifdef DEBUG_SERIALIZE
-	std::cout << "Write: TMLCommand " << _ID << " progress: " << _progress << std::endl;
+    std::cout << "Write: TMLCommand " << _ID << " progress: " << _progress << std::endl;
 #endif
-/*#ifdef SAVE_BENCHMARK_VARS 
-	WRITE_STREAM(s, _execTimes);
-#endif*/
-	return s;
-}
+    /*#ifdef SAVE_BENCHMARK_VARS
+      WRITE_STREAM(s, _execTimes);
+      #endif*/
+    return s;
+  }
 
-std::istream& TMLCommand::readObject(std::istream& s){
-	READ_STREAM(s,_progress);
+    std::istream& TMLCommand::readObject(std::istream& s){
+    READ_STREAM(s,_progress);
 #ifdef DEBUG_SERIALIZE
-	std::cout << "Read: TMLCommand " << _ID << " progress: " << _progress << std::endl;
+    std::cout << "Read: TMLCommand " << _ID << " progress: " << _progress << std::endl;
 #endif
-/*#ifdef SAVE_BENCHMARK_VARS 
-	READ_STREAM(s, _execTimes);
-#endif*/
+    /*#ifdef SAVE_BENCHMARK_VARS
+      READ_STREAM(s, _execTimes);
+      #endif*/
 #ifdef STATE_HASH_ENABLED
-	if (_liveVarList!=0) _task->refreshStateHash(_liveVarList);
+    if (_liveVarList!=0) _task->refreshStateHash(_liveVarList);
 #endif
-	//std::cout << "End Read Object TMLCommand " << _ID << std::endl;
-	return s;
-}
+    //std::cout << "End Read Object TMLCommand " << _ID << std::endl;
+    return s;
+  }
 
-void TMLCommand::reset(){
-	_progress=0;
-	//if (_currTransaction!=0) delete _currTransaction; NEW
-	_currTransaction=0;
-	_commandStartTime=-1;
-	//_execTimes=0;
-	//_stateHashes.clear();
-}
+    void TMLCommand::reset(){
+    _progress=0;
+    //if (_currTransaction!=0) delete _currTransaction; NEW
+    _currTransaction=0;
+    _commandStartTime=-1;
+    //_execTimes=0;
+    //_stateHashes.clear();
+  }
 
-void TMLCommand::registerGlobalListener(GeneralListener* iListener){
-	std::cout << "Global cmd listener created \n";
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		(*i)->registerListener(iListener);
-	}
-}
+    void TMLCommand::registerGlobalListener(GeneralListener* iListener){
+    std::cout << "Global cmd listener created \n";
+    for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+    (*i)->registerListener(iListener);
+  }
+  }
 
-template<typename T>
-void TMLCommand::registerGlobalListenerForType(GeneralListener* iListener, TMLTask* aTask){
-	//std::cout << "Global cmd listener created \n";
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		if (dynamic_cast<T*>(*i)!=0 && (aTask==0 || (*i)->getTask()==aTask)) (*i)->registerListener(iListener);
-	}
-}
+    template<typename T>
+      void TMLCommand::registerGlobalListenerForType(GeneralListener* iListener, TMLTask* aTask){
+    //std::cout << "Global cmd listener created \n";
+    for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+    if (dynamic_cast<T*>(*i)!=0 && (aTask==0 || (*i)->getTask()==aTask)) (*i)->registerListener(iListener);
+  }
+  }
 
-void TMLCommand::removeGlobalListener(GeneralListener* iListener){
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		(*i)->removeListener(iListener);
-	}
-}
+    void TMLCommand::removeGlobalListener(GeneralListener* iListener){
+    for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+    (*i)->removeListener(iListener);
+  }
+  }
 
-void TMLCommand::streamStateXML(std::ostream& s){
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		s << TAG_CMDo << " id=\"" << (*i)->_ID << "\">" << TAG_EXECTIMESo << (*i)->_execTimes << TAG_EXECTIMESc << TAG_CMDc << "\n";
-	}
-}
+    void TMLCommand::streamStateXML(std::ostream& s){
+    for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+    s << TAG_CMDo << " id=\"" << (*i)->_ID << "\">" << TAG_EXECTIMESo << (*i)->_execTimes << TAG_EXECTIMESc << TAG_CMDc << "\n";
+  }
+  }
 
-TMLCommand* TMLCommand::getCommandByID(ID iID){
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		if ((*i)->_ID == iID) return *i;
-	}
-	return 0;
-}
+    TMLCommand* TMLCommand::getCommandByID(ID iID){
+    for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+    if ((*i)->_ID == iID) return *i;
+  }
+    return 0;
+  }
 
-unsigned int TMLCommand::getCmdCoverage(){
-	unsigned int aCoveredCmds=0;
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		if ((*i)->_execTimes>0) aCoveredCmds++; //else std::cout << "Not covered: " << (*i)->toShortString() << "\n";
+    unsigned int TMLCommand::getCmdCoverage(){
+      unsigned int aCoveredCmds=0;
+      for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+	if ((*i)->_execTimes>0) aCoveredCmds++; //else std::cout << "Not covered: " << (*i)->toShortString() << "\n";
+      }
+      //std::cout << "Total no of commands: " << _instanceList.size() << "\n";
+      return aCoveredCmds * 100 / _instanceList.size();
+    }
+    
+    unsigned int TMLCommand::getBranchCoverage(){
+      unsigned int aCoveredBranchNo=0;
+      //std::cout << "Total branch no: " << _branchNo << "\n";
+      for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+	//if ((*i)->_nbOfNextCmds>1) std::cout << "** " << (*i)->toShortString() << " ID " << (*i)->_ID << " has " << (*i)->_nbOfNextCmds << " branches, covered map : " << (*i)->_coveredBranchMap << "\n";
+	long unsigned int aCoveredBranchMap = (*i)->_coveredBranchMap;
+	while (aCoveredBranchMap>0){
+	  aCoveredBranchNo++;
+	  aCoveredBranchMap >>=1;
 	}
-	//std::cout << "Total no of commands: " << _instanceList.size() << "\n";
-	return aCoveredCmds * 100 / _instanceList.size();
-}
-
-unsigned int TMLCommand::getBranchCoverage(){
-	unsigned int aCoveredBranchNo=0;
-	//std::cout << "Total branch no: " << _branchNo << "\n";
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		//if ((*i)->_nbOfNextCmds>1) std::cout << "** " << (*i)->toShortString() << " ID " << (*i)->_ID << " has " << (*i)->_nbOfNextCmds << " branches, covered map : " << (*i)->_coveredBranchMap << "\n";
-		long unsigned int aCoveredBranchMap = (*i)->_coveredBranchMap;
-		while (aCoveredBranchMap>0){
-			aCoveredBranchNo++;
-			aCoveredBranchMap >>=1;
-		}
-	}
-	return (_branchNo==0)? 100: aCoveredBranchNo * 100 / _branchNo;
-}
-
-void TMLCommand::clearCoverageVars(){
-	for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
-		(*i)->_execTimes=0;
-		(*i)->_coveredBranchMap=0;
-	}
-}
-
-template void TMLCommand::registerGlobalListenerForType<IndeterminismSource>(GeneralListener* iListener, TMLTask* aTask);
-template void TMLCommand::registerGlobalListenerForType<TMLChoiceCommand>(GeneralListener* iListener, TMLTask* aTask);
-template void TMLCommand::registerGlobalListenerForType<TMLActionCommand>(GeneralListener* iListener, TMLTask* aTask);
-template void TMLCommand::registerGlobalListenerForType<TMLNotifiedCommand>(GeneralListener* iListener, TMLTask* aTask);
-template void TMLCommand::registerGlobalListenerForType<TMLWaitCommand>(GeneralListener* iListener, TMLTask* aTask);
-
+      }
+      return (_branchNo==0)? 100: aCoveredBranchNo * 100 / _branchNo;
+    }
+    
+    void TMLCommand::clearCoverageVars(){
+      for(std::list<TMLCommand*>::const_iterator i=_instanceList.begin(); i != _instanceList.end(); ++i){
+	(*i)->_execTimes=0;
+	(*i)->_coveredBranchMap=0;
+      }
+    }
+    
+    template void TMLCommand::registerGlobalListenerForType<IndeterminismSource>(GeneralListener* iListener, TMLTask* aTask);
+    template void TMLCommand::registerGlobalListenerForType<TMLChoiceCommand>(GeneralListener* iListener, TMLTask* aTask);
+    template void TMLCommand::registerGlobalListenerForType<TMLActionCommand>(GeneralListener* iListener, TMLTask* aTask);
+    template void TMLCommand::registerGlobalListenerForType<TMLNotifiedCommand>(GeneralListener* iListener, TMLTask* aTask);
+    template void TMLCommand::registerGlobalListenerForType<TMLWaitCommand>(GeneralListener* iListener, TMLTask* aTask);
+    
diff --git a/simulators/c++2/src_simulator/sim/Simulator.cpp b/simulators/c++2/src_simulator/sim/Simulator.cpp
index 874a66dd52..a0a30a911e 100644
--- a/simulators/c++2/src_simulator/sim/Simulator.cpp
+++ b/simulators/c++2/src_simulator/sim/Simulator.cpp
@@ -72,6 +72,7 @@ TMLTransaction* Simulator::getTransLowestEndTime(SchedulableDevice*& oResultDevi
   TMLTransaction *aMarker=0, *aTempTrans;
   TMLTime aLowestTime=-1;
   SchedulableDevice* aTempDevice;
+  
   //static unsigned int aTransitionNo=0;
 #ifdef DEBUG_KERNEL
   std::cout << "kernel:getTLET: before loop" << std::endl;
@@ -780,6 +781,8 @@ void Simulator::decodeCommand(std::string iCmd, std::ostream& iXmlOutStream){
         //#endif
         unsigned int aTransCounter=0;
         _terminateExplore=false;
+	_nbOfBranchesToExplore = 1;
+	_nbOfBranchesExplored = 0;
         exploreTree(0, 0, myAUTfile, aTransCounter);
         //#ifdef DOT_GRAPH_ENABLED
         //myDOTfile << "}\n";
@@ -1435,11 +1438,15 @@ bool Simulator::runUntilCondition(std::string& iCond, TMLTask* iTask, TMLTransac
 }
 
 void Simulator::exploreTree(unsigned int iDepth, ID iPrevID, std::ofstream& iAUTFile, unsigned int& oTransCounter){
+  
   TMLTransaction* aLastTrans;
   //if (iDepth<RECUR_DEPTH){
   ID aLastID;
   bool aSimTerminated=false;
   IndeterminismSource* aRandomCmd;
+
+  //std::cout << "Command coverage current:"<<  TMLCommand::getCmdCoverage() << " to reach:" << _commandCoverage << " nbOfBranchesExplored:"<< _nbOfBranchesExplored << " nbOfBranchesToExplore:" << _nbOfBranchesToExplore << " branch coverage:" <<_branchCoverage <<std::endl;
+  
   do{
     aSimTerminated=runToNextRandomCommand(aLastTrans);
     aRandomCmd = _simComp->getCurrentRandomCmd();
@@ -1454,44 +1461,61 @@ void Simulator::exploreTree(unsigned int iDepth, ID iPrevID, std::ofstream& iAUT
     //#else
     //(21,"i(allCPUsTerminated)", 25)
     iAUTFile << "(" << aLastID << "," << "\"i(allCPUsTerminated<" << SchedulableDevice::getSimulatedTime() << ">)\"," << TMLTransaction::getID() << ")\n";
+    _nbOfBranchesExplored ++;
     //#endif
     TMLTransaction::incID();
 
-    if(_commandCoverage <= TMLCommand::getCmdCoverage() && _branchCoverage <= TMLCommand::getBranchCoverage()){
-      _simComp->setStopFlag(true, MSG_COVREACHED);
-      _terminateExplore=true;
-      //_syncInfo->_terminate=true;
+    //if(_commandCoverage <= TMLCommand::getCmdCoverage() && _branchCoverage <= TMLCommand::getBranchCoverage()){
+    //std::cout << "Command coverage current:"<<  TMLCommand::getCmdCoverage() << " to reach:" << _commandCoverage << " nbOfBranchesExplored:"<< _nbOfBranchesExplored << " nbOfBranchesToExplore:" << _nbOfBranchesToExplore<< std::endl;
+    if (_commandCoverage <= TMLCommand::getCmdCoverage()) {
+      if (_nbOfBranchesExplored > 0) {
+	if (100 * _nbOfBranchesExplored / _nbOfBranchesToExplore >= _branchCoverage) {
+	  //std::cout << "*********************************** 100% REACH" << std::endl;
+	  _simComp->setStopFlag(true, MSG_COVREACHED);
+	  _terminateExplore=true;
+	  //_syncInfo->_terminate=true;
+	}
+      }
     }
   } else if (_simComp->wasKnownStateReached()==0){
-    std::cout << "No known state reached" << std::endl;
+    //std::cout << "No known state reached" << std::endl;
     if(aRandomCmd==0){
-      std::cout << "We should never get here\n";
-    } else{
+      //std::cout << "We should never get here\n";
+    } else {
+      //std::cout << "Command coverage current:"<<  TMLCommand::getCmdCoverage() << " to reach:" << _commandCoverage << " nbOfBranchesExplored:"<< _nbOfBranchesExplored << " nbOfBranchesToExplore:" << _nbOfBranchesToExplore<< std::endl;
+      
       unsigned int aNbNextCmds;
       std::stringstream aStreamBuffer;
       std::string aStringBuffer;
       aNbNextCmds = aRandomCmd->getRandomRange();
-      std::cout << "Simulation " << iPrevID << "_" << "continued " << aNbNextCmds << std::endl;
+      //std::cout << "Simulation " << iPrevID << "_" << "continued nb of nexts commands:" << aNbNextCmds << std::endl;
       _simComp->writeObject(aStreamBuffer);
       aStringBuffer=aStreamBuffer.str();
       if ((aNbNextCmds & INT_MSB)==0){
+	_nbOfBranchesToExplore += aNbNextCmds-1;
         //for (unsigned int aBranch=0; aBranch<aNbNextCmds && !_syncInfo->_terminate; aBranch++){
         for (unsigned int aBranch=0; aBranch<aNbNextCmds && !_terminateExplore; aBranch++){
-	  std::cout << "Exploring a branch 1 from " << iPrevID << std::endl;
+	  //for (unsigned int aBranch=0; aBranch<aNbNextCmds; aBranch++){
+	  //std::cout << "1. Exploring branch #" << aBranch << " from " << iPrevID << std::endl;
           _simComp->reset();
           aStreamBuffer.str(aStringBuffer);
           //std::cout << "Read 1 in exploreTree\n";
           _simComp->readObject(aStreamBuffer);
           aRandomCmd->setRandomValue(aBranch);
           exploreTree(iDepth+1, aLastID, iAUTFile, oTransCounter);
+	  if (_terminateExplore && aBranch<aNbNextCmds-1) {
+	    //std::cout << "Terminate explore but still branches to execute ...\n";
+	  }
         }
       } else{
         unsigned int aBranch=0;
         aNbNextCmds ^= INT_MSB;
         //while (aNbNextCmds!=0 && !_syncInfo->_terminate){
-        while (aNbNextCmds!=0 && !_terminateExplore){
-	  std::cout << "Exploring a branch 2 from " << iPrevID << std::endl;
+	while (aNbNextCmds!=0 && !_terminateExplore){
+	  //while (aNbNextCmds!=0){
+	  //std::cout << "2. Exploring branch #" << aNbNextCmds << " from " << iPrevID << std::endl;
           if ((aNbNextCmds & 1)!=0){
+	    //_nbOfBranchesToExplore += 1;
             _simComp->reset();
             aStreamBuffer.str(aStringBuffer);
             //std::cout << "Read 2 in exploreTree\n";
diff --git a/simulators/c++2/src_simulator/sim/Simulator.h b/simulators/c++2/src_simulator/sim/Simulator.h
index 5dace36811..88650f9766 100644
--- a/simulators/c++2/src_simulator/sim/Simulator.h
+++ b/simulators/c++2/src_simulator/sim/Simulator.h
@@ -363,6 +363,9 @@ protected:
 	bool _terminateExplore;
 	///Duration of Simulation
 	long _simDuration;
+	//branch coverage in exploration
+	long _nbOfBranchesToExplore;
+	long _nbOfBranchesExplored;
 	std::string _end;
 };
 #endif
-- 
GitLab