home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / m / mawk11as.zip / ZMALLOC.C < prev    next >
C/C++ Source or Header  |  1991-12-18  |  3KB  |  139 lines

  1.  
  2. /********************************************
  3. zmalloc.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /*$Log:    zmalloc.c,v $
  14.  * Revision 5.1  91/12/05  07:56:35  brennan
  15.  * 1.1 pre-release
  16.  * 
  17. */
  18.  
  19. /*  zmalloc.c  */
  20. #include  "mawk.h"
  21. #include  "zmalloc.h"
  22.  
  23. void PROTO( mawk_exit, (int) ) ;
  24.  
  25. extern  struct yacc_mem  *yacc_memp ;
  26.  
  27. /*
  28.   zmalloc() gets mem from malloc() in CHUNKS of 2048 bytes
  29.   and cuts these blocks into smaller pieces that are multiples
  30.   of eight bytes.  When a piece is returned via zfree(), it goes
  31.   on a linked linear list indexed by its size.  The lists are
  32.   an array, pool[].
  33.  
  34.   E.g., if you ask for 22 bytes with p = zmalloc(22), you actually get
  35.   a piece of size 24.  When you free it with zfree(p,22) , it is added
  36.   to the list at pool[2].
  37. */
  38.  
  39. #define POOLSZ      16
  40.  
  41. #define  CHUNK          256    
  42.         /* number of blocks to get from malloc */
  43.  
  44. static PTR  PROTO( emalloc, (unsigned) ) ;
  45. void PROTO( errmsg, (int , char *, ...) ) ;
  46.  
  47. static PTR emalloc(size)
  48.   unsigned size ;
  49. { PTR p ;
  50.   static char out[] = "out of memory" ;
  51.  
  52.   if( !(p = (PTR) malloc(SIZE_T(size))) )
  53.     if ( mawk_state == EXECUTION ) rt_error(out) ;
  54.     else /* I don't think this will ever happen */
  55.     { compile_error(out) ; mawk_exit(1) ; }
  56.   return p ;
  57. }
  58.  
  59.  
  60. typedef  union  zblock {
  61. char dummy[ZBLOCKSZ] ;
  62. union zblock *link ;
  63. }  ZBLOCK  ;
  64.  
  65. /* ZBLOCKS of sizes 1, 2, ... 16
  66.    which is bytes of sizes 8, 16, ... , 128
  67.    are stored on the linked linear lists in
  68.    pool[0], pool[1], ... , pool[15]
  69. */
  70.  
  71. static  ZBLOCK  *pool[POOLSZ] ;
  72.  
  73. PTR   bmalloc( blocks )
  74.   register unsigned blocks ;
  75.   register ZBLOCK *p ;
  76.   static  unsigned amt_avail ;
  77.   static  ZBLOCK  *avail ;
  78.  
  79.   if ( blocks > POOLSZ )  return emalloc(blocks<<ZSHIFT) ;
  80.  
  81.   if ( p = pool[blocks-1] )
  82.   { pool[blocks-1] = p->link ; return (PTR) p ; }
  83.  
  84.   if ( blocks > amt_avail )
  85.   { if ( amt_avail ) /* free avail */
  86.     { avail->link = pool[--amt_avail] ; pool[amt_avail] = avail ; }
  87.  
  88.     /* use parser tables first */
  89.     if ( yacc_memp->zblocks >= blocks )
  90.     { avail = (ZBLOCK *) yacc_memp->mem ;
  91.       amt_avail = yacc_memp++ -> zblocks ;
  92.       /* make sure its -- aligned */
  93.       if ( (int) avail & 7 )
  94.       { avail = (ZBLOCK*)((char *)avail + 8 - ((int)avail&7)) ;
  95.     amt_avail-- ;
  96.       }
  97.     }
  98.     else
  99.     if ( !(avail = (ZBLOCK *) malloc(SIZE_T(CHUNK*ZBLOCKSZ))) )
  100.     { /* if we get here, almost out of memory */
  101.         amt_avail = 0 ;   
  102.     return  emalloc(blocks << ZSHIFT) ;
  103.     }
  104.     else  amt_avail = CHUNK ;
  105.   }
  106.   
  107.   /* get p from the avail pile */
  108.   p = avail ; avail += blocks ; amt_avail -= blocks ; 
  109.   return (PTR) p ;
  110. }
  111.  
  112. void  bfree( p, blocks)
  113.   register PTR p ;  
  114.   register unsigned blocks ;
  115.  
  116.   if ( blocks > POOLSZ )  free(p) ;
  117.   else
  118.   {
  119.     ((ZBLOCK *)p)->link = pool[--blocks] ;
  120.     pool[blocks] = (ZBLOCK *) p ;
  121.   }
  122. }
  123.  
  124. PTR  zrealloc( p, old_size, new_size )
  125.   register PTR  p ;
  126.   unsigned old_size, new_size ;
  127. { register PTR q ;
  128.  
  129.   (void) memcpy(q = zmalloc(new_size), p, 
  130.                 SIZE_T(old_size < new_size ? old_size : new_size)) ;
  131.  
  132.   zfree(p, old_size) ;
  133.   return q ;
  134. }
  135.  
  136.  
  137.