00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 }
00041
00042
00043
00044
00045
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 }
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
00097 total_alloc = block_size + sizeof(block_chain);
00098 if (total_alloc < alloc_gran)
00099 alloc_amt = alloc_gran;
00100 else {
00101
00102
00103 alloc_amt = ((total_alloc + (page_size-1))/page_size) * page_size;
00104 }
00105
00106 if (alloc_amt <= max_block_size) {
00107
00108
00109 new_link = (block_chain *)MemAlloc( alloc_amt );
00110
00111
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 }
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 }
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
00163
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 }
00188
00189
00190
00194 void block_pool::print_block_pool_info( FILE *fp )
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 }
00213 fprintf(fp, "Total allocated = %5d, total unused = %3d\n", total_allocated,
00214 total_unused );
00215 }
00216