00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <cstring>
00029 #include <string.h>
00030 #include <cstdlib>
00031 #include <stdlib.h>
00032 #include <iostream>
00033 #include <ostream>
00034 #include <cassert>
00035 #include "mempool.h"
00036
00037 using namespace std;
00038
00039 #ifdef TRACE_ENABLE
00040 #define TRACE_ERR(str) { std::cerr << str; }
00041 #else
00042 #define TRACE_ERR(str) { }
00043 #endif
00044
00051 mempool::mempool(int is, int bs){
00052
00053
00054
00055
00056 is=(is>(int)sizeof(char *)?is:0);
00057
00058 is=is + sizeof(char *) - (is % sizeof(char *));
00059
00060 item_size = is;
00061
00062 block_size = bs;
00063
00064 true_size = is * bs;
00065
00066 block_list = new memnode;
00067
00068 block_list->block = new char[true_size];
00069
00070 memset(block_list->block,'0',true_size);
00071
00072 block_list->next = 0;
00073
00074 blocknum = 1;
00075
00076 entries = 0;
00077
00078
00079
00080 char *ptr = free_list = block_list->block;
00081
00082 for (int i=0;i<block_size-1;i++) {
00083 *(char **)ptr= ptr + item_size;
00084 ptr+=item_size;
00085 }
00086 *(char **)ptr = NULL;
00087
00088 }
00089
00090
00091 char * mempool::allocate(){
00092
00093 char *ptr;
00094
00095 if (free_list==NULL)
00096 {
00097 memnode *new_block = new memnode;
00098
00099 new_block->block = new char[true_size];
00100
00101
00102
00103 new_block->next = block_list;
00104
00105 block_list=new_block;
00106
00107
00108
00109 ptr = free_list = block_list->block;
00110
00111 for (int i=0;i<block_size-1;i++) {
00112 *(char **)ptr = ptr + item_size;
00113 ptr = ptr + item_size;
00114 }
00115
00116 *(char **)ptr=NULL;
00117
00118 blocknum++;
00119 }
00120
00121 assert(free_list);
00122
00123 ptr = free_list;
00124
00125 free_list=*(char **)ptr;
00126
00127 *(char **)ptr=NULL;
00128
00129 entries++;
00130
00131 return ptr;
00132
00133 }
00134
00135
00136 int mempool::free(char* addr){
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 *(char **)addr=free_list;
00154 free_list=addr;
00155
00156 entries--;
00157
00158 return 1;
00159 }
00160
00161
00162 mempool::~mempool()
00163 {
00164 memnode *ptr;
00165
00166 while (block_list !=NULL){
00167 ptr=block_list->next;
00168 delete [] block_list->block;
00169 delete block_list;
00170 block_list=ptr;
00171 }
00172
00173 }
00174
00175 void mempool::map (ostream& co){
00176
00177 co << "mempool memory map:\n";
00178
00179
00180 memnode *bl=block_list;
00181 char *fl=free_list;
00182
00183 char* img=new char[block_size+1];
00184 img[block_size]='\0';
00185
00186 while (bl !=NULL){
00187
00188 memset(img,'#',block_size);
00189
00190 fl=free_list;
00191 while (fl != NULL){
00192 if ((fl >= bl->block)
00193 &&
00194 (fl < bl->block + true_size))
00195 {
00196 img[(fl-bl->block)/item_size]='-';
00197 }
00198
00199 fl=*(char **)fl;
00200 }
00201
00202 co << img << "\n";
00203 bl=bl->next;
00204 }
00205 delete [] img;
00206 }
00207
00208 void mempool::stat(){
00209
00210 TRACE_ERR("mempool class statistics\n"
00211 << "entries " << entries
00212 << " blocks " << blocknum
00213 << " used memory " << (blocknum * true_size)/1024 << " Kb\n");
00214 }
00215
00216
00217
00218 strstack::strstack(int bs){
00219
00220 size=bs;
00221 list=new memnode;
00222
00223 list->block=new char[size];
00224
00225 list->next=0;
00226
00227 memset(list->block,'\0',size);
00228 idx=0;
00229
00230 waste=0;
00231 memory=size;
00232 entries=0;
00233 blocknum=1;
00234
00235 }
00236
00237
00238 void strstack::stat(){
00239
00240 TRACE_ERR("strstack class statistics\n"
00241 << "entries " << entries
00242 << " blocks " << blocknum
00243 << " used memory " << memory/1024 << " Kb\n");
00244 }
00245
00246
00247 const char *strstack::push(const char *s){
00248 int len=strlen(s);
00249
00250 if ((len+1) >= size){
00251 cerr << "strstack::push string is too long\n";
00252 exit(1);
00253 };
00254
00255 if ((idx+len+1) >= size){
00256
00257
00258
00259
00260
00261 waste+=size-idx;
00262 blocknum++;
00263 memory+=size;
00264
00265 memnode* nd=new memnode;
00266 nd->block=new char[size];
00267 nd->next=list;
00268
00269 list=nd;
00270
00271 memset(list->block,'\0',size);
00272
00273 idx=0;
00274
00275 }
00276
00277
00278
00279 strcpy(&list->block[idx],s);
00280
00281 idx+=len+1;
00282
00283 entries++;
00284
00285 return &list->block[idx-len-1];
00286
00287 }
00288
00289
00290 const char *strstack::pop(){
00291
00292 if (list==0) return 0;
00293
00294 if (idx==0){
00295
00296
00297
00298 memnode *ptr=list->next;
00299
00300 delete [] list->block;
00301 delete list;
00302
00303 list=ptr;
00304
00305 if (list==0)
00306 return 0;
00307 else
00308 idx=size-1;
00309 }
00310
00311
00312 while (idx>0)
00313 if (list->block[idx--]!='\0')
00314 break;
00315
00316
00317 while (idx>0)
00318 if (list->block[idx--]=='\0')
00319 break;
00320
00321 entries--;
00322
00323 if (list->block[idx+1]=='\0')
00324 {
00325 idx+=2;
00326 memset(&list->block[idx],'\0',size-idx);
00327 return &list->block[idx];
00328 }
00329 else{
00330 idx=0;
00331 memset(&list->block[idx],'\0',size);
00332 return &list->block[0];
00333 }
00334 }
00335
00336
00337 const char *strstack::top(){
00338
00339 int tidx=idx;
00340 memnode *tlist=list;
00341
00342 if (tlist==0) return 0;
00343
00344 if (idx==0){
00345
00346 tlist=tlist->next;
00347
00348 if (tlist==0) return 0;
00349
00350 tidx=size-1;
00351 }
00352
00353
00354 while (tidx>0)
00355 if (tlist->block[tidx--]!='\0')
00356 break;
00357
00358
00359
00360
00361 while (tidx>0)
00362 if (tlist->block[tidx--]=='\0')
00363 break;
00364
00365 if (tlist->block[tidx+1]=='\0')
00366 {
00367 tidx+=2;
00368 return &tlist->block[tidx];
00369 }
00370 else{
00371 tidx=0;
00372 return &tlist->block[0];
00373 }
00374
00375 }
00376
00377
00378 strstack::~strstack(){
00379 memnode *ptr;
00380 while (list !=NULL){
00381 ptr=list->next;
00382 delete [] list->block;
00383 delete list;
00384 list=ptr;
00385 }
00386 }
00387
00388
00389 storage::storage(int maxsize,int blocksize)
00390 {
00391 newmemory=0;
00392 newcalls=0;
00393 setsize=maxsize;
00394 poolsize=blocksize;
00395 poolset=new mempool* [setsize+1];
00396 for (int i=0;i<=setsize;i++)
00397 poolset[i]=NULL;
00398 }
00399
00400
00401 storage::~storage(){
00402 for (int i=0;i<=setsize;i++)
00403 if (poolset[i])
00404 delete poolset[i];
00405 delete [] poolset;
00406 }
00407
00408 char *storage::allocate(int size){
00409
00410 if (size<=setsize){
00411 if (!poolset[size]){
00412 poolset[size]=new mempool(size,poolsize/size);
00413 }
00414 return poolset[size]->allocate();
00415 }
00416 else{
00417
00418 newmemory+=size+8;
00419 newcalls++;
00420 char* p=(char *)calloc(sizeof(char),size);
00421 if (p==NULL){
00422 cerr << "storage::alloc insufficient memory\n";
00423 exit(1);
00424 }
00425 return p;
00426 }
00427 }
00428
00429 char *storage::reallocate(char *oldptr,int oldsize,int newsize){
00430
00431 char *newptr;
00432
00433 assert(newsize>oldsize);
00434
00435 if (oldsize<=setsize){
00436 if (newsize<=setsize){
00437 if (!poolset[newsize])
00438 poolset[newsize]=new mempool(newsize,poolsize/newsize);
00439 newptr=poolset[newsize]->allocate();
00440 memset((char*)newptr,0,newsize);
00441 }
00442 else
00443 newptr=(char *)calloc(sizeof(char),newsize);
00444
00445 if (oldptr && oldsize){
00446 memcpy(newptr,oldptr,oldsize);
00447 poolset[oldsize]->free(oldptr);
00448 }
00449 }
00450 else{
00451 newptr=(char *)realloc(oldptr,newsize);
00452 if (newptr==oldptr)
00453 cerr << "r\b";
00454 else
00455 cerr << "a\b";
00456 }
00457 if (newptr==NULL){
00458 cerr << "storage::realloc insufficient memory\n";
00459 exit(1);
00460 }
00461
00462 return newptr;
00463 }
00464
00465 int storage::free(char *addr,int size){
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 if (size>setsize)
00476 return free(addr),1;
00477 else{
00478 poolset[size] && poolset[size]->free(addr);
00479 }
00480 return 1;
00481 }
00482
00483
00484 void storage::stat(){
00485 int used=0;
00486 int memory=sizeof(char *) * setsize;
00487 int waste=0;
00488
00489 for (int i=0;i<=setsize;i++)
00490 if (poolset[i]){
00491 used++;
00492 memory+=poolset[i]->used();
00493 waste+=poolset[i]->wasted();
00494 }
00495
00496 TRACE_ERR("storage class statistics\n"
00497 << "alloc entries " << newcalls
00498 << " used memory " << newmemory/1024 << "Kb\n"
00499 << "mpools " << setsize
00500 << " active " << used
00501 << " used memory " << memory/1024 << "Kb"
00502 << " wasted " << waste/1024 << "Kb\n");
00503 }
00504