PLearn 0.1
Public Member Functions | Protected Member Functions | Protected Attributes
PLearn::PMemPool Class Reference

A PMemPool is a collection of arenas for allocating an arbitrary number of objects of a fixed size. More...

#include <PMemPool.h>

Inheritance diagram for PLearn::PMemPool:
Inheritance graph
[legend]
Collaboration diagram for PLearn::PMemPool:
Collaboration graph
[legend]

List of all members.

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.
PMemArenanewArena ()
 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
PMemArenalast_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

Detailed Description

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.


Constructor & Destructor Documentation

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)
{ }

Member Function Documentation

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();
}

Here is the call graph for this function:

Here is the caller graph for this function:

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;
}

Here is the caller graph for this function:

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;
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

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; }

Here is the caller graph for this function:

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;
}

Here is the caller graph for this function:

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().

Here is the caller graph for this function:


Member Data Documentation

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().

currently, how many objects per arena

Definition at line 152 of file PMemPool.h.

Referenced by newArena(), and purge_memory().

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().

initially, now many objects per arena

Definition at line 151 of file PMemPool.h.

Referenced by purge_memory().

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]

size of each allocated object

Definition at line 150 of file PMemPool.h.

Referenced by newArena().

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().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines