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

blockpool.C

Go to the documentation of this file.
00001 
00012 /*===============================<o>=====================================
00013 
00014 Copyright 1996, 1997, 2004 Ian Kaplan, Bear Products International,
00015 www.bearcave.com.
00016 
00017 All Rights Reserved
00018 
00019 You may use this software in software components for which you do
00020 not collect money (e.g., non-commercial software).  All commercial
00021 use is reserved.
00022 
00023 ===============================<o>=====================================*/
00024  
00025 
00026 #include <assert.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include "stdtypes.h"
00030 #include "blockpool.h"
00031 
00032 
00033 block_pool::block_pool(void)
00034 {
00035   
00036   page_size = 0;
00037   alloc_gran = 0;
00038   current_block = NULL;
00039   block_list_start = NULL;
00040 } // block_pool constructor
00041 
00042 
00043 /*
00044    This function is automatically called to initialize the block_pool
00045    object when the "current_block" pointer is NULL.
00046 */
00047 void block_pool::init_pool( void )
00048 {
00049 
00050   block_chain *new_link;
00051 
00052   getinfo(page_size, alloc_gran);
00053 
00054   new_link = new_block( alloc_gran );
00055   block_list_start = new_link;
00056   current_block = new_link;
00057 } /* init_pool */
00058 
00059 
00060 
00070 void block_pool::free_pool(void)
00071 {
00072   block_chain *tmp;
00073 
00074   while (block_list_start != NULL) {
00075     tmp = block_list_start;
00076     block_list_start = Chain_next(block_list_start);
00077     MemFree( (void *)tmp );
00078   }
00079 }
00080 
00081 
00090 block_pool::blk_chain *block_pool::new_block( unsigned int block_size )
00091 {
00092   const unsigned int max_block_size = max_block_multiple * page_size;
00093   block_chain *new_link = NULL;
00094   unsigned int alloc_amt, total_alloc;
00095 
00096   // add in the memory needed for the block_chain structure
00097   total_alloc = block_size + sizeof(block_chain);
00098   if (total_alloc < alloc_gran)
00099       alloc_amt = alloc_gran;
00100   else { 
00101       // its larger than the allocation granularity, so round
00102       // up the the nearest page.
00103       alloc_amt = ((total_alloc + (page_size-1))/page_size) * page_size;
00104   }
00105 
00106   if (alloc_amt <= max_block_size) {
00107 
00108     /* allocate memory for both the block_chain structure and the memory block */
00109     new_link = (block_chain *)MemAlloc( alloc_amt );
00110 
00111     // The new memory block starts after the block_chain structure
00112     Chain_block(new_link) = (void *)(((unsigned int)new_link) + sizeof(block_chain));
00113 
00114     assert( alloc_amt >= block_size );
00115 
00116     Chain_bytes_used(new_link) = 0;
00117     Chain_block_size(new_link) = alloc_amt - sizeof(block_chain);
00118     Chain_next(new_link) = NULL;
00119   }
00120   else {
00121     printf("block_pool::new_block: allocation request too large\n");
00122   }
00123 
00124   return new_link;
00125 } // block_chain::new_block
00126 
00127 
00128 
00133 void *block_pool::add_block( unsigned int block_size )
00134 {
00135   block_chain *block = NULL;
00136   block_chain *last_block;
00137 
00138   last_block = current_block;
00139   block = new_block( block_size );
00140   Chain_next(current_block) = block;
00141   current_block = block;
00142 
00143   return (void *)block;
00144 } // block_chain::add_block
00145 
00146 
00147 
00148 
00156 void *block_pool::pool_alloc( unsigned int num_bytes )
00157 {
00158   const unsigned int align = sizeof( int );
00159   void *addr = NULL;
00160   unsigned int amt_free;
00161 
00162   /* the number of bytes allocated must be a multiple of the align
00163      size */
00164   num_bytes = ((num_bytes + (align-1))/align) * align;
00165 
00166   if (current_block == NULL) {
00167     init_pool();
00168   }
00169 
00170   amt_free = Chain_block_size(current_block) - Chain_bytes_used(current_block);
00171   
00172   if (num_bytes > amt_free) {
00173     if (add_block( num_bytes ) != NULL) {
00174       amt_free = Chain_block_size(current_block);
00175     }
00176   }
00177 
00178   if (amt_free >= num_bytes) {
00179     addr = (void *)((unsigned int)Chain_block(current_block) + Chain_bytes_used(current_block));
00180     Chain_bytes_used(current_block) += num_bytes;
00181   }
00182   else {
00183     printf("block_pool::block_alloc: allocation error\n");
00184     exit(1);
00185   }
00186   return addr;
00187 } // block_pool::pool_alloc
00188 
00189 
00190 
00194 void block_pool::print_block_pool_info( FILE *fp /*= stdout */)
00195 {
00196   int total_allocated = 0;
00197   int total_unused = 0;
00198   block_chain *ptr = block_list_start;
00199 
00200   fprintf(fp, "[block size, bytes_used]\n");
00201   while (ptr != NULL) {
00202     fprintf(fp, "[%4d, %4d]", Chain_block_size(ptr), Chain_bytes_used(ptr));
00203     total_allocated += Chain_bytes_used(ptr);
00204     total_unused += (Chain_block_size(ptr) - Chain_bytes_used(ptr));
00205     if (Chain_next(ptr) != NULL) {
00206       fprintf(fp, ", ");
00207     }
00208     else {
00209       fprintf(fp, "\n");
00210     }
00211     ptr = Chain_next(ptr);
00212   } // while
00213   fprintf(fp, "Total allocated = %5d, total unused = %3d\n", total_allocated,
00214          total_unused );
00215 }
00216 

Generated on Wed Mar 31 21:15:55 2004 for Data Structures for a VHDL Compiler by doxygen 1.3.3