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:
@ -5,6 +5,7 @@
|
||||
#include "BochsRegister.hpp"
|
||||
#include "../Register.hpp"
|
||||
#include "../SALInst.hpp"
|
||||
#include "../Listener.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
51
src/core/sal/bochs/BochsListener.ah
Normal file
51
src/core/sal/bochs/BochsListener.ah
Normal 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__
|
||||
@ -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
|
||||
@ -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__
|
||||
Reference in New Issue
Block a user