diff --git a/doc/class-diagram.dia b/doc/class-diagram.dia
index fa4ef15f..b0016d3e 100644
--- a/doc/class-diagram.dia
+++ b/doc/class-diagram.dia
@@ -2932,19 +2932,19 @@
-
+
-
+
-
+
-
+
#EventList#
@@ -3149,6 +3149,29 @@
+
+
+ #m_Io_cache#
+
+
+ #BufferCache<IOPortEvent*>#
+
+
+ ##
+
+
+ ##
+
+
+
+
+
+
+
+
+
+
+
@@ -3420,54 +3443,6 @@
-
-
- #makeActive#
-
-
- ##
-
-
- #void#
-
-
-
-
-
- ##
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #ev#
-
-
- #BaseEvent*#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
-
#makeActive#
@@ -3797,6 +3772,192 @@
+
+
+ #getBPBuffer#
+
+
+ ##
+
+
+ #BufferCache<BPEvent*>&#
+
+
+
+
+
+ ##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #getIOBuffer#
+
+
+ ##
+
+
+ #BufferCache<IOPortEvent*>&#
+
+
+
+
+
+ ##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #addToCaches#
+
+
+ ##
+
+
+ #void#
+
+
+
+
+
+ ##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #ev#
+
+
+ #BaseEvent*#
+
+
+ ##
+
+
+ ##
+
+
+
+
+
+
+
+
+
+ #removeFromCaches#
+
+
+ ##
+
+
+ #void#
+
+
+
+
+
+ ##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #ev#
+
+
+ #BaseEvent*#
+
+
+ ##
+
+
+ ##
+
+
+
+
+
+
+
+
+
+ #clearCaches#
+
+
+ ##
+
+
+ #void#
+
+
+
+
+
+ ##
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4374,17 +4535,17 @@
-
+
-
+
-
-
+
+
@@ -17451,19 +17612,19 @@
-
+
-
+
-
+
-
+
-
+
#BufferCache#
@@ -17558,30 +17719,7 @@
#m_Buffer#
- #T**#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
-
-
-
-
-
-
-
- #m_BufferCount#
-
-
- #int#
+ #std::list<T>#
##
@@ -17601,102 +17739,6 @@
-
-
- #setCount#
-
-
- ##
-
-
- #void#
-
-
-
-
-
- ##
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #new_count#
-
-
- #int#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
-
-
-
- #reallocate_buffer#
-
-
- ##
-
-
- #int#
-
-
-
-
-
- ##
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #new_size#
-
-
- #int#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
-
#add#
@@ -17731,7 +17773,7 @@
#val#
- #T#
+ #const T&#
##
@@ -17779,7 +17821,7 @@
#val#
- #T#
+ #const T&#
##
@@ -17801,7 +17843,7 @@
##
- #int#
+ #iterator#
@@ -17827,7 +17869,7 @@
#idx#
- #int#
+ #iterator#
##
@@ -17873,61 +17915,13 @@
- #get#
+ #begin#
##
- #T#
-
-
-
-
-
- ##
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #idx#
-
-
- #int#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
-
-
-
- #set#
-
-
- ##
-
-
- #void#
+ #iterator#
@@ -17947,52 +17941,17 @@
-
-
-
- #idx#
-
-
- #int#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
-
- #val#
-
-
- #T#
-
-
- ##
-
-
- ##
-
-
-
-
-
-
+
- #getCount#
+ #end#
##
- #int#
+ #iterator#
@@ -18007,7 +17966,7 @@
-
+
@@ -18022,7 +17981,7 @@
##
- #int#
+ #iterator#
@@ -18065,7 +18024,7 @@
#idx#
- #int#
+ #iterator#
##
@@ -18132,19 +18091,19 @@
-
+
-
+
-
+
-
-
+
+
@@ -18161,8 +18120,8 @@
-
-
+
+
diff --git a/doc/class-diagram.png b/doc/class-diagram.png
index e45b916f..9c61864b 100644
Binary files a/doc/class-diagram.png and b/doc/class-diagram.png differ
diff --git a/src/core/sal/BufferCache.cc b/src/core/sal/BufferCache.cc
index 8987ef49..de8a94f4 100644
--- a/src/core/sal/BufferCache.cc
+++ b/src/core/sal/BufferCache.cc
@@ -7,87 +7,11 @@
namespace fail {
template
-void BufferCache::add(T val)
+typename BufferCache::iterator BufferCache::makeActive(EventList &ev_list, BufferCache::iterator idx)
{
- int new_size = getCount() + 1;
- int new_last_index = getCount();
-
- int res = reallocate_buffer(new_size);
- assert (res == 0 && "FATAL ERROR: Could not add event to cache");
-
- set(new_last_index, val);
-}
-
-template
-void BufferCache::remove(T val)
-{
- bool do_remove = false;
- for (int i = 0; i < getCount(); i++) {
- if (get(i) == val) {
- do_remove = true;
- }
- if (do_remove) {
- if (i > getCount() - 1) {
- set(i, get(i + 1));
- }
- }
- }
-
- if (do_remove) {
- int new_size = getCount() - 1;
- int res = reallocate_buffer(new_size);
- assert (res == 0 && "FATAL ERROR: Could not remove event from cache");
- }
-}
-
-template
-void BufferCache::clear()
-{
- setCount(0);
- free(m_Buffer);
- m_Buffer = NULL;
-}
-
-template
-int BufferCache::erase(int idx)
-{
- if(idx < 0 || idx >= getCount())
- return -2;
-
- for (int i = idx; i < getCount() - 1; i++) {
- set(i, get(i + 1));
- }
-
- int new_size = getCount() - 1;
- if (reallocate_buffer(new_size) != 0)
- return -1;
- return idx;
-}
-
-template
-int BufferCache::reallocate_buffer(int new_size)
-{
- if (new_size < 0)
- return 20;
-
- if (new_size == 0) {
- clear();
- return 0;
- }
- void *new_buffer = realloc(m_Buffer, new_size * sizeof(T));
- if (new_buffer == NULL)
- return 10;
- m_Buffer = static_cast(new_buffer);
- setCount(new_size);
- return 0;
-}
-
-template
-int BufferCache::makeActive(EventList &ev_list, int idx)
-{
- assert(idx < getCount() &&
+ assert(idx != end() &&
"FATAL ERROR: Index larger than cache!");
- T ev = get(idx);
+ T ev = *idx;
assert(ev && "FATAL ERROR: Object pointer cannot be NULL!");
ev->decreaseCounter();
if (ev->getCounter() > 0) {
@@ -102,7 +26,8 @@ int BufferCache::makeActive(EventList &ev_list, int idx)
return erase(idx);
}
-// Declare whatever instances of the template you are going to use here:
+// Declare here whatever instances of the template you are going to use:
template class BufferCache;
+template class BufferCache;
} // end-of-namespace: fail
diff --git a/src/core/sal/BufferCache.hpp b/src/core/sal/BufferCache.hpp
index 4c26c837..f87ca61c 100644
--- a/src/core/sal/BufferCache.hpp
+++ b/src/core/sal/BufferCache.hpp
@@ -2,6 +2,7 @@
#define __BUFFER_CACHE_HPP__
#include
+#include
namespace fail {
@@ -12,74 +13,71 @@ class EventList;
*
* \brief A simple dynamic array
*
- * This class is intended to serve as a kind of cache for the entirely STL-based,
+ * This class is intended to serve as a kind of cache for the
* untyped and therefore quite slow event handling mechanism of Fail*.
- * To keep the code easily readable, some buffer management methods
- * perform suboptimally (remove() and erase() have linear complexity).
- *
- * FIXME: Why not using std::vector? ("A simple dynamic array")
*/
template
class BufferCache {
-private:
- // TODO: comments ("//!<") needed!
- T *m_Buffer;
- int m_BufferCount;
- /**
- * Changes m_BufferCount. Should be inlined.
- * @param new_count the new array length
- */
- inline void setCount(int new_count) { if(new_count >= 0) m_BufferCount = new_count; }
-protected:
- /**
- * Reallocates the buffer. This implementation is extremely primitive,
- * but since the amount of entries is small,
- * this will not be significant, hopefully. Should be inlined.
- * @param new_size the new number of elements in the array
- * @return 0 if successful, an error code otherwise (10 if realloc() fails, 20 for an invalid new size)
- */
- inline int reallocate_buffer(int new_size);
public:
- BufferCache()
- : m_Buffer(NULL), m_BufferCount(0) {}
+ /**
+ * The list type inherent to this class. Like bufferlist_t in EventList.hpp,
+ * but dynamically typed.
+ */
+ typedef std::list cachelist_t;
+ /**
+ * The iterator of this class used to loop through the list of
+ * added events. To retrieve an iterator to the first element, call
+ * begin(). end() returns the iterator, pointing after the last element.
+ * (This behaviour equals the STL iterator in C++.)
+ */
+ typedef typename cachelist_t::iterator iterator;
+private:
+ cachelist_t m_Buffer; //!< The list holding the cached elements
+public:
+ BufferCache() {}
~BufferCache() {}
/**
* Add an element to the array. The object pointed to remains untouched.
* @param val the element to add
*/
- void add(T val);
+ inline void add(const T &val) { m_Buffer.push_back(val); }
/**
* Remove an element from the array. The object pointed to remains untouched.
* @param val the element to remove
*/
- void remove(T val);
+ inline void remove(const T &val) { m_Buffer.remove(val); }
/**
* Remove an element at a specific position. The object pointed to remains untouched.
* @param val the element to remove
* @return a pointer to the given element's successor if successful, a negative value otherwise
*/
- int erase(int i);
+ inline iterator erase(iterator i) { return m_Buffer.erase(i); }
/**
* Clears the array, removing all elements. The objects pointed to remain untouched.
*/
- void clear();
+ inline void clear() { m_Buffer.clear(); }
/**
- * Retrieve an element from the array. Should be inlined.
- * @param idx the position to retrieve the element from
- * @return the element at the given position
+ * Returns an iterator to the beginning of the internal data structure.
+ * Don't forget to update the returned iterator when calling one of the
+ * modifying methods like makeActive() or remove(). Therefore you need
+ * to call the iterator-based variants of makeActive() and remove().
+ * \code
+ * [X|1|2| ... |n]
+ * ^
+ * \endcode
*/
- inline T get(int idx) const { return (idx >= 0 && idx < getCount() ? m_Buffer[idx] : NULL); }
+ inline iterator begin() { return m_Buffer.begin(); }
/**
- * Set an element at a given position. Should be inlined.
- * @param idx the position to change an element at
- * @param val the new value of the given element
+ * Returns an iterator to the end of the interal data structure.
+ * Don't forget to update the returned iterator when calling one of the
+ * modifying methods like makeActive() or remove(). Therefore you need
+ * to call the iterator-based variants of makeActive() and remove().
+ * \code
+ * [1|2| ... |n]X
+ * ^
+ * \endcode
*/
- inline void set(int idx, T val) { if(idx >= 0 && idx < getCount()) m_Buffer[idx] = val; }
- /**
- * Retrieves the current length of the array. Should be inlined.
- * @return the array length
- */
- inline int getCount() const { return m_BufferCount; }
+ inline iterator end() { return m_Buffer.end(); }
/**
* Acts as a replacement for EventList::makeActive, manipulating
* the buffer cache exclusively. EventList::fireActiveEvents needs
@@ -88,7 +86,7 @@ public:
* @param idx the index of the event to trigger
* @returns an updated index which can be used to update a loop counter
*/
- int makeActive(EventList &ev_list, int idx);
+ iterator makeActive(EventList &ev_list, iterator idx);
};
} // end-of-namespace: fail
diff --git a/src/core/sal/EventList.cc b/src/core/sal/EventList.cc
index 571a262c..cf6b73cc 100644
--- a/src/core/sal/EventList.cc
+++ b/src/core/sal/EventList.cc
@@ -4,7 +4,34 @@
#include "SALInst.hpp"
namespace fail {
-
+
+void EventList::addToCaches(BaseEvent *ev)
+{
+ BPEvent *bps_ev;
+ if((bps_ev = dynamic_cast(ev)) != NULL)
+ m_Bp_cache.add(bps_ev);
+
+ IOPortEvent *io_ev;
+ if((io_ev = dynamic_cast(ev)) != NULL)
+ m_Io_cache.add(io_ev);
+}
+
+void EventList::removeFromCaches(BaseEvent *ev)
+{
+ BPEvent *bpr_ev;
+ if((bpr_ev = dynamic_cast(ev)) != NULL)
+ m_Bp_cache.remove(bpr_ev);
+
+ IOPortEvent *io_ev;
+ if((io_ev = dynamic_cast(ev)) != NULL)
+ m_Io_cache.remove(io_ev);
+}
+
+void EventList::clearCaches() {
+ m_Bp_cache.clear();
+ m_Io_cache.clear();
+}
+
EventId EventList::add(BaseEvent* ev, ExperimentFlow* pExp)
{
assert(ev != NULL && "FATAL ERROR: Event (of base type BaseEvent*) cannot be NULL!");
@@ -12,9 +39,7 @@ EventId EventList::add(BaseEvent* ev, ExperimentFlow* pExp)
assert(ev->getCounter() != 0);
ev->setParent(pExp); // event is linked to experiment flow
- BPEvent *bp_ev;
- if((bp_ev = dynamic_cast(ev)) != NULL)
- m_Bp_cache.add(bp_ev);
+ addToCaches(ev);
m_BufferList.push_back(ev);
return (ev->getId());
}
@@ -30,7 +55,7 @@ void EventList::remove(BaseEvent* ev)
simulator.onEventDeletion(*it);
for (firelist_t::iterator it = m_FireList.begin(); it != m_FireList.end(); it++)
simulator.onEventDeletion(*it);
- m_Bp_cache.clear();
+ clearCaches();
m_BufferList.clear();
// all remaining active events must not fire anymore
m_DeleteList.insert(m_DeleteList.end(), m_FireList.begin(), m_FireList.end());
@@ -41,9 +66,7 @@ void EventList::remove(BaseEvent* ev)
} else {
simulator.onEventDeletion(ev);
- BPEvent *bp_ev;
- if((bp_ev = dynamic_cast(ev)) != NULL)
- m_Bp_cache.remove(bp_ev);
+ removeFromCaches(ev);
m_BufferList.remove(ev);
firelist_t::const_iterator it =
std::find(m_FireList.begin(), m_FireList.end(), ev);
@@ -75,9 +98,7 @@ EventList::iterator EventList::m_remove(iterator it, bool skip_deletelist)
// BufferCache::remove() from m_remove().
// NOTE: in case the semantics of skip_deletelist change, please adapt the following lines
- BPEvent *bp_ev;
- if((bp_ev = dynamic_cast(*it)) != NULL)
- m_Bp_cache.remove(bp_ev);
+ removeFromCaches((*it));
}
return (m_BufferList.erase(it));
@@ -99,7 +120,7 @@ void EventList::remove(ExperimentFlow* flow)
for (bufferlist_t::iterator it = m_BufferList.begin();
it != m_BufferList.end(); it++)
simulator.onEventDeletion(*it); // invoke event handler
- m_Bp_cache.clear();
+ clearCaches();
m_BufferList.clear();
} else { // remove all events corresponding to a specific experiment ("flow"):
for (bufferlist_t::iterator it = m_BufferList.begin();
diff --git a/src/core/sal/EventList.hpp b/src/core/sal/EventList.hpp
index 8e3c8d0f..61288131 100644
--- a/src/core/sal/EventList.hpp
+++ b/src/core/sal/EventList.hpp
@@ -30,6 +30,14 @@ typedef std::vector firelist_t;
*/
typedef std::vector deletelist_t;
+/**
+ * Cache classes for the most commonly used types of events, utilising static typing.
+ * Apart from that, they work like bufferlist_t.
+ */
+typedef BufferCache bp_cache_t;
+typedef bp_cache_t::iterator bp_iter_t;
+typedef BufferCache io_cache_t;
+typedef io_cache_t::iterator io_iter_t;
/**
* \class EventList
*
@@ -37,7 +45,7 @@ typedef std::vector deletelist_t;
*
* If a event is triggered, the internal data structure will be updated (id est,
* the event will be removed from the so called buffer-list and added to the
- * fire-list). Additionaly, if an experiment-flow deletes an "active" event
+ * fire-list). Additionally, if an experiment-flow deletes an "active" event
* which is currently stored in the fire-list, the event (to be removed) will
* be added to a -so called- delete-list. This ensures to prevent triggering
* "active" events which have already been deleted by a previous experiment
@@ -53,8 +61,10 @@ class EventList
firelist_t m_FireList; //!< the active events (used temporarily)
deletelist_t m_DeleteList; //!< the deleted events (used temporarily)
BaseEvent* m_pFired; //!< the recently fired Event-object
- BufferCache m_Bp_cache;
- friend int BufferCache::makeActive(EventList &ev_list, int idx);
+ bp_cache_t m_Bp_cache; //!< the storage cache for breakpoint events
+ io_cache_t m_Io_cache; //!< the storage cache for port i/o events
+ friend bp_iter_t bp_cache_t::makeActive(EventList &ev_list, bp_iter_t idx);
+ friend io_iter_t io_cache_t::makeActive(EventList &ev_list, io_iter_t idx);
public:
/**
* The iterator of this class used to loop through the list of
@@ -186,7 +196,27 @@ class EventList
* Retrieves the BPEvent buffer cache.
* @returns the buffer cache
*/
- inline BufferCache *getBPBuffer() { return &m_Bp_cache; }
+ inline bp_cache_t &getBPBuffer() { return m_Bp_cache; }
+ /**
+ * Retrieves the IOPortEvent buffer cache.
+ * @returns the buffer cache
+ */
+ inline io_cache_t &getIOBuffer() { return m_Io_cache; }
+ private:
+ /**
+ * Add an event to its appropriate cache.
+ * @param the event to add
+ */
+ void addToCaches(BaseEvent *ev);
+ /**
+ * Remove an event from its cache.
+ * @param the event to remove
+ */
+ void removeFromCaches(BaseEvent *ev);
+ /**
+ * Clear the event caches.
+ */
+ void clearCaches();
};
} // end-of-namespace: fail
diff --git a/src/core/sal/bochs/BochsController.cc b/src/core/sal/bochs/BochsController.cc
index e012c45a..46b6a14a 100644
--- a/src/core/sal/bochs/BochsController.cc
+++ b/src/core/sal/bochs/BochsController.cc
@@ -91,33 +91,34 @@ void BochsController::dbgEnableInstrPtrOutput(unsigned regularity, std::ostream*
void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_space)
{
-#if 0
- //the original code - performs magnitudes worse than
- //the code below and is responsible for most (~87 per cent)
- //of the slowdown of FailBochs
#ifdef DEBUG
if(m_Regularity != 0 && ++m_Counter % m_Regularity == 0)
(*m_pDest) << "0x" << std::hex << instrPtr;
#endif
+ bool do_fire = false;
// Check for active breakpoint-events:
- EventList::iterator it = m_EvList.begin();
- while(it != m_EvList.end())
+ bp_cache_t &buffer_cache = m_EvList.getBPBuffer();
+ bp_cache_t::iterator it = buffer_cache.begin();
+ while(it != buffer_cache.end())
{
- // FIXME: Maybe we need to improve the performance of this check.
- BPEvent* pEvBreakpt = dynamic_cast(*it);
- if(pEvBreakpt && pEvBreakpt->isMatching(instrPtr, address_space))
+ BPEvent* pEvBreakpt = *it;
+ if(pEvBreakpt->isMatching(instrPtr, address_space))
{
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
- it = m_EvList.makeActive(it);
+ it = buffer_cache.makeActive(m_EvList, it);
+ do_fire = true;
// "it" has already been set to the next element (by calling
// makeActive()):
continue; // -> skip iterator increment
}
it++;
}
- m_EvList.fireActiveEvents();
-#endif
- //this code is highly optimised for the average case, so it me appear a bit ugly
+ if(do_fire)
+ m_EvList.fireActiveEvents();
+ // Note: SimulatorController::onBreakpointEvent will not be invoked in this
+ // implementation.
+#if 0
+ //deprecated - this code is ugly
bool do_fire = false;
int i = 0;
BufferCache *buffer_cache = m_EvList.getBPBuffer();
@@ -140,21 +141,20 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
}
if(do_fire)
m_EvList.fireActiveEvents();
- // Note: SimulatorController::onBreakpointEvent will not be invoked in this
- // implementation.
+#endif
}
void BochsController::onIOPortEvent(unsigned char data, unsigned port, bool out) {
// Check for active breakpoint-events:
- EventList::iterator it = m_EvList.begin();
- while(it != m_EvList.end())
+ io_cache_t &buffer_cache = m_EvList.getIOBuffer();
+ io_cache_t::iterator it = buffer_cache.begin();
+ while(it != buffer_cache.end())
{
- // FIXME: Maybe we need to improve the performance of this check.
- IOPortEvent* pIOPt = dynamic_cast(*it);
- if(pIOPt && pIOPt->isMatching(port, out))
+ IOPortEvent* pIOPt = (*it);
+ if(pIOPt->isMatching(port, out))
{
pIOPt->setData(data);
- it = m_EvList.makeActive(it);
+ it = buffer_cache.makeActive(m_EvList, it);
// "it" has already been set to the next element (by calling
// makeActive()):
continue; // -> skip iterator increment
diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc
index 89e31df8..620b30fa 100644
--- a/src/experiments/l4-sys/experiment.cc
+++ b/src/experiments/l4-sys/experiment.cc
@@ -49,7 +49,7 @@ istream& operator>>(istream& in, trace_instr &val) {
return in;
}
-char const * const state_folder = "l4sys.state";
+char const * const state_folder = "l4sys.state";
char const * const instr_list_fn = "ip.list";
char const * const golden_run_fn = "golden.out";
address_t const aspace = 0x01e00000;
@@ -59,8 +59,7 @@ string golden_run;
//the program needs to run 5 times without a fault
const unsigned times_run = 5;
-string L4SysExperiment::sanitised(string in_str)
-{
+string L4SysExperiment::sanitised(string in_str) {
string result;
result.reserve(in_str.size());
for (string::iterator it = in_str.begin(); it != in_str.end(); it++) {
@@ -76,8 +75,7 @@ string L4SysExperiment::sanitised(string in_str)
return result;
}
-BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output)
-{
+BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output) {
IOPortEvent ev_ioport(0x3F8, true);
BaseEvent* ev = NULL;
if (clear_output)
@@ -95,8 +93,7 @@ BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output)
return ev;
}
-bool L4SysExperiment::run()
-{
+bool L4SysExperiment::run() {
Logger log("L4Sys", false);
BPSingleEvent bp(0, aspace);
@@ -109,8 +106,7 @@ bool L4SysExperiment::run()
simulator.addEventAndWait(&bp);
log << "test function entry reached, saving state" << endl;
- log << "EIP = " << hex << bp.getTriggerInstructionPointer()
- << " or "
+ log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
simulator.save(state_folder);
@@ -213,7 +209,7 @@ bool L4SysExperiment::run()
}
// STEP 4: The actual experiment.
- for (int i = 0; i < L4SYS_NUMINSTR; i++) {
+ while (1) {
log << "restoring state" << endl;
simulator.restore(state_folder);
@@ -247,9 +243,8 @@ bool L4SysExperiment::run()
simulator.getRegisterManager().getInstructionPointer();
param.msg.set_injection_ip(injection_ip);
log << "inject @ ip " << injection_ip << " (offset " << dec
- << instr_offset << ")" << " bit " << bit_offset << ": 0x"
- << hex << ((int) data) << " -> 0x" << ((int) newdata)
- << endl;
+ << instr_offset << ")" << " bit " << bit_offset << ": 0x" << hex
+ << ((int) data) << " -> 0x" << ((int) newdata) << endl;
// sanity check (only works if we're working with an instruction trace)
if (injection_ip != instr_list[instr_offset].trigger_addr) {
@@ -263,7 +258,7 @@ bool L4SysExperiment::run()
simulator.clearEvents();
m_jc.sendResult(param);
- continue;
+ simulator.terminate(20);
}
// aftermath
@@ -305,8 +300,7 @@ bool L4SysExperiment::run()
simulator.getRegisterManager().getInstructionPointer());
param.msg.set_output(sanitised(output.c_str()));
} else if (ev == &ev_trap) {
- log << dec << "Result TRAP #" << ev_trap.getTriggerNumber()
- << endl;
+ log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
param.msg.set_resulttype(param.msg.TRAP);
param.msg.set_resultdata(
simulator.getRegisterManager().getInstructionPointer());
@@ -339,6 +333,7 @@ bool L4SysExperiment::run()
#ifdef HEADLESS_EXPERIMENT
simulator.terminate(0);
#endif
-// experiment successfully conducted
+
+ // experiment successfully conducted
return true;
}
diff --git a/src/experiments/l4-sys/experimentInfo.hpp b/src/experiments/l4-sys/experimentInfo.hpp
index 266a22b3..56f75737 100644
--- a/src/experiments/l4-sys/experimentInfo.hpp
+++ b/src/experiments/l4-sys/experimentInfo.hpp
@@ -1,12 +1,15 @@
#ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__
-// FIXME autogenerate this
+//experiment types:
+#define GPRFLIP 10
+#define IDCFLIP 20
#define L4SYS_FUNC_ENTRY 0x1007cd0
#define L4SYS_FUNC_EXIT 0x1007d3a
#define L4SYS_NUMINSTR 3184
-//#define HEADLESS_EXPERIMENT
-#define PREPARE_EXPERIMENT
+#define HEADLESS_EXPERIMENT
+#define EXPERIMENT_TYPE IDCFLIP
+//#define PREPARE_EXPERIMENT
#endif // __EXPERIMENT_INFO_HPP__