Removed BufferCache stuff (fast breakpoints will do the job, see r1685).

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1686 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
adrian
2012-09-25 11:36:19 +00:00
parent 0cb6b39490
commit 057c216dc0
10 changed files with 34 additions and 240 deletions

View File

@ -19,6 +19,7 @@ OPTION(CONFIG_SUPPRESS_INTERRUPTS "Target backend: Suppress interrupts" OF
OPTION(CONFIG_FIRE_INTERRUPTS "Target backend: Fire interrupts" OFF)
OPTION(CONFIG_DISABLE_KEYB_INTERRUPTS "Target backend: Suppress keyboard interrupts" OFF)
OPTION(SERVER_PERFORMANCE_MEASURE "Performance measurement in job-server" OFF)
OPTION(CONFIG_FAST_BREAKPOINTS "Enable fast breakpoints (requires breakpoint events to be enabled)" OFF)
SET(SERVER_COMM_HOSTNAME "localhost" CACHE STRING "Job-server hostname or IP")
SET(SERVER_COMM_TCP_PORT "1111" CACHE STRING "Job-server TCP port")
SET(SERVER_PERF_LOG_PATH "perf.log" CACHE STRING "A file name for storing the server's performance log (CSV)")

View File

@ -15,6 +15,9 @@
#cmakedefine CONFIG_EVENT_TRAP
#cmakedefine CONFIG_EVENT_JUMP
// Performance options
#cmakedefine CONFIG_FAST_BREAKPOINTS
// Save/restore functionality
#cmakedefine CONFIG_SR_RESTORE
#cmakedefine CONFIG_SR_SAVE

View File

@ -1,32 +0,0 @@
#include <algorithm>
#include <vector>
#include "BufferCache.hpp"
#include "Listener.hpp"
#include "ListenerManager.hpp"
namespace fail {
template<class T>
typename BufferCache<T>::iterator BufferCache<T>::makeActive(ListenerManager &ev_list, BufferCache<T>::iterator idx)
{
assert(idx != end() && "FATAL ERROR: Index larger than cache!");
T ev = *idx;
assert(ev && "FATAL ERROR: Object pointer cannot be NULL!");
ev->decreaseCounter();
if (ev->getCounter() > 0) {
return ++idx;
}
ev->resetCounter();
// Note: This is the one and only situation in which remove() should NOT
// store the removed item in the delete-list.
ListenerManager::iterator it = std::find(ev_list.begin(), ev_list.end(), static_cast<BaseListener*>(ev));
ev_list.m_remove(it, true); // remove listener from buffer-list
ev_list.m_FireList.push_back(ev);
return erase(idx);
}
// Declare here whatever instances of the template you are going to use:
template class BufferCache<BPListener*>;
template class BufferCache<IOPortListener*>;
} // end-of-namespace: fail

View File

@ -1,94 +0,0 @@
#ifndef __BUFFER_CACHE_HPP__
#define __BUFFER_CACHE_HPP__
#include <stdlib.h>
#include <list>
namespace fail {
class ListenerManager;
/**
* \class BufferCache
*
* \brief A simple dynamic array
*
* This class is intended to serve as a kind of cache for the
* untyped and therefore quite slow listener handling mechanism of Fail*.
*/
template<class T>
class BufferCache {
public:
/**
* The list type inherent to this class. Like bufferlist_t in ListenerManager.hpp,
* but dynamically typed.
*/
typedef std::list<T> cachelist_t;
/**
* The iterator of this class used to loop through the list of
* added listeners. 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
*/
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
*/
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
*/
inline iterator erase(iterator i) { return m_Buffer.erase(i); }
/**
* Clears the array, removing all elements. The objects pointed to remain untouched.
*/
inline void clear() { m_Buffer.clear(); }
/**
* 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 iterator begin() { return m_Buffer.begin(); }
/**
* 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 iterator end() { return m_Buffer.end(); }
/**
* Acts as a replacement for ListenerManager::makeActive, manipulating
* the buffer cache exclusively. ListenerManager::triggerActiveListeners needs
* to be called to fire the active listeners (see there).
* This method is declared as a friend method in ListenerManager.
* @param idx the index of the listener to trigger
* @returns an updated index which can be used to update a loop counter
*/
iterator makeActive(ListenerManager &ev_list, iterator idx);
};
} // end-of-namespace: fail
#endif // __BUFFER_CACHE_HPP__

View File

@ -1,6 +1,5 @@
if(BUILD_BOCHS)
set(SRCS
BufferCache.cc
Listener.cc
ListenerManager.cc
SALConfig.cc
@ -12,7 +11,6 @@ if(BUILD_BOCHS)
)
elseif(BUILD_GEM5)
set(SRCS
BufferCache.cc
Listener.cc
ListenerManager.cc
SALConfig.cc
@ -24,7 +22,6 @@ elseif(BUILD_GEM5)
)
elseif(BUILD_OVP)
set(SRCS
BufferCache.cc
Listener.cc
ListenerManager.cc
SALConfig.cc
@ -35,7 +32,6 @@ elseif(BUILD_OVP)
)
elseif(BUILD_QEMU)
set(SRCS
BufferCache.cc
Listener.cc
ListenerManager.cc
SALConfig.cc

View File

@ -5,34 +5,6 @@
namespace fail {
void ListenerManager::addToCaches(BaseListener *li) // FIXME: REMOVE
{
BPListener *bps_li;
if ((bps_li = dynamic_cast<BPListener*>(li)) != NULL)
m_Bp_cache.add(bps_li);
IOPortListener *io_li;
if ((io_li = dynamic_cast<IOPortListener*>(li)) != NULL)
m_Io_cache.add(io_li);
}
void ListenerManager::removeFromCaches(BaseListener *li) // FIXME: REMOVE
{
BPListener *bpr_li;
if ((bpr_li = dynamic_cast<BPListener*>(li)) != NULL)
m_Bp_cache.remove(bpr_li);
IOPortListener *io_li;
if ((io_li = dynamic_cast<IOPortListener*>(li)) != NULL)
m_Io_cache.remove(io_li);
}
void ListenerManager::clearCaches() // FIXME: REMOVE
{
m_Bp_cache.clear();
m_Io_cache.clear();
}
void ListenerManager::add(BaseListener* li, ExperimentFlow* pExp)
{
assert(li != NULL && "FATAL ERROR: Listener (of base type BaseListener*) cannot be NULL!");
@ -47,7 +19,6 @@ void ListenerManager::add(BaseListener* li, ExperimentFlow* pExp)
index_t idx = m_BufferList.size()-1;
assert(m_BufferList[idx] == li && "FATAL ERROR: Invalid index after push_back() unexpected!");
li->setLocation(idx);
addToCaches(li); // FIXME: REMOVE
}
void ListenerManager::remove(BaseListener* li)
@ -81,7 +52,6 @@ void ListenerManager::remove(BaseListener* li)
// ==> no further processing required here
}
}
clearCaches(); // FIXME: REMOVE
// All remaining active listeners must not fire anymore
m_DeleteList.insert(m_DeleteList.end(), m_FireList.begin(), m_FireList.end());
@ -92,7 +62,6 @@ void ListenerManager::remove(BaseListener* li)
// * If 'li' in 'm_FireList', copy to 'm_DeleteList'
} else if (li->getLocation() != INVALID_INDEX) { // Check if li hasn't been added previously (Q&D)
li->onDeletion();
removeFromCaches(li); // FIXME: REMOVE
if (li->getPerformanceBuffer() != NULL)
li->getPerformanceBuffer()->remove(li->getLocation());
m_remove(li->getLocation());
@ -118,8 +87,6 @@ void ListenerManager::m_remove(index_t idx)
// Note: This operation has O(1) time complexity. It copies (aka "swaps") the
// trailing element "m_BufferList[m_BufferList.size()-1]" to the slot
// at "m_BufferList[idx]" and removes the last element (pop_back()).
if(idx == INVALID_INDEX)
((BaseListener*)NULL)->setPerformanceBuffer(NULL);
// Override the element to be deleted (= copy the last element to the slot
// of the element to be deleted) and update their attributes:
@ -156,14 +123,6 @@ ListenerManager::iterator ListenerManager::m_remove(iterator it, bool skip_delet
// to *delete* (not "move") a listener.
(*it)->onDeletion();
m_DeleteList.push_back(*it);
// Cached listeners have their own BufferCache<T>::makeActive() implementation, which
// calls this method and afterwards erase() in the cache class. This is why, when
// called from any kind of makeActive() method, it is unnecessary to call
// BufferCache<T>::remove() from m_remove().
// NOTE: in case the semantics of skip_deletelist change, please adapt the following lines
removeFromCaches(*it); // FIXME: REMOVE (incl. comments)
}
// This has O(1) time complexity due to a underlying std::vector (-> random access iterator)
@ -206,7 +165,6 @@ void ListenerManager::remove(ExperimentFlow* flow)
for (std::set<PerfBufferBase*>::iterator it = perfBufLists.begin();
it != perfBufLists.end(); ++it)
(*it)->clear();
clearCaches(); // FIXME: REMOVE
// All remaining active listeners must not fire anymore
m_DeleteList.insert(m_DeleteList.end(), m_FireList.begin(), m_FireList.end());
} else { // remove all listeners corresponding to a specific experiment ("flow"):

View File

@ -7,7 +7,6 @@
#include <algorithm>
#include "Listener.hpp"
#include "BufferCache.hpp"
namespace fail {
@ -30,14 +29,6 @@ typedef std::vector<BaseListener*> firelist_t;
*/
typedef std::vector<BaseListener*> deletelist_t;
/**
* Cache classes for the most commonly used types of listeners, utilising static typing.
* Apart from that, they work like bufferlist_t.
*/
typedef BufferCache<BPListener*> bp_cache_t;
typedef bp_cache_t::iterator bp_iter_t;
typedef BufferCache<IOPortListener*> io_cache_t;
typedef io_cache_t::iterator io_iter_t;
/**
* \class ListenerManager
*
@ -59,10 +50,6 @@ private:
firelist_t m_FireList; //!< the active listeners (used temporarily)
deletelist_t m_DeleteList; //!< the deleted listeners (used temporarily)
BaseListener* m_pFired; //!< the recently fired Listener-object
bp_cache_t m_Bp_cache; //!< the storage cache for breakpoint listeners
io_cache_t m_Io_cache; //!< the storage cache for port i/o listeners
friend bp_iter_t bp_cache_t::makeActive(ListenerManager &ev_list, bp_iter_t idx);
friend io_iter_t io_cache_t::makeActive(ListenerManager &ev_list, io_iter_t idx);
public:
/**
* Determines the pointer to the listener base type, stored at index \c idx.
@ -124,7 +111,7 @@ private:
* Updates the buffer-list by "removing" the element located at index \c idx.
* This is done by replacing the element with the last element of the vector.
* @param idx the index of the element to be removed
* @warning The internals of the listener, stored at index \c idx wont be
* @warning The internals of the listener, stored at index \c idx will be
* updated.
* @note This method should typically be used in a performance buffer-list
* implemenation.
@ -226,31 +213,6 @@ public:
* triggered, the (internal) fire- and delete-list will be cleared.
*/
void triggerActiveListeners();
/**
* Retrieves the BPListener buffer cache.
* @returns the buffer cache
*/
inline bp_cache_t &getBPBuffer() { return m_Bp_cache; }
/**
* Retrieves the IOPortListener buffer cache.
* @returns the buffer cache
*/
inline io_cache_t &getIOBuffer() { return m_Io_cache; }
private:
/**
* Add an listener to its appropriate cache.
* @param li the listener to add
*/
void addToCaches(BaseListener* li);
/**
* Remove an listener from its cache.
* @param li the listener to remove
*/
void removeFromCaches(BaseListener* li);
/**
* Clear the listener caches.
*/
void clearCaches();
};
} // end-of-namespace: fail

View File

@ -95,14 +95,14 @@ void BochsController::onBreakpoint(address_t instrPtr, address_t address_space)
#endif
bool do_fire = false;
// Check for active breakpoint-events:
bp_cache_t &buffer_cache = m_LstList.getBPBuffer();
bp_cache_t::iterator it = buffer_cache.begin();
ListenerManager::iterator it = m_LstList.begin();
BPEvent tmp(instrPtr, address_space);
while (it != buffer_cache.end()) {
BPListener* pEvBreakpt = *it;
if (pEvBreakpt->isMatching(&tmp)) {
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
it = buffer_cache.makeActive(m_LstList, it);
while (it != m_LstList.end()) {
BaseListener* pLi = *it;
BPListener* pBreakpt = dynamic_cast<BPListener*>(pLi);
if (pBreakpt != NULL && pBreakpt->isMatching(&tmp)) {
pBreakpt->setTriggerInstructionPointer(instrPtr);
it = m_LstList.makeActive(it);
do_fire = true;
// "it" has already been set to the next element (by calling
// makeActive()):
@ -126,13 +126,13 @@ void BochsController::updateBPEventInfo(BX_CPU_C *context, bxICacheEntry_c *cach
void BochsController::onIOPort(unsigned char data, unsigned port, bool out) {
// Check for active IOPortListeners:
io_cache_t &buffer_cache = m_LstList.getIOBuffer();
io_cache_t::iterator it = buffer_cache.begin();
while (it != buffer_cache.end()) {
IOPortListener* pIOPt = (*it);
if (pIOPt->isMatching(port, out)) {
ListenerManager::iterator it = m_LstList.begin();
while (it != m_LstList.end()) {
BaseListener* pLi = *it;
IOPortListener* pIOPt = dynamic_cast<IOPortListener*>(pLi);
if (pIOPt != NULL && pIOPt->isMatching(port, out)) {
pIOPt->setData(data);
it = buffer_cache.makeActive(m_LstList, it);
it = m_LstList.makeActive(it);
// "it" has already been set to the next element (by calling
// makeActive()):
continue; // -> skip iterator increment

View File

@ -35,17 +35,16 @@ void Gem5Controller::reboot()
void Gem5Controller::onBreakpoint(address_t instrPtr, address_t address_space)
{
bool do_fire = false;
BPEvent tmp(instrPtr, address_space);
// Check for active breakpoint-events:
bp_cache_t &buffer_cache = m_LstList.getBPBuffer();
for(bp_cache_t::iterator it = buffer_cache.begin(); it != buffer_cache.end(); it++)
{
BPListener* pEvBreakpt = *it;
if(pEvBreakpt->isMatching(instrPtr, address_space)) {
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
it = buffer_cache.makeActive(m_LstList, it);
for (ListenerManager::iterator it = m_LstList.begin(); it != m_LstList.end(); it++) {
BaseListener* pLi = *it;
BPListener* pBreakpt = dynamic_cast<BPListener*>(pLi);
if(pBreakpt != NULL && pBreakpt->isMatching(&tmp)) {
pBreakpt->setTriggerInstructionPointer(instrPtr);
it = m_LstList.makeActive(it);
do_fire = true;
// "it" has already been set to the next element (by calling
// makeActive()):
// "it" has already been set to the next element (by calling makeActive()):
continue; // -> skip iterator increment
}
}

View File

@ -22,15 +22,16 @@ QEMUController::~QEMUController()
}
// FIXME: copied from BochsController; remove redundancy!
void QEMUController::onIOPort(unsigned char data, unsigned port, bool out) {
void QEMUController::onIOPort(unsigned char data, unsigned port, bool out)
{
// Check for active IOPortListeners:
io_cache_t &buffer_cache = m_LstList.getIOBuffer();
io_cache_t::iterator it = buffer_cache.begin();
while (it != buffer_cache.end()) {
IOPortListener* pIOPt = (*it);
if (pIOPt->isMatching(port, out)) {
ListenerManager::iterator it = m_LstList.begin();
while (it != m_LstList.end()) {
BaseListener* pLi = ;
IOPortListener* pIOPt = dynamic_cast<IOPortListener>(*it);
if (pIOPt != NULL && pIOPt->isMatching(port, out)) {
pIOPt->setData(data);
it = buffer_cache.makeActive(m_LstList, it);
it = m_LstList.makeActive(it);
// "it" has already been set to the next element (by calling
// makeActive()):
continue; // -> skip iterator increment