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 }
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
00101 total_alloc = block_size + sizeof(block_chain);
00102 if (total_alloc < alloc_gran)
00103 alloc_amt = alloc_gran;
00104 else {
00105
00106
00107 alloc_amt = ((total_alloc + (page_size-1))/page_size) * page_size;
00108 }
00109
00110 if (alloc_amt <= max_block_size) {
00111
00112
00113
00114 new_link = (block_chain *)MemAlloc( alloc_amt );
00115
00116
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 }
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 }
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
00178
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 }
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 }
00229
00230
00231
00238 void block_pool::print_block_pool_info( FILE *fp )
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 }
00259 fprintf(fp, "Total allocated = %5d, total unused = %3d\n", total_allocated,
00260 total_unused );
00261 }
00262