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:
@ -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)")
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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__
|
||||
@ -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
|
||||
|
||||
@ -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"):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user