This is useful to reuse the DefPerfVector class for fast-watchpoints, too. git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1898 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
119 lines
4.1 KiB
C++
119 lines
4.1 KiB
C++
#ifndef __BREAKPOINT_BUFFER_HPP__
|
|
#define __BREAKPOINT_BUFFER_HPP__
|
|
|
|
#include "BufferInterface.hpp"
|
|
|
|
// TODOs:
|
|
// - Make these implementations even faster (see below: continue PerfVecSortedSingleBP).
|
|
|
|
namespace fail {
|
|
|
|
class BPEvent;
|
|
|
|
/**
|
|
* Concrete implementation for the \c BPSingleListener class.
|
|
*/
|
|
class PerfVectorBreakpoints : public DefPerfVector<BPEvent> {
|
|
public:
|
|
ResultSet& gather(BPEvent* pData);
|
|
};
|
|
|
|
/**
|
|
* \class PerfVecSortedSingleBP
|
|
*
|
|
* This class implements a faster mechanism to store BPSingleListener
|
|
* based on binary search on their corresponding instruction pointer.
|
|
*/
|
|
/*
|
|
class PerfVecSortedSingleBP : public PerfVectorBreakpoints {
|
|
private:
|
|
SimulatorController* m_Sim;
|
|
public:
|
|
PerfVecSortedSingleBP(SimulatorController* pSim) : m_Sim(pSim) { }
|
|
**
|
|
* TODO.
|
|
* @warning The method expects that \c idx is a valid index within the main
|
|
* buffer-list. Therefore we are allowed to call \c SimulatorController::dereference().
|
|
* Additionally, the indexed listener is expected to be of type \c BPListener*.
|
|
*
|
|
void add(index_t idx)
|
|
{
|
|
address_t watchIP = static_cast<BPSingleListener*>(m_Sim->dereference(idx))->getWatchInstructionPointer();
|
|
// Keep the indices sorted in ascending order regarding their instr. ptr.
|
|
// Search for the slot to insert the element (skip lower IPs):
|
|
int pos = binarySearch(m_BufList, 0, m_BufList.size()-1, idx);
|
|
assert(pos < 0 && "FATAL ERROR: Element already inserted!");
|
|
m_BufList.insert(it + (pos * (-1) + 1), idx);
|
|
// for (std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) {
|
|
// if (static_cast<BPSingleListener*>(
|
|
// m_Sim->dereference(*it))->getWatchInstructionPointer() > watchIP) {
|
|
// m_BufList.insert(it, idx); // Insert the element before "it"
|
|
// break;
|
|
// }
|
|
}
|
|
}
|
|
|
|
static bool CompareInstrPtr(index_t arg1, index_t arg2, void* pStuff)
|
|
{
|
|
SimulatorController* pSim = static_cast<SimulatorController*>(pStuff);
|
|
#define VAL(idx) \
|
|
static_cast<BPSingleListener*>(pSim->dereference(idx))->getWatchInstructionPointer()
|
|
return (VAL(arg1) > VAL(arg2);
|
|
}
|
|
|
|
**
|
|
* Searches vec[first]...vec[last] for \c key. Returns the index of the matching
|
|
* element if it finds key, otherwise -(index where it could be inserted)-1.
|
|
* @param vec array of sorted (ascending) values.
|
|
* @param first lower subscript bound
|
|
* @param last upper subscript bound
|
|
* @param key value to search for
|
|
* @param pfnCmp a function pointer to a comparison function, returning \c true
|
|
* if the first argument is greater than the second, otherwise \c false.
|
|
* The last parameter equals the last parameter provided by calling this
|
|
* method. It can be used to pass additional data.
|
|
* @return index of key, or -insertion_position -1 if key is not in the array.
|
|
* This value can easily be transformed into the position to insert it.
|
|
*
|
|
int binarySearch(const std::vector<index_t>& vec, index_t first, index_t last, index_t key, bool (*pfnCmp)(index_t, index_t, void*), void* pStuff = NULL)
|
|
{
|
|
|
|
while (first <= last) {
|
|
int mid = (first + last) / 2; // compute mid point.
|
|
if (VAL(key) > VAL(vec[mid]))
|
|
first = mid + 1; // repeat search in top half.
|
|
else if (VAL(key) < VAL(vec[mid]))
|
|
last = mid - 1; // repeat search in bottom half.
|
|
else
|
|
return mid; // found it. return position
|
|
}
|
|
return -(first + 1); // failed to find key
|
|
}
|
|
void remove(index_t idx)
|
|
{
|
|
int pos = binarySearch(m_BufList, 0, m_BufList.size()-1, idx, CompareInstrPtr, m_Sim);
|
|
if (pos >= 0)
|
|
m_BufList.erase(m_BufList.begin() + pos);
|
|
}
|
|
ResultSet& gather(BPEvent* pData)
|
|
{
|
|
// TODO: Improve this by using binary search, too!
|
|
ResultSet res;
|
|
// Search for all indices of matching listener objects:
|
|
for(std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) {
|
|
BPListener* pLi = static_cast<BPListener*>(simulator.dereference(*it));
|
|
if (pLi->isMatching(pData)) {
|
|
// Update trigger IPtr:
|
|
pLi->setTriggerInstructionPointer(pData->getTriggerInstructionPointer());
|
|
res.add(*it);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
};
|
|
*/
|
|
|
|
} // end-of-namespace: fail
|
|
|
|
#endif // __BREAKPOINT_BUFFER_HPP__
|