Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

block_pool Class Reference

This class supports memory pool allocation. More...

#include <blockpool.h>

List of all members.

Public Types

typedef struct block_pool::block_chain_struct  block_chain
 typedef for memory block chain. More...

enum  bogus { one_kay = 1024, page_size = (4 * one_kay), max_block_multiple = 256, last_enum }
 the largest block of memory that can be allocated is the page_size * max_block_multiple. More...


Public Methods

 block_pool (void)
 constructor does nothing, since all the class variables are static. More...

void free_pool (void)
 block_pool::free_pool. More...

void* pool_alloc (unsigned int block_size)
 pool_alloc. More...

void print_block_pool_info (FILE *fp=stdout)
 print_block_pool_info. More...


Protected Methods

virtual void* MemAlloc (unsigned int n_bytes)
 Allocate memory using calloc. More...

virtual void MemFree (void *addr)
 Free memory that has been allocated with MemAlloc. More...


Private Methods

block_chainnew_block (unsigned int block_size)
 new_block. More...

void* add_block (unsigned int block_size)
 block_pool::add_block Add a new memory block to the memory pool. More...

void init_pool (void)
 block_pool::init_pool. More...


Static Private Attributes

unsigned int alloc_gran = (unsigned int)block_pool::page_size
 allocation granularity. More...

block_chainblock_list_start = 0
 start of the block list for this pool. More...

block_chaincurrent_block = 0
 current block memory is being allocated from. More...


Detailed Description

This class supports memory pool allocation.

A memory pool is allocated in blocks and smaller chunks of memory are allocated from these blocks. Instead of calling a set of class destructors (which is time consuming) the memory pool allows all the objects allocated in the memory pool to be destroyed at once. This provide a sort of "poorman's garbage collector. Deallocating memory in a single place simplifies the software structure, since allocation can be scattered throughout the code without worry about deallocation.

This is a simplified version of a low level memory allocator that can be used to create multiple memory pools. In this class the class variables are static and shared by all instances of the class. This allows the class to be declared locally to allocate memory, but the state remains global. This makes the local instance a window into the global state. The limitation is that only one memory pool can be used.

Originally written November, 1996
Revised for the wavelet packet transform code March 2002

Author:
Ian Kaplan

Definition at line 66 of file blockpool.h.


Member Typedef Documentation

typedef struct block_pool::block_chain_struct block_pool::block_chain
 

typedef for memory block chain.


Member Enumeration Documentation

enum block_pool::bogus
 

the largest block of memory that can be allocated is the page_size * max_block_multiple.

Enumeration values:
one_kay  
page_size  
max_block_multiple  
last_enum  

Definition at line 70 of file blockpool.h.

00070                { one_kay = 1024,
00071                  page_size = (4 * one_kay),  /* 4 Kb */
00072                  max_block_multiple = 256,   /* 1 Mb */
00073                  last_enum
00074                } bogus;


Constructor & Destructor Documentation

block_pool::block_pool ( void ) [inline]
 

constructor does nothing, since all the class variables are static.

Definition at line 145 of file blockpool.h.

00145 {}


Member Function Documentation

void * block_pool::MemAlloc ( unsigned int n_bytes ) [inline, protected, virtual]
 

Allocate memory using calloc.

The POSIX calloc function sets the memory to zero (in contrast to malloc which allocates the memory without initializing it.

      include <stdlib>
      void *calloc( size_t num, size_t size );

The arguments to calloc are:

num: number of elements
size: size of the elements in bytes

The argument to MemAlloc is the size, in bytes to allocate.

Definition at line 128 of file blockpool.h.

Referenced by new_block().

00129   {
00130     void *rtn = calloc( n_bytes, 1 );
00131     return rtn;
00132   }

void block_pool::MemFree ( void * addr ) [inline, protected, virtual]
 

Free memory that has been allocated with MemAlloc.

Definition at line 136 of file blockpool.h.

Referenced by free_pool().

00137   {
00138     free( addr );
00139   }

void * block_pool::add_block ( unsigned int block_size ) [private]
 

block_pool::add_block Add a new memory block to the memory pool.

This function is called when the amount of memory requested by pool_alloc will not fit in the current block.

Definition at line 141 of file blockpool.cpp.

Referenced by pool_alloc().

00142 {
00143   block_chain *block = 0;
00144   block_chain *last_block;
00145 
00146   last_block = current_block;
00147   block = new_block( block_size );
00148   Chain_next(current_block) = block;
00149   current_block = block;
00150 
00151   return (void *)block;
00152 } // block_chain::add_block

void block_pool::free_pool ( void )
 

block_pool::free_pool.

Walk through the block chain and deallocate the blocks. Note that the block chain structures and the allocatible memory is contained within a single allocated block. The block_chain structure is at the start of this block so passing its address to the memory deallocation function deallocates both the block chain structure and the allocatible memory

Definition at line 219 of file blockpool.cpp.

Referenced by main().

00220 {
00221   block_chain *tmp;
00222 
00223   while (block_list_start != 0) {
00224     tmp = block_list_start;
00225     block_list_start = Chain_next(block_list_start);
00226     MemFree( (void *)tmp );
00227   }
00228 } // free_pool

void block_pool::init_pool ( void ) [private]
 

block_pool::init_pool.

This function is automatically called to initialize the block_pool object when the "current_block" pointer is null.

Definition at line 66 of file blockpool.cpp.

Referenced by pool_alloc().

00067 {
00068 
00069   block_chain *new_link;
00070 
00071   new_link = new_block( alloc_gran );
00072   block_list_start = new_link;
00073   current_block = new_link;
00074 } /* init_pool */

block_chain * block_pool::new_block ( unsigned int block_size ) [private]
 

new_block.

The new_block function is the "root" memory allocator for the block_pool object. The amount of memory allocated is rounded up to the next "block_size" boundary. Both the block_chain structure and the allocatible memory are allocated from a single block that is a multiple of the page size. This should avoid fragmentation in the system memory allocator.

The "page" referenced here is a virtual memory page. This version of the code does not actually check the system page size, but assumes a 4Kb page.

Definition at line 94 of file blockpool.cpp.

Referenced by add_block(), and init_pool().

00095 {
00096   const unsigned int max_block_size = max_block_multiple * page_size;
00097   block_chain *new_link = 0;
00098   unsigned int alloc_amt, total_alloc;
00099 
00100   // add in the memory needed for the block_chain structure
00101   total_alloc = block_size + sizeof(block_chain);
00102   if (total_alloc < alloc_gran)
00103       alloc_amt = alloc_gran;
00104   else { 
00105       // its larger than the minimum allocation granularity, so round
00106       // up the the nearest page.
00107       alloc_amt = ((total_alloc + (page_size-1))/page_size) * page_size;
00108   }
00109 
00110   if (alloc_amt <= max_block_size) {
00111 
00112     /* Allocate memory for both the block_chain structure and the memory 
00113        block */
00114     new_link = (block_chain *)MemAlloc( alloc_amt );
00115 
00116     // The new memory block starts after the block_chain structure
00117     Chain_block(new_link) = (void *)(((unsigned int)new_link) + sizeof(block_chain));
00118 
00119     assert( alloc_amt >= block_size );
00120 
00121     Chain_bytes_used(new_link) = 0;
00122     Chain_block_size(new_link) = alloc_amt - sizeof(block_chain);
00123     Chain_next(new_link) = 0;
00124   }
00125   else {
00126     printf("block_pool::new_block: allocation request too large\n");
00127   }
00128 
00129   return new_link;
00130 } // block_chain::new_block

void * block_pool::pool_alloc ( unsigned int block_size )
 

pool_alloc.

Allocate memory from the memory pool. The pool_alloc and free_pool functions do memory allocation and deallocation.

This function is called to allocate memory from the memory pool. If there is enough free memory in the current block to satisify the memory request, memory is allocated from the current block and the amount of free memory is updated. If the current block does not have enough memory, add_block is called to allocate a new memory block which will be large enough.

Definition at line 171 of file blockpool.cpp.

Referenced by queueElem::operator new(), packdata::operator new(), packcontainer_int::operator new(), packcontainer::operator new(), LIST::list_type::operator new(), FIFO_LIST::list_type::operator new(), packcontainer::packcontainer(), packcontainer_int::packcontainer_int(), packfreq::packfreq(), packtree::packtree(), packtree_int::packtree_int(), invpacktree_int::reduce(), invpacktree::reduce(), and testWaveletTrans().

00172 {
00173   const unsigned int align = sizeof( int );
00174   void *addr = 0;
00175   unsigned int amt_free;
00176 
00177   /* the number of bytes allocated must be a multiple of the align
00178      size */
00179   num_bytes = ((num_bytes + (align-1))/align) * align;
00180 
00181   if (current_block == 0) {
00182     init_pool();
00183   }
00184 
00185   amt_free = Chain_block_size(current_block) - Chain_bytes_used(current_block);
00186   
00187   if (num_bytes > amt_free) {
00188     if (add_block( num_bytes ) != 0) {
00189       amt_free = Chain_block_size(current_block);
00190     }
00191   }
00192 
00193   if (amt_free >= num_bytes) {
00194     addr = (void *)((unsigned int)Chain_block(current_block) + Chain_bytes_used(current_block));
00195     Chain_bytes_used(current_block) += num_bytes;
00196   }
00197   else {
00198     printf("block_pool::block_alloc: allocation error\n");
00199     exit(1);
00200   }
00201   return addr;
00202 } // block_pool::pool_alloc

void block_pool::print_block_pool_info ( FILE * fp = stdout )
 

print_block_pool_info.

Print information about the block pool

Definition at line 238 of file blockpool.cpp.

00239 {
00240   int total_allocated = 0;
00241   int total_unused = 0;
00242   block_chain *ptr = block_list_start;
00243 
00244   fprintf(fp, "Minimum memory allocation size: %d\n", alloc_gran );
00245   fprintf(fp, "Page size: %d\n", (unsigned int)page_size );
00246   fprintf(fp, "[block size, bytes_used]\n");
00247   while (ptr != 0) {
00248     fprintf(fp, "[%4d, %4d]", Chain_block_size(ptr), Chain_bytes_used(ptr));
00249     total_allocated += Chain_bytes_used(ptr);
00250     total_unused += (Chain_block_size(ptr) - Chain_bytes_used(ptr));
00251     if (Chain_next(ptr) != 0) {
00252       fprintf(fp, ", ");
00253     }
00254     else {
00255       fprintf(fp, "\n");
00256     }
00257     ptr = Chain_next(ptr);
00258   } // while
00259   fprintf(fp, "Total allocated = %5d, total unused = %3d\n", total_allocated,
00260          total_unused );
00261 }


Member Data Documentation

unsigned int block_pool::alloc_gran = (unsigned int)block_pool::page_size [static, private]
 

allocation granularity.

Definition at line 93 of file blockpool.h.

block_chain * block_pool::block_list_start = 0 [static, private]
 

start of the block list for this pool.

Definition at line 96 of file blockpool.h.

block_chain * block_pool::current_block = 0 [static, private]
 

current block memory is being allocated from.

Definition at line 99 of file blockpool.h.


The documentation for this class was generated from the following files:
Generated at Sat Aug 10 13:23:36 2002 for Wavelet Packet Transform and Lossless Compression by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001