ircd/pool.hpp
#ifndef POOL_HPP_
#define POOL_HPP_
#include "common.hpp"
#ifndef NDEBUG
#include <valgrind/memcheck.h>
#endif
#define MAX_TPOOL_SPARE 1000
template <class T> class TPool {
private:
struct tpool_node_s {
struct tpool_node_s* next;
T data;
};
tpool_node_s* head; ///< spare ones
unsigned size; ///< only needed for upper spare limit
public:
TPool();
~TPool();
static INLINE size_t len() { return sizeof(T); }
void push(T*);
T* pop();
};
template <class T> TPool<T>::TPool(): head(NULL), size(0) {
}
template <class T> TPool<T>::~TPool() {
tpool_node_s* node;
while ((node = head) != NULL) {
head = head->next;
free(node);
size--;
}
}
template <class T> void TPool<T>::push(T* data) {
tpool_node_s* node = (tpool_node_s*)(((char*)data) - (sizeof(tpool_node_s*)));
if (size >= MAX_TPOOL_SPARE) {
free(node);
} else {
#ifndef NDEBUG
VALGRIND_MAKE_MEM_UNDEFINED(data, sizeof(T));
#endif
node->next = head;
head = node;
size++;
}
}
template <class T> T* TPool<T>::pop() {
tpool_node_s* node;
if (head) {
node = head;
head = head->next;
size--;
} else {
node = (tpool_node_s*)malloc(sizeof(tpool_node_s));
}
return &node->data;
}
#endif