Skip to content
Snippets Groups Projects
Commit 4de80a1b authored by Daniel Knorreck's avatar Daniel Knorreck
Browse files

extended listener functionality (task start, task end, command start,...)

parent 6559cd0b
No related branches found
No related tags found
No related merge requests found
Showing
with 296 additions and 36 deletions
/*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.
*
*/
#ifndef ChannelListenerH
#define ChannelListenerH
#define NOTIFY_WRITE_TRANS_EXECUTED(iTrans) for(std::list<ChannelListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) {(*i)->transExecuted(iTrans);(*i)->writeTrans(iTrans);}
#define NOTIFY_READ_TRANS_EXECUTED(iTrans) for(std::list<ChannelListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) {(*i)->transExecuted(iTrans);(*i)->readTrans(iTrans);}
///Encapsulates events associated with commands
class ChannelListener{
public:
///Gets called when a transaction is executed
/**
\param iTrans Pointer to the transaction
\return true if simulation is stopped
*/
virtual bool transExecuted(TMLTransaction* iTrans){return false;}
///Gets called when a read transaction is executed
/**
\param iTrans Pointer to the transaction
\return true if simulation is stopped
*/
virtual bool readTrans(TMLTransaction* iTrans){return false;}
///Gets called when a write transaction is executed
/**
\param iTrans Pointer to the transaction
\return true if simulation is stopped
*/
virtual bool writeTrans(TMLTransaction* iTrans){return false;}
virtual ~ChannelListener(){}
protected:
};
#endif
......@@ -40,10 +40,11 @@ Ludovic Apvrille, Renaud Pacalet
#ifndef CommandListenerH
#define CommandListenerH
//#define FOR_EACH_CMDLISTENER for(std::list<CommandListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i)
#define NOTIFY_CMD_ENTERED(iComm) for(std::list<CommandListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->commandEntered(iComm)
#define NOTIFY_CMD_EXECUTED(iComm) for(std::list<CommandListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->commandExecuted(iComm)
#define NOTIFY_CMD_FINISHED(iComm) for(std::list<CommandListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->commandFinished(iComm)
#define NOTIFY_CMD_STARTED(iComm) for(std::list<CommandListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->commandStarted(iComm)
///Encapsulates events associated with commands
class CommandListener{
......@@ -66,6 +67,12 @@ public:
\return true if simulation is stopped
*/
virtual bool commandFinished(TMLCommand* iComm){return false;}
///Gets called when a the first transaction of the command is executed
/**
\param iComm Pointer to the command
\return true if simulation is stopped
*/
virtual bool commandStarted(TMLCommand* iComm){return false;}
///Destructor
virtual ~CommandListener(){}
protected:
......
......@@ -298,6 +298,54 @@ bool RunTillTransOnTask::transExecuted(TMLTransaction* iTrans){
}
//************************************************************************
RunTillTransOnChannel::RunTillTransOnChannel(SimComponents* iSimComp, ListenerSubject<ChannelListener>* iSubject):_simComp(iSimComp), _subject(iSubject) {
_subject->registerListener(this);
}
RunTillTransOnChannel::~RunTillTransOnChannel(){
_subject->removeListener(this);
}
bool RunTillTransOnChannel::transExecuted(TMLTransaction* iTrans){
//_simComp->setStopFlag(true);
_simComp->setStopFlag(true, MSG_TRANSONDEVICE);
return true;
}
//************************************************************************
TestListener::TestListener(SimComponents* iSimComp):_simComp(iSimComp){
}
bool TestListener::taskStarted(TMLTransaction* iTrans){
std::cout << "Task started\n";
}
bool TestListener::taskFinished(TMLTransaction* iTrans){
std::cout << "Task finished\n";
}
bool TestListener::readTrans(TMLTransaction* iTrans){
std::cout << "readTrans\n";
}
bool TestListener::writeTrans(TMLTransaction* iTrans){
std::cout << "write Trans\n";
}
bool TestListener::commandFinished(TMLCommand* iComm){
std::cout << "command started\n";
}
bool TestListener::commandStarted(TMLCommand* iComm){
std::cout << "command finished\n";
}
TestListener::~TestListener(){
}
//************************************************************************
ConstraintBlock::ConstraintBlock(SimComponents* iSimComp):_simComp(iSimComp){
}
......
......@@ -283,6 +283,50 @@ protected:
};
//************************************************************************
///Listener which stops the simulation as soon data is conveyed on a given channel
class RunTillTransOnChannel: public ChannelListener{
public:
///Constructor
/**
\param iSimComp Pointer to a SimComponents object
\param iSubject Channel to listen on
*/
RunTillTransOnChannel(SimComponents* iSimComp, ListenerSubject<ChannelListener>* iSubject);
///Destructor
virtual ~RunTillTransOnChannel();
bool transExecuted(TMLTransaction* iTrans);
protected:
///Pointer to a SimComponents object
SimComponents* _simComp;
///Channel to listen on
ListenerSubject <ChannelListener> * _subject;
};
//************************************************************************
class TestListener: public TaskListener, public ChannelListener, public CommandListener{
public:
///Constructor
/**
\param iSimComp Pointer to a SimComponents object
*/
TestListener(SimComponents* iSimComp);
bool taskStarted(TMLTransaction* iTrans);
bool taskFinished(TMLTransaction* iTrans);
bool readTrans(TMLTransaction* iTrans);
bool writeTrans(TMLTransaction* iTrans);
bool commandFinished(TMLCommand* iComm);
bool commandStarted(TMLCommand* iComm);
///Destructor
virtual ~TestListener();
protected:
///Pointer to a SimComponents object
SimComponents* _simComp;
};
//************************************************************************
class ConstraintBlock: public TransactionListener{
ConstraintBlock(SimComponents* iSimComp);
......
......@@ -42,12 +42,6 @@ Ludovic Apvrille, Renaud Pacalet
#include <Server.h>
#include <ServerLocal.h>
#include <TMLSelectCommand.h>
//#include <BusAbstr.h>
//#include <CPUAbstr.h>
//#include <ChannelAbstr.h>
//#include <TaskAbstr.h>
//#include <CommandAbstr.h>
//#include <TransactionAbstr.h>
Simulator::Simulator(SimServSyncInfo* iSyncInfo):_syncInfo(iSyncInfo), _simComp(iSyncInfo->_simComponents), _busy(false), _simTerm(false), _leafsID(0), _randChoiceBreak(iSyncInfo->_simComponents) {}
......@@ -974,7 +968,16 @@ void Simulator::printVariablesOfTask(TMLTask* iTask, std::ostream& ioMessage){
}
bool Simulator::runToNextBreakpoint(TMLTransaction*& oLastTrans){
return simulate(oLastTrans);
//TestListener myListener(_simComp);
//_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->registerListener(&myListener);
//_simComp->getChannelByName("DIPLODOCUSDesign__evt")->registerListener(&myListener);
//_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->getCommandByID(17)->registerListener(&myListener);
//bool erg=simulate(oLastTrans);
return simulate(oLastTrans);
//_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->removeListener(&myListener);
//_simComp->getChannelByName("DIPLODOCUSDesign__evt")->removeListener(&myListener);
//_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->getCommandByID(17)->removeListener(&myListener);
//return erg;
}
bool Simulator::runXTransactions(unsigned int iTrans, TMLTransaction*& oLastTrans){
......@@ -1022,8 +1025,8 @@ bool Simulator::runToSlaveTrans(Slave* iSlave, TMLTransaction*& oLastTrans){
}
bool Simulator::runToChannelTrans(TMLChannel* iChannel, TMLTransaction*& oLastTrans){
ListenerSubject<TransactionListener>* aSubject= static_cast<ListenerSubject<TransactionListener>* > (iChannel);
RunTillTransOnDevice aListener(_simComp, aSubject);
ListenerSubject<ChannelListener>* aSubject= static_cast<ListenerSubject<ChannelListener>* > (iChannel);
RunTillTransOnChannel aListener(_simComp, aSubject);
return simulate(oLastTrans);
}
......
......@@ -46,7 +46,7 @@ Ludovic Apvrille, Renaud Pacalet
#include <Slave.h>
#include <Serializable.h>
#include <ListenerSubject.h>
#include <TransactionListener.h>
#include <ChannelListener.h>
class TMLTransaction;
class TMLCommand;
......@@ -54,7 +54,7 @@ class TMLTask;
class Bus;
///This class defines the basic interfaces and functionalites of a TML channel. All specific channels are derived from this base class. A channel is able to convey data and events.
class TMLChannel: public Serializable, public ListenerSubject <TransactionListener> {
class TMLChannel: public Serializable, public ListenerSubject <ChannelListener> {
public:
///Constructor
/**
......
......@@ -53,7 +53,7 @@ Ludovic Apvrille, Renaud Pacalet
std::list<TMLCommand*> TMLCommand::_instanceList;
SimComponents* TMLCommand::_simComp=0;
TMLCommand::TMLCommand(unsigned int iID, TMLTask* iTask, TMLLength iLength, ParamFuncPointer iParamFunc, unsigned int iNbOfNextCmds): _ID(iID), _length(iLength), _progress(0), _currTransaction(0), _task(iTask), _nextCommand(0), _paramFunc(iParamFunc), _nbOfNextCmds(iNbOfNextCmds), _breakpoint(0){
TMLCommand::TMLCommand(unsigned int iID, TMLTask* iTask, TMLLength iLength, ParamFuncPointer iParamFunc, unsigned int iNbOfNextCmds): _ID(iID), _length(iLength), _progress(0), _currTransaction(0), _task(iTask), _nextCommand(0), _paramFunc(iParamFunc), _nbOfNextCmds(iNbOfNextCmds), _breakpoint(0), _justStarted(true){
_instanceList.push_back(this);
_task->addCommand(iID, this);
}
......@@ -72,8 +72,8 @@ TMLCommand* TMLCommand::prepare(bool iInit){
if(_length==_progress){
TMLCommand* aNextCommand;
//std::cout << "COMMAND FINISHED!!n";
//FOR_EACH_CMDLISTENER (*i)->commandFinished(this);
NOTIFY_CMD_FINISHED(this);
if (_justStarted) NOTIFY_CMD_STARTED(this);
_progress=0;
//std::cout << "Prepare command, get next command" << std::endl;
aNextCommand=getNextCommand();
......@@ -87,33 +87,29 @@ TMLCommand* TMLCommand::prepare(bool iInit){
}
}else{
//std::cout << "Prepare next transaction beg " << _listeners.size() << std::endl;
//_simStopped=false;
if (iInit){
//_simStopped=false;
if (_currTransaction!=0) delete _currTransaction;
if (_progress==0) _justStarted=true;
}else{
//_simStopped=false;
if (_progress==0)
//FOR_EACH_CMDLISTENER _simStopped|= (*i)->commandEntered(this);
//FOR_EACH_CMDLISTENER (*i)->commandEntered(this);
if (_progress==0){
NOTIFY_CMD_ENTERED(this);
else
//FOR_EACH_CMDLISTENER _simStopped|= (*i)->commandExecuted(this);
//FOR_EACH_CMDLISTENER (*i)->commandExecuted(this);
_justStarted=true;
}else{
NOTIFY_CMD_EXECUTED(this);
if (_justStarted){
NOTIFY_CMD_STARTED(this);
_justStarted=false;
}
}
//std::cout << "Prepare next transaction" << std::endl;
//if (_simStopped){
//if (_simComp->getStopFlag()){
// std::cout << "aSimStopped=true " << std::endl;
// _task->setCurrCommand(this);
// return this; //for command which generates transactions this is returned anyway by prepareTransaction
//}
}
TMLCommand* result = prepareNextTransaction();
//if (_length==0) std::cout << "create trans with length 0: " << toString() << std::endl;
#ifdef REGISTER_TRANS_AT_CPU
if (_currTransaction!=0 && _currTransaction->getVirtualLength()!=0){
_task->getCPU()->registerTransaction(_currTransaction,0);
}
#endif
return result;
}
return 0;
......
......@@ -199,8 +199,10 @@ protected:
unsigned int _nbOfNextCmds;
///Breakpoint
CommandListener* _breakpoint;
///Indicates if the breakpoint of the command has stopped the simulation
bool _simStopped;
/////Indicates if the breakpoint of the command has stopped the simulation
//bool _simStopped;
///Is true until the first transaction of a task is executed
bool _justStarted;
///Determines the next command based on the _nextCommand array
/**
\return Pointer to the next command
......
......@@ -48,6 +48,7 @@ void TMLStopCommand::execute(){
}
TMLCommand* TMLStopCommand::prepareNextTransaction(){
_task->finished();
return 0;
}
......
......@@ -43,7 +43,7 @@ Ludovic Apvrille, Renaud Pacalet
#include <TMLStopCommand.h>
#include <CPU.h>
TMLTask::TMLTask(unsigned int iID, unsigned int iPriority, std::string iName, CPU* iCPU): _ID(iID), _name(iName), _priority(iPriority), _endLastTransaction(0), _currCommand(0), _firstCommand(0), _cpu(iCPU), _previousTransEndTime(0), _comment(0), _busyCycles(0), _CPUContentionDelay(0), _noCPUTransactions(0) {
TMLTask::TMLTask(unsigned int iID, unsigned int iPriority, std::string iName, CPU* iCPU): _ID(iID), _name(iName), _priority(iPriority), _endLastTransaction(0), _currCommand(0), _firstCommand(0), _cpu(iCPU), _previousTransEndTime(0), _comment(0), _busyCycles(0), _CPUContentionDelay(0), _noCPUTransactions(0), _justStarted(true) {
//_myid=++_id;
_cpu->registerTask(this);
#ifdef ADD_COMMENTS
......@@ -121,6 +121,10 @@ void TMLTask::addTransaction(TMLTransaction* iTrans){
_busyCycles+=iTrans->getOperationLength();
//FOR_EACH_TASKLISTENER (*i)->transExecuted(iTrans);
NOTIFY_TASK_TRANS_EXECUTED(iTrans);
if (_justStarted){
NOTIFY_TASK_STARTED(iTrans);
_justStarted=false;
}
if(iTrans->getChannel()==0){
_noCPUTransactions++;
_CPUContentionDelay+=iTrans->getStartTime()-iTrans->getRunnableTime();
......@@ -229,6 +233,7 @@ std::istream& TMLTask::readObject(std::istream& s){
//_currCommand->prepare();
}
//std::cout << "End Read Object TMLTask " << _name << std::endl;
_justStarted=false;
return s;
}
......@@ -251,7 +256,8 @@ void TMLTask::reset(){
_transactList.clear();
_busyCycles=0;
_CPUContentionDelay=0;
_noCPUTransactions=0;
_noCPUTransactions=0;
_justStarted=true;
}
ParamType* TMLTask::getVariableByName(std::string& iVarName ,bool& oIsId){
......@@ -286,3 +292,8 @@ VariableLookUpTableID::const_iterator TMLTask::getVariableIteratorID(bool iEnd)
VariableLookUpTableName::const_iterator TMLTask::getVariableIteratorName(bool iEnd) const{
return (iEnd)?_varLookUpName.end():_varLookUpName.begin();
}
void TMLTask::finished(){
_justStarted=true;
if (!_transactList.empty()) NOTIFY_TASK_FINISHED(_transactList.front());
}
......@@ -174,7 +174,8 @@ public:
\return Const iterator for variable table
*/
VariableLookUpTableName::const_iterator getVariableIteratorName(bool iEnd) const;
///Is called when a stop command is encountered
void finished();
protected:
///ID of the task
unsigned int _ID;
......@@ -218,6 +219,8 @@ protected:
VariableLookUpTableID _varLookUpID;
///Hash table containing commands
CommandHashTab _commandHash;
///Is true until the first transaction of a task is executed
bool _justStarted;
};
#endif
......@@ -62,7 +62,9 @@ void TMLTransaction::setRunnableTime(TMLTime iRunnableTime){
// std::cout << "ERROR: runnable time set twice\n";
//}else{
//_runnableTimeSet=true;
#ifdef REGISTER_TRANS_AT_CPU
_command->getTask()->getCPU()->registerTransaction(this,0);
#endif
//}
}
......
......@@ -61,6 +61,7 @@ void TMLWaitCommand::execute(){
TMLCommand* TMLWaitCommand::prepareNextTransaction(){
//std::cout << "wait command length: " << _length << " progress: " << _progress << std::endl;
if (_progress==0 && _channel->getRequestChannel()) _task->finished();
_currTransaction=new TMLTransaction(this, _length-_progress, _task->getEndLastTransaction(), _channel);
_channel->testRead(_currTransaction);
return this;
......
/*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.
*
*/
#ifndef TaskListenerH
#define TaksListenerH
#include <TransactionListener.h>
#define NOTIFY_TASK_TRANS_EXECUTED(iTrans) for(std::list<TaskListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->transExecuted(iTrans)
#define NOTIFY_TASK_FINISHED(iTrans) for(std::list<TaskListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->taskFinished(iTrans)
#define NOTIFY_TASK_STARTED(iTrans) for(std::list<TaskListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->taskStarted(iTrans)
///Encapsulates events associated with transactions
class TaskListener{
public:
///Gets called when a task executes its first transaction
/**
\param iTrans Pointer to the transaction
\return true if simulation is stopped
*/
virtual bool taskStarted(TMLTransaction* iTrans){return false;}
///Gets called when a task executes its last transaction
/**
\param iTrans Pointer to the transaction
\return true if simulation is stopped
*/
virtual bool taskFinished(TMLTransaction* iTrans){return false;}
///Destructor
///Gets called when a transaction is executed
/**
\param iTrans Pointer to the transaction
\return true if simulation is stopped
*/
virtual bool transExecuted(TMLTransaction* iTrans){return false;}
virtual ~TaskListener(){}
protected:
};
#endif
......@@ -42,8 +42,6 @@ Ludovic Apvrille, Renaud Pacalet
#define TransactionListenerH
//#define FOR_EACH_TRANSLISTENER for(std::list<TransactionListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i)
#define NOTIFY_TRANS_EXECUTED(iTrans) for(std::list<TransactionListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->transExecuted(iTrans)
#define NOTIFY_WRITE_TRANS_EXECUTED(iTrans) for(std::list<TransactionListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->transExecuted(iTrans)
#define NOTIFY_READ_TRANS_EXECUTED(iTrans) for(std::list<TransactionListener*>::iterator i=_listeners.begin(); i != _listeners.end(); ++i) (*i)->transExecuted(iTrans)
///Encapsulates events associated with transactions
class TransactionListener{
......
......@@ -83,6 +83,7 @@ using std::max;
#define PARAMETER_BLOCK_SIZE 1000
#define ADD_COMMENTS
#define NO_EVENTS_TO_LOAD 10
#undef REGISTER_TRANS_AT_CPU
#define PORT "3490"
#define BACKLOG 10
#define VCD_PREFIX "b"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment