home *** CD-ROM | disk | FTP | other *** search
/ gdead.berkeley.edu / gdead.berkeley.edu.tar / gdead.berkeley.edu / pub / cad-tools / ciftomann.tar / CD / nmalloc.c < prev    next >
C/C++ Source or Header  |  1988-01-28  |  6KB  |  200 lines

  1. /*
  2.  * nmalloc.c
  3.  *
  4.  * Copyright -C- 1981 Peter P. Moore
  5.  * sccsid "%W%  %G%"
  6.  *
  7.  *  A new malloc/free package for virtual memory machines. 
  8.  *
  9.  *        A seperate freelist is kept for each object of size 
  10.  *  sizeof(NM_ALIGN) to NM_MAX_INDEX*sizeof(NM_ALIGN), where NM_ALIGN is
  11.  *  the smallest-sized type having the most stringent alignment 
  12.  *  requirement on the particular machine. ( i.e. an int on the VAX ). 
  13.  *  Any objects larger than NM_MAX_INDEX*sizeof(NM_ALIGN) is allocated
  14.  *  and free'd by using the old malloc and free respectively. The space
  15.  *  is allocated in blocks of size BLOCK_SIZE, but this can be changed
  16.  *  by calling nm_set_block_size(new_size). The relevant routines are :
  17.  *
  18.  *        nm_malloc(size) : same syntax and usage as the old malloc.
  19.  *
  20.  *        nm_free(ptr, size) : free the object pointed to by ptr and
  21.  *                 of size 'size'.
  22.  *        
  23.  *        In order to allow compatibility with the old malloc and free
  24.  *  three macros are defined in nmalloc.h : malloc(size), free(ptr), and
  25.  *  alloc(type). Malloc and free are the same as of old, alloc returns 
  26.  *  a properly cast pointer to an object of type 'type' ( i.e. it will
  27.  *  keep lint quiet ). So to replace the old malloc/free, simply put
  28.  *  #include "nmalloc.h" in any file that does malloc or free and 
  29.  *  recompile with nmalloc.o.
  30.  *
  31.  *    Keep the following dire warnings in mind :
  32.  *
  33.  *        You may use the old and new mallocs in the same program,
  34.  *        but DO NOT use my free on something the old malloc allocated
  35.  *        or vice-versa.
  36.  *
  37.  *        If you use the free(ptr) macro, sizeof(*ptr) better be
  38.  *        the same as the size you used in the malloc, i.e. 
  39.  *            
  40.  *            int *ptr;
  41.  *            ptr = (int *)malloc(40);
  42.  *            free(ptr);
  43.  *
  44.  *        will cause the allocated object of size 40 to be placed
  45.  *        in the freelist for objects of size 4 ( sizeof(int) = 4 
  46.  *        on a VAX). This could cause extreme difficulties. You
  47.  *        don`t have to worry about this if all your allocations
  48.  *        are of the form :
  49.  *        
  50.  *            thing *ptr;
  51.  *            ptr = (thing *) malloc(sizeof(thing))
  52.  *            (* usage of ptr *)
  53.  *            free(ptr);
  54.  *
  55.  *        or better yet :
  56.  *            
  57.  *            thing *ptr;
  58.  *            ptr = alloc(thing);
  59.  *            (* usage of pointers *)
  60.  *            free(ptr);
  61.  *
  62.  *        But if you are doing a lot of type casting of pointers or 
  63.  *        other jockish things, then explicit use of nm_free(ptr,size)
  64.  *        is suggested.
  65.  *
  66.  *
  67.  *    The *( (char **) ptr) constructs are used to recast portions
  68.  *    of the objects as linking pointers to chain them to the 
  69.  *    freelist.
  70.  *
  71.  *
  72.  *     KIC is an graphics editor that was developed by the integrated
  73.  * circuits group of the Electronics Research Laboratory and the
  74.  * Department of Electrical Engineering and Computer Sciences at
  75.  * the University of California, Berkeley, California.  The program
  76.  * KIC is available free of charge to any interested party.
  77.  * The sale, resale, or use of this program for profit without the
  78.  * express written consent of the Department of Electrical Engineering
  79.  * and Computer Sciences, University of California, Berkeley, California,
  80.  * is forbidden.
  81.  */
  82.  
  83. #define NM_MAX_INDEX 20        /* see above description */
  84. #define NM_ALIGN int        /* see above description */
  85. #define BLOCK_SIZE 2048        /* the amount of space requested in
  86.                    each block allocation */
  87.  
  88. #define nm_align(size)\
  89.     /* round size to next largest multiple of sizeof(NM_ALIGN) */\
  90.     (( int )(( (int) size + sizeof(NM_ALIGN) - 1)/sizeof(NM_ALIGN)))
  91.  
  92. #ifndef vms
  93. char *sbrk();
  94. #endif
  95.  
  96. char *malloc();
  97. char *nm_slow_alloc(), *nm_block_alloc();
  98. char *nm_freelist[NM_MAX_INDEX + 1];
  99.  
  100. int nm_block_size = BLOCK_SIZE;
  101.  
  102.  
  103. char *nm_malloc(size) 
  104.     /* 
  105.      *  return a pointer to an object of size 'size',
  106.      *  allocating a new block of free space if necessary
  107.      */
  108.     unsigned int size;
  109.     {
  110.     register char *temp;
  111.     register int index = nm_align(size);
  112.  
  113.     if ( index > NM_MAX_INDEX ) {    /* too large, use old malloc */
  114.     return( nm_slow_alloc(size) );
  115.     }
  116.     else if ( nm_freelist[index] == (char *) 0 ) {
  117.     /* out of free space, allocate a new block */
  118.     return( nm_block_alloc( (int) size ) );
  119.     }
  120.     else {
  121.     /* return the top item on the freelist */
  122.     temp = nm_freelist[index];
  123.     nm_freelist[index] = *( (char **) temp );
  124.     *( (char **) temp) = (char *) 0;
  125.     return( temp );
  126.     }
  127.     }
  128.  
  129. nm_free(ptr,size) 
  130.     /* 
  131.      *    Free the object pointed to by ptr of size 'size'
  132.      */
  133.     char *ptr;
  134.     int size;
  135.     {
  136.     register int index = nm_align(size);
  137.  
  138.     if ( index > NM_MAX_INDEX ) { /* too large, use old free */
  139.     nm_slow_free(ptr);
  140.     }
  141.     else {
  142.     /* link to the top of the freelist */
  143.     *( (char **) ptr ) = nm_freelist[index];
  144.     nm_freelist[index] = (char *) ptr;
  145.     }
  146.     }
  147.  
  148. char *nm_block_alloc(size)
  149.     /*
  150.      *    Allocate a block of size nm_block_size, aligned to the
  151.      *    sizeof(NM_ALIGN)
  152.      */
  153.     int size;
  154.     {
  155.     int index = nm_align(size);
  156.     char *ptr;
  157.     char *current_pos, *start_of_block, *end_of_block;
  158.     size = sizeof(NM_ALIGN)*index;
  159. #ifdef vms
  160.     if((start_of_block = (char *) malloc(nm_block_size)) == (char *) 0 )
  161.     return( (char *) 0);
  162. #else
  163.     current_pos = sbrk(0);
  164.     start_of_block = (char *) (nm_align(current_pos)*sizeof(NM_ALIGN));
  165. #endif
  166.     end_of_block = start_of_block + nm_block_size;
  167. #ifndef vms
  168.     if ( sbrk(end_of_block - current_pos) ==  (char *) -1) {
  169.     /* out of memory */
  170.     return( (char *) 0);
  171.     }
  172. #endif
  173.     for(ptr = start_of_block; ptr <= end_of_block - 2*size; ptr += size) {
  174.     /* link all the objects in the new block together */
  175.     *( (char **) ptr ) = ptr + size;
  176.     }
  177.     *( (char **) ptr ) = (char *) 0;
  178.     nm_freelist[index] = start_of_block + size;
  179.     return( start_of_block );
  180.     }
  181.  
  182. char *nm_slow_alloc(size)
  183.     unsigned size;
  184.     {
  185.     return(malloc(size));
  186.     }
  187.  
  188. nm_slow_free(ptr)
  189.     char *ptr;
  190.     {
  191.     free(ptr);
  192.     }
  193.  
  194. nm_set_block_size(size)
  195.     int size;
  196.     {
  197.     nm_block_size = size;
  198.     }
  199.  
  200.