mirror of https://github.com/OpenTTD/OpenTTD
(svn r17839) -Codechange: implement the concept of 'caching' pool items to pools, that is instead of 'free' push the unused items in a linked list and use them on 'malloc'. Also add the concept of zeroing, or actually not zeroing, on new for pool items.
parent
0ebe525e5b
commit
1528b64a68
|
@ -17,8 +17,8 @@
|
||||||
#include "pool_type.hpp"
|
#include "pool_type.hpp"
|
||||||
|
|
||||||
#define DEFINE_POOL_METHOD(type) \
|
#define DEFINE_POOL_METHOD(type) \
|
||||||
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, bool Tzero> \
|
||||||
type Pool<Titem, Tindex, Tgrowth_step, Tmax_size>
|
type Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero>
|
||||||
|
|
||||||
DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
|
DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
|
||||||
name(name),
|
name(name),
|
||||||
|
@ -27,7 +27,8 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
|
||||||
first_unused(0),
|
first_unused(0),
|
||||||
items(0),
|
items(0),
|
||||||
cleaning(false),
|
cleaning(false),
|
||||||
data(NULL)
|
data(NULL),
|
||||||
|
alloc_cache(NULL)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
DEFINE_POOL_METHOD(inline void)::ResizeFor(size_t index)
|
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->first_unused = max(this->first_unused, index + 1);
|
||||||
this->items++;
|
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;
|
item->index = (uint)index;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +123,13 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index)
|
||||||
{
|
{
|
||||||
assert(index < this->size);
|
assert(index < this->size);
|
||||||
assert(this->data[index] != NULL);
|
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->data[index] = NULL;
|
||||||
this->first_free = min(this->first_free, index);
|
this->first_free = min(this->first_free, index);
|
||||||
this->items--;
|
this->items--;
|
||||||
|
@ -129,6 +147,14 @@ DEFINE_POOL_METHOD(void)::CleanPool()
|
||||||
this->first_unused = this->first_free = this->size = 0;
|
this->first_unused = this->first_free = this->size = 0;
|
||||||
this->data = NULL;
|
this->data = NULL;
|
||||||
this->cleaning = false;
|
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
|
#undef DEFINE_POOL_METHOD
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
* @tparam Tindex Type of the index for this pool
|
* @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 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 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 {
|
struct Pool {
|
||||||
static const size_t MAX_SIZE = Tmax_size; ///< Make template parameter accessible from outside
|
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
|
* Base class for all PoolItems
|
||||||
* @tparam Tpool The pool this item is going to be part of
|
* @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 {
|
struct PoolItem {
|
||||||
Tindex index; ///< Index of this pool item
|
Tindex index; ///< Index of this pool item
|
||||||
|
|
||||||
|
@ -252,6 +255,18 @@ struct Pool {
|
||||||
private:
|
private:
|
||||||
static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t); ///< Contant to indicate we can't allocate any more items
|
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
|
* Makes given index valid
|
||||||
* @param size size of item
|
* @param size size of item
|
||||||
|
|
Loading…
Reference in New Issue