Introducing the BufferCache announced on the mailing list, and some small changes. L4Sys is still WIP.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1316 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -92,10 +92,14 @@ void BochsController::dbgEnableInstrPtrOutput(unsigned regularity, std::ostream*
|
|||||||
|
|
||||||
void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_space)
|
void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_space)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#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)
|
if(m_Regularity != 0 && ++m_Counter % m_Regularity == 0)
|
||||||
(*m_pDest) << "0x" << std::hex << instrPtr;
|
(*m_pDest) << "0x" << std::hex << instrPtr;
|
||||||
#endif
|
#endif
|
||||||
// Check for active breakpoint-events:
|
// Check for active breakpoint-events:
|
||||||
fi::EventList::iterator it = m_EvList.begin();
|
fi::EventList::iterator it = m_EvList.begin();
|
||||||
while(it != m_EvList.end())
|
while(it != m_EvList.end())
|
||||||
@ -113,6 +117,37 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
|||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
m_EvList.fireActiveEvents();
|
m_EvList.fireActiveEvents();
|
||||||
|
#endif
|
||||||
|
//this code is highly optimised for the average case, so it me appear a bit ugly
|
||||||
|
bool do_fire = false;
|
||||||
|
unsigned i = 0;
|
||||||
|
fi::BufferCache<fi::BPEvent*> *buffer_cache = m_EvList.getBPBuffer();
|
||||||
|
while(i < buffer_cache->get_count()) {
|
||||||
|
fi::BPEvent *pEvBreakpt = buffer_cache->get(i);
|
||||||
|
if(pEvBreakpt->isMatching(instrPtr, address_space)) {
|
||||||
|
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||||
|
|
||||||
|
//transition to STL: find the element we are working on in the Event List
|
||||||
|
fi::EventList::iterator it = std::find(m_EvList.begin(), m_EvList.end(), pEvBreakpt);
|
||||||
|
it = m_EvList.makeActive(it);
|
||||||
|
//find out how much elements need to be skipped to get in sync again
|
||||||
|
//(should be one or none, the loop is just to make sure)
|
||||||
|
for(unsigned j = i; j < buffer_cache->get_count(); j++) {
|
||||||
|
if(buffer_cache->get(j) == (*it)) {
|
||||||
|
i = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we now know we need to fire the active events - usually we do not have to
|
||||||
|
do_fire = true;
|
||||||
|
// "i" has already been set to the next element (by calling
|
||||||
|
// makeActive()):
|
||||||
|
continue; // -> skip loop increment
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(do_fire)
|
||||||
|
m_EvList.fireActiveEvents();
|
||||||
// Note: SimulatorController::onBreakpointEvent will not be invoked in this
|
// Note: SimulatorController::onBreakpointEvent will not be invoked in this
|
||||||
// implementation.
|
// implementation.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
aspect IOPortCom
|
aspect IOPortCom
|
||||||
{
|
{
|
||||||
// ATM only capturing bytewise output (most common, I suppose)
|
// ATM only capturing bytewise output (most common, I suppose)
|
||||||
pointcut outInstruction() = "% ...::bx_cpu_c::OUT_DXAL%(...)";
|
pointcut outInstruction() = "% ...::bx_cpu_c::OUT_DXAL(...)";
|
||||||
|
|
||||||
advice execution (outInstruction()) : after ()
|
advice execution (outInstruction()) : after ()
|
||||||
{
|
{
|
||||||
@ -23,7 +23,7 @@ aspect IOPortCom
|
|||||||
sal::simulator.onIOPortEvent(rAL, rDX, true);
|
sal::simulator.onIOPortEvent(rAL, rDX, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointcut inInstruction() = "% ...::bx_cpu_c::IN_ALDX%(...)";
|
pointcut inInstruction() = "% ...::bx_cpu_c::IN_ALDX(...)";
|
||||||
|
|
||||||
advice execution (inInstruction()) : after ()
|
advice execution (inInstruction()) : after ()
|
||||||
{
|
{
|
||||||
|
|||||||
74
core/controller/BufferCache.cc
Normal file
74
core/controller/BufferCache.cc
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "BufferCache.hpp"
|
||||||
|
#include "Event.hpp"
|
||||||
|
|
||||||
|
namespace fi {
|
||||||
|
|
||||||
|
template<class T> int BufferCache<T>::add(T val) {
|
||||||
|
size_t new_size = get_count() + 1;
|
||||||
|
size_t new_last_index = get_count();
|
||||||
|
|
||||||
|
int res = reallocate_buffer(new_size);
|
||||||
|
if (res == 0) {
|
||||||
|
set(new_last_index, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> int BufferCache<T>::remove(T val) {
|
||||||
|
bool do_remove = false;
|
||||||
|
for (size_t i = 0; i < get_count(); i++) {
|
||||||
|
if (get(i) == val) {
|
||||||
|
do_remove = true;
|
||||||
|
}
|
||||||
|
if (do_remove) {
|
||||||
|
if (i > get_count() - 1) {
|
||||||
|
set(i, get(i + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
if (do_remove) {
|
||||||
|
size_t new_size = get_count() - 1;
|
||||||
|
res = reallocate_buffer(new_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void BufferCache<T>::clear() {
|
||||||
|
set_count(0);
|
||||||
|
free(m_Buffer);
|
||||||
|
m_Buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> int BufferCache<T>::erase(int idx) {
|
||||||
|
for (size_t i = idx; i < get_count() - 1; i++) {
|
||||||
|
set(i, get(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t new_size = get_count() - 1;
|
||||||
|
if (reallocate_buffer(new_size) != 0)
|
||||||
|
return -1;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> int BufferCache<T>::reallocate_buffer(size_t new_size) {
|
||||||
|
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<T*>(new_buffer);
|
||||||
|
set_count(new_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//declare whatever instances of the template
|
||||||
|
//you are going to use here:
|
||||||
|
template class BufferCache<BPEvent*>;
|
||||||
|
|
||||||
|
} /* namespace fi */
|
||||||
82
core/controller/BufferCache.hpp
Normal file
82
core/controller/BufferCache.hpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#ifndef __BUFFERCACHE_HPP__
|
||||||
|
#define __BUFFERCACHE_HPP__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace fi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class BufferCache
|
||||||
|
*
|
||||||
|
* \brief A simple dynamic array
|
||||||
|
*
|
||||||
|
* This class is intended to serve as a kind of cache for the entirely STL-based,
|
||||||
|
* untyped and therefore quite slow event handling mechanism of Fail*.
|
||||||
|
* To keep the code easily readable, the buffer management methods
|
||||||
|
* are less performant than the could be (remove() and erase() have linear complexity).
|
||||||
|
*/
|
||||||
|
template<class T> class BufferCache {
|
||||||
|
public:
|
||||||
|
BufferCache()
|
||||||
|
: m_Buffer(NULL), m_Buffer_count(0) {}
|
||||||
|
~BufferCache() {}
|
||||||
|
/**
|
||||||
|
* Add an element to the array. The object pointed to remains untouched.
|
||||||
|
* @param val the element to add
|
||||||
|
* @returns 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||||
|
*/
|
||||||
|
int add(T val);
|
||||||
|
/**
|
||||||
|
* Remove an element from the array. The object pointed to remains untouched.
|
||||||
|
* @param val the element to remove
|
||||||
|
* @returns 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||||
|
*/
|
||||||
|
int remove(T val);
|
||||||
|
/**
|
||||||
|
* Remove an element at a specific position. The object pointed to remains untouched.
|
||||||
|
* @param val the element to remove
|
||||||
|
* @returns a pointer to the given element's successor if successful, -1 otherwise
|
||||||
|
*/
|
||||||
|
int erase(int i);
|
||||||
|
/**
|
||||||
|
* Clears the array, removing all elements. The objects pointed to remain untouched.
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
/**
|
||||||
|
* Retrieve an element from the array. Should be inlined.
|
||||||
|
* @param idx the position to retrieve the element from
|
||||||
|
* @returns the element at the given position
|
||||||
|
*/
|
||||||
|
inline T get(size_t idx) { return m_Buffer[idx]; }
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
inline void set(size_t idx, T val) { m_Buffer[idx] = val; }
|
||||||
|
/**
|
||||||
|
* Retrieves the current length of the array. Should be inlined.
|
||||||
|
* @returns the array length
|
||||||
|
*/
|
||||||
|
inline size_t get_count() { return m_Buffer_count; }
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Changes the current length of the array. Should be inlined.
|
||||||
|
* @param new_count the new array length
|
||||||
|
*/
|
||||||
|
inline void set_count(size_t new_count) { m_Buffer_count = new_count; }
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* @returns 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||||
|
*/
|
||||||
|
inline int reallocate_buffer(size_t new_size);
|
||||||
|
private:
|
||||||
|
T *m_Buffer;
|
||||||
|
size_t m_Buffer_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace fi */
|
||||||
|
#endif /* BUFFERCACHE_H_ */
|
||||||
@ -1,4 +1,5 @@
|
|||||||
set(SRCS
|
set(SRCS
|
||||||
|
BufferCache.cc
|
||||||
CampaignManager.cc
|
CampaignManager.cc
|
||||||
CoroutineManager.cc
|
CoroutineManager.cc
|
||||||
Event.cc
|
Event.cc
|
||||||
|
|||||||
@ -12,6 +12,10 @@ EventId EventList::add(BaseEvent* ev, ExperimentFlow* pExp)
|
|||||||
// a zero counter does not make sense
|
// a zero counter does not make sense
|
||||||
assert(ev->getCounter() != 0);
|
assert(ev->getCounter() != 0);
|
||||||
ev->setParent(pExp); // event is linked to experiment flow
|
ev->setParent(pExp); // event is linked to experiment flow
|
||||||
|
|
||||||
|
BPEvent *bp_ev;
|
||||||
|
if((bp_ev = dynamic_cast<BPEvent*>(ev)) != NULL)
|
||||||
|
m_Bp_cache.add(bp_ev);
|
||||||
m_BufferList.push_back(ev);
|
m_BufferList.push_back(ev);
|
||||||
return (ev->getId());
|
return (ev->getId());
|
||||||
}
|
}
|
||||||
@ -27,6 +31,7 @@ void EventList::remove(BaseEvent* ev)
|
|||||||
sal::simulator.onEventDeletion(*it);
|
sal::simulator.onEventDeletion(*it);
|
||||||
for (firelist_t::iterator it = m_FireList.begin(); it != m_FireList.end(); it++)
|
for (firelist_t::iterator it = m_FireList.begin(); it != m_FireList.end(); it++)
|
||||||
sal::simulator.onEventDeletion(*it);
|
sal::simulator.onEventDeletion(*it);
|
||||||
|
m_Bp_cache.clear();
|
||||||
m_BufferList.clear();
|
m_BufferList.clear();
|
||||||
// all remaining active events must not fire anymore
|
// all remaining active events must not fire anymore
|
||||||
m_DeleteList.insert(m_DeleteList.end(), m_FireList.begin(), m_FireList.end());
|
m_DeleteList.insert(m_DeleteList.end(), m_FireList.begin(), m_FireList.end());
|
||||||
@ -36,6 +41,10 @@ void EventList::remove(BaseEvent* ev)
|
|||||||
// * if ev in m_FireList, copy to m_DeleteList
|
// * if ev in m_FireList, copy to m_DeleteList
|
||||||
} else {
|
} else {
|
||||||
sal::simulator.onEventDeletion(ev);
|
sal::simulator.onEventDeletion(ev);
|
||||||
|
|
||||||
|
BPEvent *bp_ev;
|
||||||
|
if((bp_ev = dynamic_cast<BPEvent*>(ev)) != NULL)
|
||||||
|
m_Bp_cache.remove(bp_ev);
|
||||||
m_BufferList.remove(ev);
|
m_BufferList.remove(ev);
|
||||||
firelist_t::const_iterator it =
|
firelist_t::const_iterator it =
|
||||||
std::find(m_FireList.begin(), m_FireList.end(), ev);
|
std::find(m_FireList.begin(), m_FireList.end(), ev);
|
||||||
@ -61,6 +70,10 @@ EventList::iterator EventList::m_remove(iterator it, bool skip_deletelist)
|
|||||||
sal::simulator.onEventDeletion(*it);
|
sal::simulator.onEventDeletion(*it);
|
||||||
m_DeleteList.push_back(*it);
|
m_DeleteList.push_back(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BPEvent *bp_ev;
|
||||||
|
if((bp_ev = dynamic_cast<BPEvent*>(*it)) != NULL)
|
||||||
|
m_Bp_cache.remove(bp_ev);
|
||||||
return (m_BufferList.erase(it));
|
return (m_BufferList.erase(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +93,7 @@ void EventList::remove(ExperimentFlow* flow)
|
|||||||
for (bufferlist_t::iterator it = m_BufferList.begin();
|
for (bufferlist_t::iterator it = m_BufferList.begin();
|
||||||
it != m_BufferList.end(); it++)
|
it != m_BufferList.end(); it++)
|
||||||
sal::simulator.onEventDeletion(*it); // invoke event handler
|
sal::simulator.onEventDeletion(*it); // invoke event handler
|
||||||
|
m_Bp_cache.clear();
|
||||||
m_BufferList.clear();
|
m_BufferList.clear();
|
||||||
} else { // remove all events corresponding to a specific experiment ("flow"):
|
} else { // remove all events corresponding to a specific experiment ("flow"):
|
||||||
for (bufferlist_t::iterator it = m_BufferList.begin();
|
for (bufferlist_t::iterator it = m_BufferList.begin();
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Event.hpp"
|
#include "Event.hpp"
|
||||||
|
#include "BufferCache.hpp"
|
||||||
|
|
||||||
namespace fi
|
namespace fi
|
||||||
{
|
{
|
||||||
@ -53,6 +54,7 @@ class EventList
|
|||||||
deletelist_t m_DeleteList; //!< the deleted events (used temporarily)
|
deletelist_t m_DeleteList; //!< the deleted events (used temporarily)
|
||||||
// TODO: Hashing?
|
// TODO: Hashing?
|
||||||
BaseEvent* m_pFired; //!< the recently fired Event-object
|
BaseEvent* m_pFired; //!< the recently fired Event-object
|
||||||
|
BufferCache<BPEvent*> m_Bp_cache;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The iterator of this class used to loop through the list of
|
* The iterator of this class used to loop through the list of
|
||||||
@ -180,6 +182,11 @@ class EventList
|
|||||||
* TODO: Improve naming (instead of "fireActiveEvents")?
|
* TODO: Improve naming (instead of "fireActiveEvents")?
|
||||||
*/
|
*/
|
||||||
void fireActiveEvents();
|
void fireActiveEvents();
|
||||||
|
/**
|
||||||
|
* Retrieves the BPEvent buffer cache.
|
||||||
|
* @returns the buffer cache
|
||||||
|
*/
|
||||||
|
inline BufferCache<BPEvent*> *getBPBuffer() { return &m_Bp_cache; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // end-of-namespace: fi
|
}; // end-of-namespace: fi
|
||||||
|
|||||||
@ -33,7 +33,7 @@ bool L4SysCampaign::run()
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
//iterate over one register
|
//iterate over one register
|
||||||
for (int bit_offset = 0; bit_offset < 1; ++bit_offset) {
|
for (int bit_offset = 0; bit_offset < 1; ++bit_offset) {
|
||||||
for (int instr_offset = 0; instr_offset < COOL_ECC_NUMINSTR; ++instr_offset) {
|
for (int instr_offset = 0; instr_offset < L4SYS_NUMINSTR; ++instr_offset) {
|
||||||
L4SysExperimentData *d = new L4SysExperimentData;
|
L4SysExperimentData *d = new L4SysExperimentData;
|
||||||
d->msg.set_instr_offset(instr_offset);
|
d->msg.set_instr_offset(instr_offset);
|
||||||
d->msg.set_bit_offset(bit_offset);
|
d->msg.set_bit_offset(bit_offset);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -33,7 +34,7 @@ using std::endl;
|
|||||||
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 instr_list_fn = "ip.list";
|
||||||
char const * const golden_run_fn = "golden.out";
|
char const * const golden_run_fn = "golden.out";
|
||||||
sal::address_t const aspace = 0x1fd44000;
|
sal::address_t const aspace = 0x01e00000;
|
||||||
std::string output;
|
std::string output;
|
||||||
std::vector<sal::address_t> instr_list;
|
std::vector<sal::address_t> instr_list;
|
||||||
std::string golden_run;
|
std::string golden_run;
|
||||||
@ -80,14 +81,12 @@ bool L4SysExperiment::run() {
|
|||||||
|
|
||||||
log << "startup" << endl;
|
log << "startup" << endl;
|
||||||
|
|
||||||
//FIXME: this is a race condition:
|
#ifdef PREPARE_EXPERIMENT
|
||||||
//only one L4SysExperiment instance should execute this block
|
|
||||||
//at a time
|
|
||||||
|
|
||||||
struct stat teststruct;
|
struct stat teststruct;
|
||||||
// STEP 1: run until interesting function starts, and save state
|
// STEP 1: run until interesting function starts, and save state
|
||||||
if (stat(state_folder, &teststruct) == -1) {
|
if (stat(state_folder, &teststruct) == -1) {
|
||||||
bp.setWatchInstructionPointer(COOL_ECC_FUNC_ENTRY);
|
bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
|
||||||
sal::simulator.addEventAndWait(&bp);
|
sal::simulator.addEventAndWait(&bp);
|
||||||
|
|
||||||
log << "test function entry reached, saving state" << endl;
|
log << "test function entry reached, saving state" << endl;
|
||||||
@ -112,7 +111,7 @@ bool L4SysExperiment::run() {
|
|||||||
std::ofstream instr_list_file(instr_list_fn);
|
std::ofstream instr_list_file(instr_list_fn);
|
||||||
instr_list_file << std::hex;
|
instr_list_file << std::hex;
|
||||||
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
||||||
while (bp.getTriggerInstructionPointer() != COOL_ECC_CALCDONE) {
|
while (bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) {
|
||||||
sal::simulator.addEventAndWait(&bp);
|
sal::simulator.addEventAndWait(&bp);
|
||||||
//short sanity check
|
//short sanity check
|
||||||
sal::address_t curr_instr = bp.getTriggerInstructionPointer();
|
sal::address_t curr_instr = bp.getTriggerInstructionPointer();
|
||||||
@ -146,7 +145,7 @@ bool L4SysExperiment::run() {
|
|||||||
sal::simulator.addSuppressedInterrupt(32);
|
sal::simulator.addSuppressedInterrupt(32);
|
||||||
|
|
||||||
std::ofstream golden_run_file(golden_run_fn);
|
std::ofstream golden_run_file(golden_run_fn);
|
||||||
bp.setWatchInstructionPointer(COOL_ECC_CALCDONE);
|
bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT);
|
||||||
bp.setCounter(times_run);
|
bp.setCounter(times_run);
|
||||||
sal::simulator.addEvent(&bp);
|
sal::simulator.addEvent(&bp);
|
||||||
fi::BaseEvent* ev = waitIOOrOther(true);
|
fi::BaseEvent* ev = waitIOOrOther(true);
|
||||||
@ -183,10 +182,10 @@ bool L4SysExperiment::run() {
|
|||||||
output.reserve(flen);
|
output.reserve(flen);
|
||||||
}
|
}
|
||||||
|
|
||||||
//end of critical section
|
#endif
|
||||||
|
|
||||||
// STEP 4: The actual experiment.
|
// STEP 4: The actual experiment.
|
||||||
for (int i = 0; i < COOL_ECC_NUMINSTR; i++) {
|
for (int i = 0; i < 1/*L4SYS_NUMINSTR*/; i++) {
|
||||||
log << "restoring state" << endl;
|
log << "restoring state" << endl;
|
||||||
sal::simulator.restore(state_folder);
|
sal::simulator.restore(state_folder);
|
||||||
|
|
||||||
@ -195,7 +194,7 @@ bool L4SysExperiment::run() {
|
|||||||
if (!m_jc.getParam(param)) {
|
if (!m_jc.getParam(param)) {
|
||||||
log << "Dying." << endl;
|
log << "Dying." << endl;
|
||||||
// communicate that we were told to die
|
// communicate that we were told to die
|
||||||
sal::simulator.terminate(1); // "return (false);" ?
|
sal::simulator.terminate(1);
|
||||||
}
|
}
|
||||||
int id = param.getWorkloadID();
|
int id = param.getWorkloadID();
|
||||||
int instr_offset = param.msg.instr_offset();
|
int instr_offset = param.msg.instr_offset();
|
||||||
@ -239,10 +238,10 @@ bool L4SysExperiment::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// aftermath
|
// aftermath
|
||||||
fi::BPSingleEvent ev_done(COOL_ECC_CALCDONE, aspace);
|
fi::BPSingleEvent ev_done(L4SYS_FUNC_EXIT, aspace);
|
||||||
ev_done.setCounter(times_run);
|
ev_done.setCounter(times_run);
|
||||||
sal::simulator.addEvent(&ev_done);
|
sal::simulator.addEvent(&ev_done);
|
||||||
const unsigned instr_run = times_run * COOL_ECC_NUMINSTR;
|
const unsigned instr_run = times_run * L4SYS_NUMINSTR;
|
||||||
fi::BPSingleEvent ev_timeout(fi::ANY_ADDR, aspace);
|
fi::BPSingleEvent ev_timeout(fi::ANY_ADDR, aspace);
|
||||||
ev_timeout.setCounter(instr_run + 3000);
|
ev_timeout.setCounter(instr_run + 3000);
|
||||||
sal::simulator.addEvent(&ev_timeout);
|
sal::simulator.addEvent(&ev_timeout);
|
||||||
@ -264,7 +263,7 @@ bool L4SysExperiment::run() {
|
|||||||
if (ev == &ev_done) {
|
if (ev == &ev_done) {
|
||||||
if (strcmp(output.c_str(), golden_run.c_str()) == 0) {
|
if (strcmp(output.c_str(), golden_run.c_str()) == 0) {
|
||||||
log << std::dec << "Result DONE" << endl;
|
log << std::dec << "Result DONE" << endl;
|
||||||
param.msg.set_resulttype(param.msg.CALCDONE);
|
param.msg.set_resulttype(param.msg.DONE);
|
||||||
} else {
|
} else {
|
||||||
log << std::dec << "Result WRONG" << endl;
|
log << std::dec << "Result WRONG" << endl;
|
||||||
param.msg.set_resulttype(param.msg.WRONG);
|
param.msg.set_resulttype(param.msg.WRONG);
|
||||||
|
|||||||
@ -3,9 +3,10 @@
|
|||||||
|
|
||||||
// FIXME autogenerate this
|
// FIXME autogenerate this
|
||||||
|
|
||||||
#define COOL_ECC_FUNC_ENTRY 0x1007cd0
|
#define L4SYS_FUNC_ENTRY 0x1007cd0
|
||||||
#define COOL_ECC_CALCDONE 0x1007d3a
|
#define L4SYS_FUNC_EXIT 0x1007d3a
|
||||||
#define COOL_ECC_NUMINSTR 3166
|
#define L4SYS_NUMINSTR 3184
|
||||||
#define HEADLESS_EXPERIMENT
|
//#define HEADLESS_EXPERIMENT
|
||||||
|
#define PREPARE_EXPERIMENT
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,7 +6,7 @@ message L4SysProtoMsg {
|
|||||||
// results
|
// results
|
||||||
// make these optional to reduce overhead for server->client communication
|
// make these optional to reduce overhead for server->client communication
|
||||||
enum ResultType {
|
enum ResultType {
|
||||||
CALCDONE = 1;
|
DONE = 1;
|
||||||
TIMEOUT = 2;
|
TIMEOUT = 2;
|
||||||
TRAP = 3;
|
TRAP = 3;
|
||||||
INTR = 4;
|
INTR = 4;
|
||||||
|
|||||||
@ -45,7 +45,7 @@ ExperimentData *JobServer::getDone()
|
|||||||
&& m_doneJobs.Size() == 0) {
|
&& m_doneJobs.Size() == 0) {
|
||||||
// FRICKEL workaround
|
// FRICKEL workaround
|
||||||
sleep(1);
|
sleep(1);
|
||||||
ExperimentData *exp;
|
ExperimentData *exp = NULL;
|
||||||
if (m_doneJobs.Dequeue_nb(exp)) {
|
if (m_doneJobs.Dequeue_nb(exp)) {
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user