Simulator specific listener are now implemented using aspects instead of an additional inheritance level

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1706 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
friemel
2012-10-02 11:42:18 +00:00
parent 4d5bab72b6
commit 7d49b6f063
20 changed files with 176 additions and 296 deletions

View File

@ -5,6 +5,7 @@
#include "BochsRegister.hpp"
#include "../Register.hpp"
#include "../SALInst.hpp"
#include "../Listener.hpp"
namespace fail {

View File

@ -8,10 +8,8 @@
#include <string.h>
#include "FailBochsGlobals.hpp"
#include "BochsListener.hpp"
#include "../SimulatorController.hpp"
#include "../Listener.hpp"
#include "bochs.h"
#include "cpu/cpu.h"

View File

@ -0,0 +1,51 @@
#ifndef __BOCHSLISTENER_AH__
#define __BOCHSLISTENER_AH__
#include "config/VariantConfig.hpp"
#include "config/FailConfig.hpp"
#if defined(BUILD_BOCHS) && defined(CONFIG_EVENT_BREAKPOINTS)
#include "bochs.h"
#include "BochsController.hpp"
aspect BochsListener
{
advice "fail::TimerListener" : slice class
{
public:
bool onAddition()
{
// Register the timer listener in the Bochs simulator:
setId(m_registerTimer(this));
if(getId() == -1)
return false; // unable to register the timer (error in Bochs' function call)
return true;
}
void onDeletion()
{
// Unregister the time listener:
m_unregisterTimer(this);
}
private:
timer_id_t m_registerTimer(TimerListener* pev)
{
assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!");
return static_cast<timer_id_t>(
bx_pc_system.register_timer(pev, BochsController::onTimerTrigger, pev->getTimeout(),
false, 1/*start immediately*/, "Fail*: BochsController"/*name*/));
}
bool m_unregisterTimer(TimerListener* pev)
{
assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!");
bx_pc_system.deactivate_timer(static_cast<unsigned>(pev->getId()));
return bx_pc_system.unregisterTimer(static_cast<unsigned>(pev->getId()));
}
};
};
#endif // BUILD_BOCHS && CONFIG_EVENT_BREAKPOINTS
#endif // __BOCHSLISTENER_AH__

View File

@ -1,36 +0,0 @@
#include "BochsListener.hpp"
#include "../SALInst.hpp"
namespace fail {
bool TimerListener::onAddition()
{
// Register the timer listener in the Bochs simulator:
setId(m_registerTimer(this));
if(getId() == -1)
return false; // unable to register the timer (error in Bochs' function call)
return true;
}
void TimerListener::onDeletion()
{
// Unregister the time listener:
m_unregisterTimer(this);
}
timer_id_t TimerListener::m_registerTimer(TimerListener* pev)
{
assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!");
return static_cast<timer_id_t>(
bx_pc_system.register_timer(pev, BochsController::onTimerTrigger, pev->getTimeout(),
false, 1/*start immediately*/, "Fail*: BochsController"/*name*/));
}
bool TimerListener::m_unregisterTimer(TimerListener* pev)
{
assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!");
bx_pc_system.deactivate_timer(static_cast<unsigned>(pev->getId()));
return bx_pc_system.unregisterTimer(static_cast<unsigned>(pev->getId()));
}
} // end-of-namespace: fail

View File

@ -1,81 +0,0 @@
#ifndef __BOCHS_LISTENER_HPP__
#define __BOCHS_LISTENER_HPP__
#include "../Listener.hpp"
namespace fail {
typedef GenericBPSingleListener BPSingleListener;
typedef GenericMemWriteListener MemWriteListener;
/**
* \class TimerListener
* Concrete TimerListener implementation of GenericTimerListener for the Bochs
* simulator backend. A (Fail)Bochs bug currently leads to the consequence that
* timers cannot be added/enabled at boot time (see BochsController.hpp for
* further details).
*/
class TimerListener : public GenericTimerListener {
private:
/**
* Registers a timer in the Bochs simulator. This timer triggers \a TimerListeners
* to inform the corresponding experiment-flow. Note that the number of timers
* (in Bochs) is limited to \c BX_MAX_TIMERS (defaults to 64 in v2.4.6).
* @param pli a pointer to the (experiment flow-) allocated TimerListener object,
* providing all required information to start the timer (e.g. the
* timeout value).
* @return The unique id of the timer recently created. This id is carried
* along with the TimerListener. On errors, -1 is returned (e.g. because
* a timer with the same id is already existing)
* @see TimerListener::getId()
*/
static timer_id_t m_registerTimer(TimerListener* pli);
/**
* Deletes a timer. No further events will be triggered by the timer.
* @param pli a pointer to the TimerListener-object to be removed
* @return \c true if the timer with \a pli->getId() has been removed
* successfully, \c false otherwise
*/
static bool m_unregisterTimer(TimerListener* pli);
public:
/**
* Creates a new timer event. This can be used to implement a timeout-
* mechanism in the experiment-flow. The timer starts automatically when
* added to FailBochs.
* @param timeout the time intervall in milliseconds (ms)
* @see SimulatorController::addListener
*/
TimerListener(unsigned timeout)
: GenericTimerListener(timeout) { }
~TimerListener() { onDeletion(); } // FIXME ~BaseListener should automatically dequeue a Listener, and then indirectly calls onDeletion. In the current implementation, no dequeueing happens at all.
/**
* This method is called when an experiment flow adds a new event by
* calling \c simulator.addListener() or \c simulator.addListenerAndResume().
* More specifically, the event will be added to the event-list first
* (buffer-list, to be precise) and then this event handler is called.
* @return You should return \c true to continue and \c false to prevent
* the addition of the event \a pev, yielding an error in the
* experiment flow (i.e. -1 is returned).
*/
bool onAddition();
/**
* This method is called when an experiment flow removes an event from
* the event-management by calling \c removeListener(prev), \c clearListeners()
* or by deleting a complete flow (\c removeFlow). More specifically, this
* event handler will be called *before* the event is actually deleted.
*/
void onDeletion();
/**
* This method is called when an previously added event is about to be
* triggered by the simulator-backend. More specifically, this event handler
* will be called *before* the event is actually triggered, i.e. before the
* corresponding coroutine is toggled.
*/
void onTrigger() { onDeletion(); } // FIXME It should NOT be a Listener's job to call its own onDeletion. ListenerManager should call onDeletion when it deletes a Listener from a queue.
// TODO/FIXME: bei neuer impl. anpassen
};
} // end-of-namespace: fail
#endif // __BOCHS_LISTENER_HPP__