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:
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
|
||||
BufferCache.cc
|
||||
CampaignManager.cc
|
||||
CoroutineManager.cc
|
||||
Event.cc
|
||||
|
||||
@ -12,6 +12,10 @@ EventId EventList::add(BaseEvent* ev, ExperimentFlow* pExp)
|
||||
// a zero counter does not make sense
|
||||
assert(ev->getCounter() != 0);
|
||||
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);
|
||||
return (ev->getId());
|
||||
}
|
||||
@ -27,6 +31,7 @@ void EventList::remove(BaseEvent* ev)
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
for (firelist_t::iterator it = m_FireList.begin(); it != m_FireList.end(); it++)
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
m_Bp_cache.clear();
|
||||
m_BufferList.clear();
|
||||
// all remaining active events must not fire anymore
|
||||
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
|
||||
} else {
|
||||
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);
|
||||
firelist_t::const_iterator it =
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
@ -80,6 +93,7 @@ void EventList::remove(ExperimentFlow* flow)
|
||||
for (bufferlist_t::iterator it = m_BufferList.begin();
|
||||
it != m_BufferList.end(); it++)
|
||||
sal::simulator.onEventDeletion(*it); // invoke event handler
|
||||
m_Bp_cache.clear();
|
||||
m_BufferList.clear();
|
||||
} else { // remove all events corresponding to a specific experiment ("flow"):
|
||||
for (bufferlist_t::iterator it = m_BufferList.begin();
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "Event.hpp"
|
||||
#include "BufferCache.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
@ -53,6 +54,7 @@ class EventList
|
||||
deletelist_t m_DeleteList; //!< the deleted events (used temporarily)
|
||||
// TODO: Hashing?
|
||||
BaseEvent* m_pFired; //!< the recently fired Event-object
|
||||
BufferCache<BPEvent*> m_Bp_cache;
|
||||
public:
|
||||
/**
|
||||
* The iterator of this class used to loop through the list of
|
||||
@ -180,6 +182,11 @@ class EventList
|
||||
* TODO: Improve naming (instead of "fireActiveEvents")?
|
||||
*/
|
||||
void fireActiveEvents();
|
||||
/**
|
||||
* Retrieves the BPEvent buffer cache.
|
||||
* @returns the buffer cache
|
||||
*/
|
||||
inline BufferCache<BPEvent*> *getBPBuffer() { return &m_Bp_cache; }
|
||||
};
|
||||
|
||||
}; // end-of-namespace: fi
|
||||
|
||||
Reference in New Issue
Block a user