ccutil/memry.cpp

Go to the documentation of this file.
00001 
00020 #include          "mfcpch.h"
00021 #include          <stdlib.h>
00022 #ifdef __UNIX__
00023 #include          <assert.h>
00024 #endif
00025 #include          "stderr.h"
00026 #include          "tprintf.h"
00027 #include          "memblk.h"
00028 #include          "memry.h"
00029 
00030 //#define COUNTING_CLASS_STRUCTURES
00031 
00032 /*
00033 Replace global new to get at memory leaks etc.
00034 */
00035 /*
00036 void*                operator new(           //allocate memory
00037 size_t                  size                 //amount to allocate
00038 )
00039 {
00040   if (size==0)
00041   {
00042     err.log(RESULT_LOGICAL_ERROR,E_LOC,ERR_PRIMITIVES,
00043       ERR_SCROLLING,ERR_CONTINUE,ERR_ERROR,
00044       "Zero requested of new");
00045     size=1;
00046   }
00047   return alloc_big_mem(size);
00048 }
00049 
00050 void                 operator delete(        //free memory
00051 void*                addr                 //mem to free
00052 )
00053 {
00054   free_big_mem(addr);
00055 }*/
00056 
00060 DLLSYM void check_mem(                     //check consistency
00061                       const char *string,  //context message
00062                       INT8 level           //level of check
00063                      ) {
00064   big_mem.check (string, level);
00065   main_mem.check (string, level);
00066   check_structs(level);
00067 }
00068 
00069 
00083 DLLSYM char *alloc_string(             //allocate string
00084                           INT32 count  //no of chars required
00085                          ) {
00086 #ifdef RAYS_MALLOC
00087   char *string;                  //allocated string
00088 
00089   if (count < 1 || count > MAX_CHUNK) {
00090     tprintf ("Invalid size %d requested of alloc_string", count);
00091     return NULL;
00092   }
00093 
00094   count++;                       //add size byte
00095   if (count <= MAX_STRUCTS * sizeof (MEMUNION)) {
00096     string = (char *) alloc_struct (count, "alloc_string");
00097     //get a fast structure
00098     if (string == NULL) {
00099       tprintf ("No memory for alloc_string");
00100       return NULL;
00101     }
00102     string[0] = (INT8) count;    //save its length
00103   }
00104   else {
00105                                  //get a big block
00106     string = (char *) alloc_mem (count);
00107     if (string == NULL) {
00108       tprintf ("No memory for alloc_string");
00109       return NULL;
00110     }
00111     string[0] = 0;               //mark its id
00112   }
00113   return &string[1];             //string for user
00114 #else
00115   return static_cast<char*>(malloc(count));
00116 #endif
00117 }
00118 
00119 
00123 DLLSYM void free_string(              //free a string
00124                         char *string  //string to free
00125                        ) {
00126 #ifdef RAYS_MALLOC
00127   if (((ptrdiff_t) string & 3) == 1) { //one over word
00128     string--;                    //get id marker
00129     if (*string == 0) {
00130       free_mem(string);  //generally free it
00131       return;
00132     }
00133     else if (*string <= MAX_STRUCTS * sizeof (MEMUNION)) {
00134                                  //free structure
00135       free_struct (string, *string, "alloc_string");
00136       return;
00137     }
00138   }
00139   tprintf ("Non-string given to free_string");
00140 #else
00141   free(string);
00142 #endif
00143 }
00144 
00145 
00157 DLLSYM void *
00158 alloc_struct (                   //allocate memory
00159 INT32 count,                     //no of chars required
00160 #if defined COUNTING_CLASS_STRUCTURES
00161 const char *name                 //name of type
00162 #else
00163 const char *                     //name of type
00164 #endif
00165 ) {
00166 #ifdef RAYS_MALLOC
00167   MEMUNION *element;             //current element
00168   MEMUNION *returnelement;       //return value
00169   INT32 struct_count;            //no of required structs
00170   INT32 blocksize;               //no of structs in block
00171   INT32 index;                   //index to structure
00172 
00173   if (count < 1 || count > MAX_CHUNK) {
00174     tprintf ("Invalid size %d requested of alloc_struct", count);
00175     return NULL;
00176   }
00177 
00178   //      tprintf("Allocating structure of size %d\n",count);
00179                                  //no of MEMUNIONS-1
00180   struct_count = (count - 1) / sizeof (MEMUNION);
00181   if (struct_count < MAX_STRUCTS) {
00182                                  //can do fixed sizes
00183     #ifdef COUNTING_CLASS_STRUCTURES
00184     if (name != NULL) {
00185       index = identify_struct_owner (struct_count, name);
00186       if (index < MAX_CLASSES)
00187         owner_counts[struct_count][index]++;
00188     }
00189     #endif
00190                                  //head of freelist
00191     returnelement = free_structs[struct_count];
00192     if (returnelement == NULL) {
00193                                  //need a new block
00194                                  //get one
00195       element = (MEMUNION *) new_struct_block ();
00196       if (element == NULL) {
00197         tprintf ("No memory to satisfy request for %d", (int) count);
00198         return NULL;
00199       }
00200                                  //add to block list
00201       element->ptr = struct_blocks[struct_count];
00202       struct_blocks[struct_count] = element;
00203       blocks_in_use[struct_count]++;
00204       element++;                 //free cell
00205       returnelement = element;   //going to return 1st
00206       blocksize = STRUCT_BLOCK_SIZE / (struct_count + 1) - 1;
00207 
00208       for (index = 1; index < blocksize; index++) {
00209                                  //make links
00210         element->ptr = element + struct_count + 1;
00211         element += struct_count + 1;
00212       }
00213       element->ptr = NULL;       //end of freelist
00214     }
00215                                  //new free one
00216     free_structs[struct_count] = returnelement->ptr;
00217                                  //count number issued
00218     structs_in_use[struct_count]++;
00219   }
00220   else {
00221                                  //just get some
00222     returnelement = (MEMUNION *) alloc_mem (count);
00223     if (returnelement == NULL) {
00224       tprintf ("No memory to satisfy request for %d", (int) count);
00225       return NULL;
00226     }
00227   }
00228   return returnelement;          //free cell
00229 #else
00230   return malloc(count);
00231 #endif
00232 }
00233 
00234 
00238 DLLSYM void
00239 free_struct (                    //free a structure
00240 void *deadstruct,                //structure to free
00241 INT32 count,                     //no of bytes
00242 #if defined COUNTING_CLASS_STRUCTURES
00243 const char *name                 //name of type
00244 #else
00245 const char *                     //name of type
00246 #endif
00247 ) {
00248 #ifdef RAYS_MALLOC
00249   MEMUNION *end_element;         //current element
00250   MEMUNION *element;             //current element
00251   MEMUNION *prev_element;        //previous element
00252   MEMUNION *prev_block;          //previous element
00253   MEMUNION *nextblock;           //next block in list
00254   MEMUNION *block;               //next block in list
00255   INT32 struct_count;            //no of required structs
00256   INT32 index;                   //to structure counts
00257 
00258   if (count < 1 || count > MAX_CHUNK) {
00259     tprintf ("Invalid size %d requested of free_struct", count);
00260     return;
00261   }
00262 
00263   //      tprintf("Freeing structure of size %d\n",count);
00264                                  //no of MEMUNIONS-1
00265   struct_count = (count - 1) / sizeof (MEMUNION);
00266 
00267   if (deadstruct == NULL) {
00268                                  //not really legal
00269     check_struct(MEMCHECKS, count);
00270   }
00271   else {
00272     if (struct_count < MAX_STRUCTS) {
00273                                  //can do fixed sizes
00274       #ifdef COUNTING_CLASS_STRUCTURES
00275       if (name != NULL) {
00276         index = identify_struct_owner (struct_count, name);
00277         if (index < MAX_CLASSES) {
00278           owner_counts[struct_count][index]--;
00279           ASSERT_HOST (owner_counts[struct_count][index] >= 0);
00280         }
00281       }
00282       #endif
00283       element = (MEMUNION *) deadstruct;
00284                                  //add to freelist
00285       element->ptr = free_structs[struct_count];
00286       free_structs[struct_count] = element;
00287                                  //one less in use
00288       structs_in_use[struct_count]--;
00289       if (structs_in_use[struct_count] == 0) {
00290         index = 0;
00291         for (element = struct_blocks[struct_count];
00292         element != NULL; element = nextblock) {
00293                                  //traverse and destroy
00294           nextblock = element->ptr;
00295                                  //free all the blocks
00296           old_struct_block(element);
00297           index++;
00298         }
00299                                  //none left any more
00300         struct_blocks[struct_count] = NULL;
00301                                  //no free structs
00302         free_structs[struct_count] = NULL;
00303         blocks_in_use[struct_count] = 0;
00304       }
00305       else if (structs_in_use[struct_count] < 0) {
00306         tprintf ("Negative number of structs of size %d in use",
00307           (int) count);
00308       }
00309       else if (structs_in_use[struct_count] < blocks_in_use[struct_count]) {
00310         prev_block = NULL;
00311         for (block = struct_blocks[struct_count];
00312         block != NULL; block = nextblock) {
00313           nextblock = block;
00314           index = STRUCT_BLOCK_SIZE / (struct_count + 1) - 1;
00315           end_element = block + STRUCT_BLOCK_SIZE;
00316           for (element = free_structs[struct_count];
00317           element != NULL; element = element->ptr) {
00318             if (element > nextblock && element < end_element) {
00319               index--;
00320               if (index == 0)
00321                 break;
00322             }
00323           }
00324           if (index == 0) {
00325             index = STRUCT_BLOCK_SIZE / (struct_count + 1) - 1;
00326             for (element =
00327               free_structs[struct_count], prev_element = NULL;
00328             element != NULL; element = element->ptr) {
00329               if (element > nextblock && element < end_element) {
00330                 index--;
00331                 if (prev_element != NULL)
00332                   prev_element->ptr = element->ptr;
00333                 else
00334                   free_structs[struct_count] = element->ptr;
00335                 if (index == 0)
00336                   break;
00337               }
00338               else
00339                 prev_element = element;
00340             }
00341             if (prev_block != NULL)
00342               prev_block->ptr = block->ptr;
00343             else
00344               struct_blocks[struct_count] = block->ptr;
00345             nextblock = block->ptr;
00346             blocks_in_use[struct_count]--;
00347                                  //free all the blocks
00348             old_struct_block(block);
00349           }
00350           else {
00351             prev_block = block;
00352                                  //traverse and destroy
00353             nextblock = block->ptr;
00354           }
00355         }
00356       }
00357     }
00358     else
00359       free_mem(deadstruct);  //free directly
00360   }
00361 #else
00362   free(deadstruct);
00363 #endif // RAYS_MALLOC
00364 }
00365 
00366 
00367 //#ifdef __UNIX__
00368 //#pragma OPT_LEVEL 0
00369 //#endif
00370 
00378 DLLSYM void *alloc_mem_p(             //allocate permanent space
00379                          INT32 count  //block size to allocate
00380                         ) {
00381   #ifdef RAYS_MALLOC
00382   #ifdef TESTING_BIGSTUFF
00383   if (main_mem.biggestblock == 0)
00384     main_mem.init (alloc_big_mem, free_big_mem,
00385       FIRSTSIZE, LASTSIZE, MAX_CHUNK);
00386   #else
00387   if (main_mem.biggestblock == 0)
00388     main_mem.init ((void *(*)(INT32)) malloc, free,
00389       FIRSTSIZE, LASTSIZE, MAX_CHUNK);
00390   #endif
00391   if (mem_mallocdepth > 0)
00392     return main_mem.alloc_p (count, trace_caller (mem_mallocdepth));
00393   else
00394     return main_mem.alloc_p (count, NULL);
00395   #else
00396   return malloc ((size_t) count);
00397   #endif
00398 }
00399 
00400 
00404 DLLSYM void *alloc_mem(             //get some memory
00405                        INT32 count  //no of bytes to get
00406                       ) {
00407   #ifdef RAYS_MALLOC
00408   #ifdef TESTING_BIGSTUFF
00409   if (main_mem.biggestblock == 0)
00410     main_mem.init (alloc_big_mem, free_big_mem,
00411       FIRSTSIZE, LASTSIZE, MAX_CHUNK);
00412   #else
00413   if (main_mem.biggestblock == 0)
00414     main_mem.init ((void *(*)(INT32)) malloc, free,
00415       FIRSTSIZE, LASTSIZE, MAX_CHUNK);
00416   #endif
00417   if (mem_mallocdepth > 0)
00418     return main_mem.alloc (count, trace_caller (mem_mallocdepth));
00419   else
00420     return main_mem.alloc (count, NULL);
00421   #else
00422   return malloc ((size_t) count);
00423   #endif
00424 }
00425 
00426 
00430 DLLSYM void *alloc_big_mem(             //get some memory
00431                            INT32 count  //no of bytes to get
00432                           ) {
00433   #ifdef TESTING_BIGSTUFF
00434   if (big_mem.biggestblock == 0)
00435     big_mem.init ((void *(*)(INT32)) malloc, free,
00436       BIGSIZE, BIGSIZE, MAX_BIGCHUNK);
00437   if (mem_mallocdepth > 0)
00438     return big_mem.alloc (count, trace_caller (mem_mallocdepth));
00439   else
00440     return big_mem.alloc (count, NULL);
00441   #else
00442   return malloc ((size_t) count);
00443   #endif
00444 }
00445 
00446 
00450 DLLSYM void *alloc_big_zeros(             //get some memory
00451                              INT32 count  //no of bytes to get
00452                             ) {
00453   #ifdef TESTING_BIGSTUFF
00454   if (big_mem.biggestblock == 0)
00455     big_mem.init ((void *(*)(INT32)) malloc, free,
00456       BIGSIZE, BIGSIZE, MAX_BIGCHUNK);
00457   void *buf;                     //return value
00458 
00459   if (mem_mallocdepth > 0)
00460     buf = big_mem.alloc (count, trace_caller (mem_mallocdepth));
00461   else
00462     buf = big_mem.alloc (count, NULL);
00463   memset (buf, 0, count);
00464   return buf;
00465   #else
00466   return calloc ((size_t) count, 1);
00467   #endif
00468 }
00469 
00470 
00477 DLLSYM void free_mem(                //free mem from alloc_mem
00478                      void *oldchunk  //chunk to free
00479                     ) {
00480   #ifdef RAYS_MALLOC
00481   if (mem_freedepth > 0 && main_mem.callers != NULL)
00482     main_mem.dealloc (oldchunk, trace_caller (mem_freedepth));
00483   else
00484     main_mem.dealloc (oldchunk, NULL);
00485   #else
00486   free(oldchunk);
00487   #endif
00488 }
00489 
00490 
00497 DLLSYM void free_big_mem(                //free mem from alloc_mem
00498                          void *oldchunk  //chunk to free
00499                         ) {
00500   #ifdef TESTING_BIGSTUFF
00501   if (mem_freedepth > 0 && main_mem.callers != NULL)
00502     big_mem.dealloc (oldchunk, trace_caller (mem_freedepth));
00503   else
00504     big_mem.dealloc (oldchunk, NULL);
00505   #else
00506   free(oldchunk);
00507   #endif
00508 }

Generated on Wed Feb 28 19:49:09 2007 for Tesseract by  doxygen 1.5.1