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

blockpool.cpp

Go to the documentation of this file.
00001 
00044  
00045 
00046 #include <assert.h>
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049 
00050 #include "blockpool.h"
00051 
00052 
00053 unsigned int block_pool::alloc_gran = (unsigned int)block_pool::page_size;
00054 block_pool::block_chain *block_pool::current_block = 0;
00055 block_pool::block_chain *block_pool::block_list_start = 0;
00056 
00057 
00058   
00066 void block_pool::init_pool( void )
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 */
00075 
00076 
00077 
00078   
00094 block_pool::block_chain *block_pool::new_block( unsigned int block_size )
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
00131 
00132 
00133 
00141 void *block_pool::add_block( unsigned int block_size )
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
00153 
00154 
00155 
00156 
00171 void *block_pool::pool_alloc( unsigned int num_bytes )
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
00203 
00204 
00205   
00219 void block_pool::free_pool(void)
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
00229 
00230 
00231 
00238 void block_pool::print_block_pool_info( FILE *fp /*= stdout */)
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 }
00262 

Generated at Tue May 27 21:56:16 2003 for Wavelet compression, determinism and time series forecasting by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001