home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / MAWK113.ZIP / mawk113 / zmalloc.c < prev    next >
C/C++ Source or Header  |  1993-02-06  |  4KB  |  159 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.1.1  1993/02/06  11:12:19  mike
  15.  * fix bug in reuse of parser table memory
  16.  * for most users ifdef the mess out
  17.  *
  18.  * Revision 5.1  1991/12/05  07:56:35  brennan
  19.  * 1.1 pre-release
  20.  *
  21. */
  22.  
  23. /*  zmalloc.c  */
  24. #include  "mawk.h"
  25. #include  "zmalloc.h"
  26.  
  27. void PROTO( mawk_exit, (int) ) ;
  28.  
  29. extern  struct yacc_mem  *yacc_memp ;
  30.  
  31. /*
  32.   zmalloc() gets mem from malloc() in CHUNKS of 2048 bytes
  33.   and cuts these blocks into smaller pieces that are multiples
  34.   of eight bytes.  When a piece is returned via zfree(), it goes
  35.   on a linked linear list indexed by its size.  The lists are
  36.   an array, pool[].
  37.  
  38.   E.g., if you ask for 22 bytes with p = zmalloc(22), you actually get
  39.   a piece of size 24.  When you free it with zfree(p,22) , it is added
  40.   to the list at pool[2].
  41. */
  42.  
  43. #define POOLSZ      16
  44.  
  45. #define  CHUNK          256    
  46.         /* number of blocks to get from malloc */
  47.  
  48. static PTR  PROTO( emalloc, (unsigned) ) ;
  49. void PROTO( errmsg, (int , char *, ...) ) ;
  50.  
  51. static PTR emalloc(size)
  52.   unsigned size ;
  53. { PTR p ;
  54.   static char out[] = "out of memory" ;
  55.  
  56.   if( !(p = (PTR) malloc(SIZE_T(size))) )
  57.     if ( mawk_state == EXECUTION ) rt_error(out) ;
  58.     else /* I don't think this will ever happen */
  59.     { compile_error(out) ; mawk_exit(1) ; }
  60.   return p ;
  61. }
  62.  
  63.  
  64. typedef  union  zblock {
  65. char dummy[ZBLOCKSZ] ;
  66. union zblock *link ;
  67. }  ZBLOCK  ;
  68.  
  69. /* ZBLOCKS of sizes 1, 2, ... 16
  70.    which is bytes of sizes 8, 16, ... , 128
  71.    are stored on the linked linear lists in
  72.    pool[0], pool[1], ... , pool[15]
  73. */
  74.  
  75. static  ZBLOCK  *pool[POOLSZ] ;
  76.  
  77. PTR   bmalloc( blocks )
  78.   register unsigned blocks ;
  79.   register ZBLOCK *p ;
  80.   static  unsigned amt_avail ;
  81.   static  ZBLOCK  *avail ;
  82.  
  83.   if ( blocks > POOLSZ )  return emalloc(blocks<<ZSHIFT) ;
  84.  
  85.   if ( p = pool[blocks-1] )
  86.   { pool[blocks-1] = p->link ; return (PTR) p ; }
  87.  
  88.   if ( blocks > amt_avail )
  89.   { 
  90.     if ( amt_avail != 0 ) /* free avail */
  91.     { 
  92.       avail->link = pool[--amt_avail] ;
  93.       pool[amt_avail] = avail ;
  94.     }
  95.  
  96. #if MSDOS || HAVE_SMALL_MEMORY
  97. /* this hack is dangerous (I've blown it twice), not portable,
  98.    and counts on byacc not changing, but it is a big win on
  99.    DOS.  On paged vmem systems it is a nop so ifdef it out.
  100. */
  101.     /* use parser tables first */
  102.     if ( yacc_memp->zblocks > blocks )
  103.     { 
  104.       avail = (ZBLOCK *) yacc_memp->mem ;
  105.       amt_avail = yacc_memp++ -> zblocks ;
  106.       /* make sure its -- aligned */
  107.       {
  108.     int k = (int) avail & 7 ;
  109.         if ( k )
  110.         { 
  111.       avail = (ZBLOCK*)((char *)avail + (8-k)) ;
  112.       amt_avail-- ;
  113.     }
  114.       }
  115.     }
  116.     else
  117. #endif
  118.  
  119.     if ( !(avail = (ZBLOCK *) malloc(SIZE_T(CHUNK*ZBLOCKSZ))) )
  120.     { /* if we get here, almost out of memory */
  121.         amt_avail = 0 ;   
  122.     return  emalloc(blocks << ZSHIFT) ;
  123.     }
  124.     else  amt_avail = CHUNK ;
  125.   }
  126.   
  127.   /* get p from the avail pile */
  128.   p = avail ; avail += blocks ; amt_avail -= blocks ; 
  129.   return (PTR) p ;
  130. }
  131.  
  132. void  bfree( p, blocks)
  133.   register PTR p ;  
  134.   register unsigned blocks ;
  135.  
  136.   if ( blocks > POOLSZ )  free(p) ;
  137.   else
  138.   {
  139.     ((ZBLOCK *)p)->link = pool[--blocks] ;
  140.     pool[blocks] = (ZBLOCK *) p ;
  141.   }
  142. }
  143.  
  144. PTR  zrealloc( p, old_size, new_size )
  145.   register PTR  p ;
  146.   unsigned old_size, new_size ;
  147. { register PTR q ;
  148.  
  149.   (void) memcpy(q = zmalloc(new_size), p, 
  150.                 SIZE_T(old_size < new_size ? old_size : new_size)) ;
  151.  
  152.   zfree(p, old_size) ;
  153.   return q ;
  154. }
  155.  
  156.  
  157.