PLearn 0.1
|
A PMemPool is a collection of arenas for allocating an arbitrary number of objects of a fixed size. More...
#include <PMemPool.h>
Public Member Functions | |
PMemPool (size_t object_size, size_t initial_arena_size, float growth_factor=1.5, bool use_fast_deallocator=true) | |
Constructor specifies the size of each object to be allocated from the pool, how big (in number of objects) should be the first allocated arena, and how should subsequent arenas grow in size. | |
void * | allocate () |
Allocate one object from the pool. Throws bad_alloc if cannot allocate. | |
void | deallocate (void *p) |
Free an object from the pool; this is not extremely fast, as the arenas must be searched for who contains the address. | |
bool | empty () const |
Return true if no objects remain allocated within the pool. | |
void | purge_memory () |
Deallocate all memory from the pool. | |
Protected Member Functions | |
void * | allocateFromArenas () |
Search the list of arenas for one that contains some storage; if found, return it. | |
PMemArena * | newArena () |
Construct a new arena and return it; it is added to arenas and stormap. | |
Protected Attributes | |
std::list< PP< PMemArena > > | arenas |
list of allocated arenas | |
PMemArena * | last_arena |
arena we last allocated from | |
size_t | object_size |
size of each allocated object | |
size_t | initial_arena_size |
initially, now many objects per arena | |
size_t | cur_arena_size |
currently, how many objects per arena | |
float | arena_growth_factor |
by how much to grow cur_arena_size | |
map< void *, PMemArena * > | stormap |
quick access to arena storage addresses | |
bool | fast_deallocate |
whether to use fast deallocator | |
void * | free_list |
A PMemPool is a collection of arenas for allocating an arbitrary number of objects of a fixed size.
In addition to the fixed object size, the user may pass the initial arena size to create and by how much subsequent arenas should grow.
The pool offers two methods for object deallocation, the "standard deallocator" and the "fast" one. The standard deallocator must search for the applicable arena for releasing the memory, which can be rather slow. On the other hand, if an arena turns out to be empty after releasing the memory, its storage is releaseed, and memory given back to the system. The fast deallocator simply adds the released block to a pool-local free list (distinct from the Arena free list), and allocate may then take memory from there. It is, by construction, very fast (and the default behavior), at the cost of code obscurity and a less efficient storage release policy.
Definition at line 145 of file PMemPool.h.
PLearn::PMemPool::PMemPool | ( | size_t | object_size, |
size_t | initial_arena_size, | ||
float | growth_factor = 1.5 , |
||
bool | use_fast_deallocator = true |
||
) |
Constructor specifies the size of each object to be allocated from the pool, how big (in number of objects) should be the first allocated arena, and how should subsequent arenas grow in size.
Definition at line 98 of file PMemPool.cc.
: last_arena(0), object_size(object_size_), initial_arena_size(initial_size_), cur_arena_size(initial_size_), arena_growth_factor(growth_factor_), fast_deallocate(use_fast_deallocator), free_list(0) { }
void * PLearn::PMemPool::allocate | ( | ) |
Allocate one object from the pool. Throws bad_alloc if cannot allocate.
Reimplemented in PLearn::PObjectPool< T >, PLearn::PObjectPool< StandaloneFunction >, and PLearn::PObjectPool< PyMethodDef >.
Definition at line 109 of file PMemPool.cc.
References PLearn::PMemArena::allocate(), allocateFromArenas(), free_list, last_arena, and newArena().
Referenced by PLearn::PObjectPool< PyMethodDef >::allocate().
{ // First try to allocate from last-used arena if (last_arena) { if (void* new_mem = last_arena->allocate()) return new_mem; } // Otherwise, try to allocate from free list if (free_list) { void** to_return = static_cast<void**>(free_list); free_list = *to_return; return to_return; } // Otherwise, try to allocate from an existing arena if (void* new_mem = allocateFromArenas()) return new_mem; // Otherwise, create a new arena and allocate from it last_arena = newArena(); if (last_arena) if (void* new_mem = last_arena->allocate()) return new_mem; // Last resort, throw bad_alloc... throw std::bad_alloc(); }
void * PLearn::PMemPool::allocateFromArenas | ( | ) | [protected] |
Search the list of arenas for one that contains some storage; if found, return it.
last_arena is modified.
Definition at line 174 of file PMemPool.cc.
References arenas, and last_arena.
Referenced by allocate().
{ for (list< PP<PMemArena> >::iterator it = arenas.begin(), end = arenas.end() ; it != end ; ++it) { if (void* newmem = (*it)->allocate()) { last_arena = *it; return newmem; } } return 0; }
void PLearn::PMemPool::deallocate | ( | void * | p | ) |
Free an object from the pool; this is not extremely fast, as the arenas must be searched for who contains the address.
If an arena becomes completely free, it is destroyed and its memory released.
Definition at line 138 of file PMemPool.cc.
References arenas, PLearn::PMemArena::belongsToArena(), PLearn::PMemArena::deallocate(), PLearn::PMemArena::empty(), fast_deallocate, free_list, last_arena, PLASSERT, and stormap.
Referenced by PLearn::PObjectPool< PyMethodDef >::deallocate().
{ // Fast deallocation :: append to free list if (fast_deallocate) { void** new_free_head = static_cast<void**>(p); *new_free_head = free_list; free_list = new_free_head; } // Traditional deallocator else { if (last_arena && last_arena->belongsToArena(p)) last_arena->deallocate(p); else { // Find arena from map map<void*,PMemArena*>::iterator arena_it = stormap.upper_bound(p); PLASSERT( arena_it != stormap.begin() ); --arena_it; PMemArena* arena = arena_it->second; PLASSERT( arena && arena->belongsToArena(p)); arena->deallocate(p); last_arena = arena; } // Check to see if arena should be eliminated if (last_arena && last_arena->empty()) { map<void*,PMemArena*>::iterator arena_it = stormap.upper_bound(p); PLASSERT( arena_it != stormap.begin() ); --arena_it; PLASSERT( last_arena == arena_it->second ); stormap.erase(arena_it); arenas.remove(last_arena); last_arena = 0; } } }
bool PLearn::PMemPool::empty | ( | ) | const [inline] |
Return true if no objects remain allocated within the pool.
Definition at line 177 of file PMemPool.h.
References arenas.
Referenced by alloc_from_pool().
{ return arenas.size() == 0; }
PMemArena * PLearn::PMemPool::newArena | ( | ) | [protected] |
Construct a new arena and return it; it is added to arenas and stormap.
Definition at line 186 of file PMemPool.cc.
References arena_growth_factor, arenas, cur_arena_size, object_size, and stormap.
Referenced by allocate().
{ PP<PMemArena> new_arena = new PMemArena(object_size, cur_arena_size); cur_arena_size = size_t(cur_arena_size * arena_growth_factor); stormap[new_arena->storage] = (PMemArena*)new_arena; arenas.push_back(new_arena); return new_arena; }
void PLearn::PMemPool::purge_memory | ( | ) |
Deallocate all memory from the pool.
Definition at line 195 of file PMemPool.cc.
References arenas, cur_arena_size, free_list, initial_arena_size, last_arena, and stormap.
Referenced by PLearn::PythonCodeSnippet::build_(), and PLearn::PythonCodeSnippet::makeDeepCopyFromShallowCopy().
{ arenas.clear(); stormap.clear(); last_arena = 0; free_list = 0; cur_arena_size = initial_arena_size; }
float PLearn::PMemPool::arena_growth_factor [protected] |
by how much to grow cur_arena_size
Definition at line 153 of file PMemPool.h.
Referenced by newArena().
std::list< PP<PMemArena> > PLearn::PMemPool::arenas [protected] |
list of allocated arenas
Definition at line 148 of file PMemPool.h.
Referenced by allocateFromArenas(), deallocate(), empty(), newArena(), and purge_memory().
size_t PLearn::PMemPool::cur_arena_size [protected] |
currently, how many objects per arena
Definition at line 152 of file PMemPool.h.
Referenced by newArena(), and purge_memory().
bool PLearn::PMemPool::fast_deallocate [protected] |
whether to use fast deallocator
Definition at line 155 of file PMemPool.h.
Referenced by deallocate().
void* PLearn::PMemPool::free_list [protected] |
Definition at line 156 of file PMemPool.h.
Referenced by allocate(), deallocate(), and purge_memory().
size_t PLearn::PMemPool::initial_arena_size [protected] |
initially, now many objects per arena
Definition at line 151 of file PMemPool.h.
Referenced by purge_memory().
PMemArena* PLearn::PMemPool::last_arena [protected] |
arena we last allocated from
Definition at line 149 of file PMemPool.h.
Referenced by allocate(), allocateFromArenas(), deallocate(), and purge_memory().
size_t PLearn::PMemPool::object_size [protected] |
map<void*, PMemArena*> PLearn::PMemPool::stormap [protected] |
quick access to arena storage addresses
Definition at line 154 of file PMemPool.h.
Referenced by deallocate(), newArena(), and purge_memory().