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_FIRE_INTERRUPTS "Target backend: Fire interrupts" OFF)
|
||||||
OPTION(CONFIG_DISABLE_KEYB_INTERRUPTS "Target backend: Suppress keyboard interrupts" OFF)
|
OPTION(CONFIG_DISABLE_KEYB_INTERRUPTS "Target backend: Suppress keyboard interrupts" OFF)
|
||||||
OPTION(SERVER_PERFORMANCE_MEASURE "Performance measurement in job-server" 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_HOSTNAME "localhost" CACHE STRING "Job-server hostname or IP")
|
||||||
SET(SERVER_COMM_TCP_PORT "1111" CACHE STRING "Job-server TCP port")
|
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)")
|
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_TRAP
|
||||||
#cmakedefine CONFIG_EVENT_JUMP
|
#cmakedefine CONFIG_EVENT_JUMP
|
||||||
|
|
||||||
|
// Performance options
|
||||||
|
#cmakedefine CONFIG_FAST_BREAKPOINTS
|
||||||
|
|
||||||
// Save/restore functionality
|
// Save/restore functionality
|
||||||
#cmakedefine CONFIG_SR_RESTORE
|
#cmakedefine CONFIG_SR_RESTORE
|
||||||
#cmakedefine CONFIG_SR_SAVE
|
#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)
|
if(BUILD_BOCHS)
|
||||||
set(SRCS
|
set(SRCS
|
||||||
BufferCache.cc
|
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
SALConfig.cc
|
SALConfig.cc
|
||||||
@ -12,7 +11,6 @@ if(BUILD_BOCHS)
|
|||||||
)
|
)
|
||||||
elseif(BUILD_GEM5)
|
elseif(BUILD_GEM5)
|
||||||
set(SRCS
|
set(SRCS
|
||||||
BufferCache.cc
|
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
SALConfig.cc
|
SALConfig.cc
|
||||||
@ -24,7 +22,6 @@ elseif(BUILD_GEM5)
|
|||||||
)
|
)
|
||||||
elseif(BUILD_OVP)
|
elseif(BUILD_OVP)
|
||||||
set(SRCS
|
set(SRCS
|
||||||
BufferCache.cc
|
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
SALConfig.cc
|
SALConfig.cc
|
||||||
@ -35,7 +32,6 @@ elseif(BUILD_OVP)
|
|||||||
)
|
)
|
||||||
elseif(BUILD_QEMU)
|
elseif(BUILD_QEMU)
|
||||||
set(SRCS
|
set(SRCS
|
||||||
BufferCache.cc
|
|
||||||
Listener.cc
|
Listener.cc
|
||||||
ListenerManager.cc
|
ListenerManager.cc
|
||||||
SALConfig.cc
|
SALConfig.cc
|
||||||
|
|||||||
@ -5,34 +5,6 @@
|
|||||||
|
|
||||||
namespace fail {
|
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)
|
void ListenerManager::add(BaseListener* li, ExperimentFlow* pExp)
|
||||||
{
|
{
|
||||||
assert(li != NULL && "FATAL ERROR: Listener (of base type BaseListener*) cannot be NULL!");
|
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;
|
index_t idx = m_BufferList.size()-1;
|
||||||
assert(m_BufferList[idx] == li && "FATAL ERROR: Invalid index after push_back() unexpected!");
|
assert(m_BufferList[idx] == li && "FATAL ERROR: Invalid index after push_back() unexpected!");
|
||||||
li->setLocation(idx);
|
li->setLocation(idx);
|
||||||
addToCaches(li); // FIXME: REMOVE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListenerManager::remove(BaseListener* li)
|
void ListenerManager::remove(BaseListener* li)
|
||||||
@ -81,7 +52,6 @@ void ListenerManager::remove(BaseListener* li)
|
|||||||
// ==> no further processing required here
|
// ==> no further processing required here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearCaches(); // FIXME: REMOVE
|
|
||||||
// All remaining active listeners must not fire anymore
|
// All remaining active listeners 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());
|
||||||
|
|
||||||
@ -92,7 +62,6 @@ void ListenerManager::remove(BaseListener* li)
|
|||||||
// * If 'li' in 'm_FireList', copy to 'm_DeleteList'
|
// * 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)
|
} else if (li->getLocation() != INVALID_INDEX) { // Check if li hasn't been added previously (Q&D)
|
||||||
li->onDeletion();
|
li->onDeletion();
|
||||||
removeFromCaches(li); // FIXME: REMOVE
|
|
||||||
if (li->getPerformanceBuffer() != NULL)
|
if (li->getPerformanceBuffer() != NULL)
|
||||||
li->getPerformanceBuffer()->remove(li->getLocation());
|
li->getPerformanceBuffer()->remove(li->getLocation());
|
||||||
m_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
|
// Note: This operation has O(1) time complexity. It copies (aka "swaps") the
|
||||||
// trailing element "m_BufferList[m_BufferList.size()-1]" to the slot
|
// trailing element "m_BufferList[m_BufferList.size()-1]" to the slot
|
||||||
// at "m_BufferList[idx]" and removes the last element (pop_back()).
|
// 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
|
// Override the element to be deleted (= copy the last element to the slot
|
||||||
// of the element to be deleted) and update their attributes:
|
// 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.
|
// to *delete* (not "move") a listener.
|
||||||
(*it)->onDeletion();
|
(*it)->onDeletion();
|
||||||
m_DeleteList.push_back(*it);
|
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)
|
// 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();
|
for (std::set<PerfBufferBase*>::iterator it = perfBufLists.begin();
|
||||||
it != perfBufLists.end(); ++it)
|
it != perfBufLists.end(); ++it)
|
||||||
(*it)->clear();
|
(*it)->clear();
|
||||||
clearCaches(); // FIXME: REMOVE
|
|
||||||
// All remaining active listeners must not fire anymore
|
// All remaining active listeners 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());
|
||||||
} else { // remove all listeners corresponding to a specific experiment ("flow"):
|
} else { // remove all listeners corresponding to a specific experiment ("flow"):
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Listener.hpp"
|
#include "Listener.hpp"
|
||||||
#include "BufferCache.hpp"
|
|
||||||
|
|
||||||
namespace fail {
|
namespace fail {
|
||||||
|
|
||||||
@ -30,14 +29,6 @@ typedef std::vector<BaseListener*> firelist_t;
|
|||||||
*/
|
*/
|
||||||
typedef std::vector<BaseListener*> deletelist_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
|
* \class ListenerManager
|
||||||
*
|
*
|
||||||
@ -59,10 +50,6 @@ private:
|
|||||||
firelist_t m_FireList; //!< the active listeners (used temporarily)
|
firelist_t m_FireList; //!< the active listeners (used temporarily)
|
||||||
deletelist_t m_DeleteList; //!< the deleted listeners (used temporarily)
|
deletelist_t m_DeleteList; //!< the deleted listeners (used temporarily)
|
||||||
BaseListener* m_pFired; //!< the recently fired Listener-object
|
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:
|
public:
|
||||||
/**
|
/**
|
||||||
* Determines the pointer to the listener base type, stored at index \c idx.
|
* 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.
|
* 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.
|
* This is done by replacing the element with the last element of the vector.
|
||||||
* @param idx the index of the element to be removed
|
* @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.
|
* updated.
|
||||||
* @note This method should typically be used in a performance buffer-list
|
* @note This method should typically be used in a performance buffer-list
|
||||||
* implemenation.
|
* implemenation.
|
||||||
@ -226,31 +213,6 @@ public:
|
|||||||
* triggered, the (internal) fire- and delete-list will be cleared.
|
* triggered, the (internal) fire- and delete-list will be cleared.
|
||||||
*/
|
*/
|
||||||
void triggerActiveListeners();
|
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
|
} // end-of-namespace: fail
|
||||||
|
|||||||
@ -95,14 +95,14 @@ void BochsController::onBreakpoint(address_t instrPtr, address_t address_space)
|
|||||||
#endif
|
#endif
|
||||||
bool do_fire = false;
|
bool do_fire = false;
|
||||||
// Check for active breakpoint-events:
|
// Check for active breakpoint-events:
|
||||||
bp_cache_t &buffer_cache = m_LstList.getBPBuffer();
|
ListenerManager::iterator it = m_LstList.begin();
|
||||||
bp_cache_t::iterator it = buffer_cache.begin();
|
|
||||||
BPEvent tmp(instrPtr, address_space);
|
BPEvent tmp(instrPtr, address_space);
|
||||||
while (it != buffer_cache.end()) {
|
while (it != m_LstList.end()) {
|
||||||
BPListener* pEvBreakpt = *it;
|
BaseListener* pLi = *it;
|
||||||
if (pEvBreakpt->isMatching(&tmp)) {
|
BPListener* pBreakpt = dynamic_cast<BPListener*>(pLi);
|
||||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
if (pBreakpt != NULL && pBreakpt->isMatching(&tmp)) {
|
||||||
it = buffer_cache.makeActive(m_LstList, it);
|
pBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||||
|
it = m_LstList.makeActive(it);
|
||||||
do_fire = true;
|
do_fire = true;
|
||||||
// "it" has already been set to the next element (by calling
|
// "it" has already been set to the next element (by calling
|
||||||
// makeActive()):
|
// 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) {
|
void BochsController::onIOPort(unsigned char data, unsigned port, bool out) {
|
||||||
// Check for active IOPortListeners:
|
// Check for active IOPortListeners:
|
||||||
io_cache_t &buffer_cache = m_LstList.getIOBuffer();
|
ListenerManager::iterator it = m_LstList.begin();
|
||||||
io_cache_t::iterator it = buffer_cache.begin();
|
while (it != m_LstList.end()) {
|
||||||
while (it != buffer_cache.end()) {
|
BaseListener* pLi = *it;
|
||||||
IOPortListener* pIOPt = (*it);
|
IOPortListener* pIOPt = dynamic_cast<IOPortListener*>(pLi);
|
||||||
if (pIOPt->isMatching(port, out)) {
|
if (pIOPt != NULL && pIOPt->isMatching(port, out)) {
|
||||||
pIOPt->setData(data);
|
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
|
// "it" has already been set to the next element (by calling
|
||||||
// makeActive()):
|
// makeActive()):
|
||||||
continue; // -> skip iterator increment
|
continue; // -> skip iterator increment
|
||||||
|
|||||||
@ -35,17 +35,16 @@ void Gem5Controller::reboot()
|
|||||||
void Gem5Controller::onBreakpoint(address_t instrPtr, address_t address_space)
|
void Gem5Controller::onBreakpoint(address_t instrPtr, address_t address_space)
|
||||||
{
|
{
|
||||||
bool do_fire = false;
|
bool do_fire = false;
|
||||||
|
BPEvent tmp(instrPtr, address_space);
|
||||||
// Check for active breakpoint-events:
|
// Check for active breakpoint-events:
|
||||||
bp_cache_t &buffer_cache = m_LstList.getBPBuffer();
|
for (ListenerManager::iterator it = m_LstList.begin(); it != m_LstList.end(); it++) {
|
||||||
for(bp_cache_t::iterator it = buffer_cache.begin(); it != buffer_cache.end(); it++)
|
BaseListener* pLi = *it;
|
||||||
{
|
BPListener* pBreakpt = dynamic_cast<BPListener*>(pLi);
|
||||||
BPListener* pEvBreakpt = *it;
|
if(pBreakpt != NULL && pBreakpt->isMatching(&tmp)) {
|
||||||
if(pEvBreakpt->isMatching(instrPtr, address_space)) {
|
pBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
it = m_LstList.makeActive(it);
|
||||||
it = buffer_cache.makeActive(m_LstList, it);
|
|
||||||
do_fire = true;
|
do_fire = true;
|
||||||
// "it" has already been set to the next element (by calling
|
// "it" has already been set to the next element (by calling makeActive()):
|
||||||
// makeActive()):
|
|
||||||
continue; // -> skip iterator increment
|
continue; // -> skip iterator increment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,15 +22,16 @@ QEMUController::~QEMUController()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: copied from BochsController; remove redundancy!
|
// 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:
|
// Check for active IOPortListeners:
|
||||||
io_cache_t &buffer_cache = m_LstList.getIOBuffer();
|
ListenerManager::iterator it = m_LstList.begin();
|
||||||
io_cache_t::iterator it = buffer_cache.begin();
|
while (it != m_LstList.end()) {
|
||||||
while (it != buffer_cache.end()) {
|
BaseListener* pLi = ;
|
||||||
IOPortListener* pIOPt = (*it);
|
IOPortListener* pIOPt = dynamic_cast<IOPortListener>(*it);
|
||||||
if (pIOPt->isMatching(port, out)) {
|
if (pIOPt != NULL && pIOPt->isMatching(port, out)) {
|
||||||
pIOPt->setData(data);
|
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
|
// "it" has already been set to the next element (by calling
|
||||||
// makeActive()):
|
// makeActive()):
|
||||||
continue; // -> skip iterator increment
|
continue; // -> skip iterator increment
|
||||||
|
|||||||
Reference in New Issue
Block a user