diff options
-rw-r--r-- | src/core/pool_func.hpp | 36 | ||||
-rw-r--r-- | src/core/pool_type.hpp | 19 |
2 files changed, 48 insertions, 7 deletions
diff --git a/src/core/pool_func.hpp b/src/core/pool_func.hpp index 567ef1ae9..68ee378b3 100644 --- a/src/core/pool_func.hpp +++ b/src/core/pool_func.hpp @@ -17,8 +17,8 @@ #include "pool_type.hpp" #define DEFINE_POOL_METHOD(type) \ - template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size> \ - type Pool<Titem, Tindex, Tgrowth_step, Tmax_size> + template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, bool Tcache, bool Tzero> \ + type Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero> DEFINE_POOL_METHOD(inline)::Pool(const char *name) : name(name), @@ -27,7 +27,8 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) : first_unused(0), items(0), cleaning(false), - data(NULL) + data(NULL), + alloc_cache(NULL) { } DEFINE_POOL_METHOD(inline void)::ResizeFor(size_t index) @@ -75,7 +76,18 @@ DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index) this->first_unused = max(this->first_unused, index + 1); this->items++; - Titem *item = this->data[index] = (Titem *)CallocT<byte>(size); + Titem *item; + if (Tcache && this->alloc_cache != NULL) { + assert(sizeof(Titem) == size); + item = (Titem *)this->alloc_cache; + this->alloc_cache = this->alloc_cache->next; + if (Tzero) MemSetT(item, 0); + } else if (Tzero) { + item = (Titem *)CallocT<byte>(size); + } else { + item = (Titem *)MallocT<byte>(size); + } + this->data[index] = item; item->index = (uint)index; return item; } @@ -111,7 +123,13 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index) { assert(index < this->size); assert(this->data[index] != NULL); - free(this->data[index]); + if (Tcache) { + AllocCache *ac = (AllocCache *)this->data[index]; + ac->next = this->alloc_cache; + this->alloc_cache = ac; + } else { + free(this->data[index]); + } this->data[index] = NULL; this->first_free = min(this->first_free, index); this->items--; @@ -129,6 +147,14 @@ DEFINE_POOL_METHOD(void)::CleanPool() this->first_unused = this->first_free = this->size = 0; this->data = NULL; this->cleaning = false; + + if (Tcache) { + while (this->alloc_cache != NULL) { + AllocCache *ac = this->alloc_cache; + this->alloc_cache = ac->next; + free(ac); + } + } } #undef DEFINE_POOL_METHOD diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 728678515..58a58f6ac 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.hpp @@ -18,8 +18,11 @@ * @tparam Tindex Type of the index for this pool * @tparam Tgrowth_step Size of growths; if the pool is full increase the size by this amount * @tparam Tmax_size Maximum size of the pool + * @tparam Tcache Whether to perform 'alloc' caching, i.e. don't actually free/malloc just reuse the memory + * @tparam Tzero Whether to zero the memory + * @warning when Tcache is enabled *all* instances of this pool's item must be of the same size. */ -template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size> +template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, bool Tcache = false, bool Tzero = true> struct Pool { static const size_t MAX_SIZE = Tmax_size; ///< Make template parameter accessible from outside @@ -75,7 +78,7 @@ struct Pool { * Base class for all PoolItems * @tparam Tpool The pool this item is going to be part of */ - template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size> *Tpool> + template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero> *Tpool> struct PoolItem { Tindex index; ///< Index of this pool item @@ -253,6 +256,18 @@ private: static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t); ///< Contant to indicate we can't allocate any more items /** + * Helper struct to cache 'freed' PoolItems so we + * do not need to allocate them again. + */ + struct AllocCache { + /** The next in our 'cache' */ + AllocCache *next; + }; + + /** Cache of freed pointers */ + AllocCache *alloc_cache; + + /** * Makes given index valid * @param size size of item * @param index index of item |