home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 11 / AUCD11B.iso / LANGUAGES / WraithSet / AwkStuff / MawkSrc / c / zmalloc < prev   
Text File  |  1999-11-28  |  4KB  |  196 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 1.6  1995/06/06  00:18:35  mike
  15.  * change mawk_exit(1) to mawk_exit(2)
  16.  *
  17.  * Revision 1.5  1995/03/08  00:06:26  mike
  18.  * add a pointer cast
  19.  *
  20.  * Revision 1.4  1993/07/14  12:45:15  mike
  21.  * run thru indent
  22.  *
  23.  * Revision 1.3  1993/07/07  00:07:54  mike
  24.  * more work on 1.2
  25.  *
  26.  * Revision 1.2  1993/07/03  21:15:35  mike
  27.  * bye bye yacc_mem
  28.  *
  29.  * Revision 1.1.1.1  1993/07/03  18:58:23  mike
  30.  * move source to cvs
  31.  *
  32.  * Revision 5.4  1993/02/13  21:57:38  mike
  33.  * merge patch3
  34.  *
  35.  * Revision 5.3  1993/01/14  13:12:33  mike
  36.  * casts in front of malloc
  37.  *
  38.  * Revision 5.1.1.1  1993/02/06  11:12:19  mike
  39.  * fix bug in reuse of parser table memory
  40.  * for most users ifdef the mess out
  41.  *
  42.  * Revision 5.1  1991/12/05  07:56:35  brennan
  43.  * 1.1 pre-release
  44.  *
  45. */
  46.  
  47. /*  zmalloc.c  */
  48. #include  "mawk.h"
  49. #include  "zmalloc.h"
  50.  
  51.  
  52.  
  53. /*
  54.   zmalloc() gets mem from malloc() in CHUNKS of 2048 bytes
  55.   and cuts these blocks into smaller pieces that are multiples
  56.   of eight bytes.  When a piece is returned via zfree(), it goes
  57.   on a linked linear list indexed by its size.  The lists are
  58.   an array, pool[].
  59.  
  60.   E.g., if you ask for 22 bytes with p = zmalloc(22), you actually get
  61.   a piece of size 24.  When you free it with zfree(p,22) , it is added
  62.   to the list at pool[2].
  63. */
  64.  
  65. #define POOLSZ      16
  66.  
  67. #define  CHUNK          256
  68.  /* number of blocks to get from malloc */
  69.  
  70. static void PROTO(out_of_mem, (void)) ;
  71.  
  72.  
  73. static void
  74. out_of_mem()
  75. {
  76.    static char out[] = "out of memory" ;
  77.  
  78.    if (mawk_state == EXECUTION)  rt_error(out) ;
  79.    else
  80.    {
  81.       /* I don't think this will ever happen */
  82.       compile_error(out) ; mawk_exit(2) ; 
  83.    }
  84. }
  85.  
  86.  
  87. typedef union zblock
  88. {
  89.    char dummy[ZBLOCKSZ] ;
  90.    union zblock *link ;
  91. } ZBLOCK ;
  92.  
  93. /* ZBLOCKS of sizes 1, 2, ... 16
  94.    which is bytes of sizes 8, 16, ... , 128
  95.    are stored on the linked linear lists in
  96.    pool[0], pool[1], ... , pool[15]
  97. */
  98.  
  99. static ZBLOCK *pool[POOLSZ] ;
  100.  
  101. /* zmalloc() is a macro in front of bmalloc "BLOCK malloc" */
  102.  
  103. PTR
  104. bmalloc(blocks)
  105.    register unsigned blocks ;
  106. {
  107.    register ZBLOCK *p ;
  108.    static unsigned amt_avail ;
  109.    static ZBLOCK *avail ;
  110.  
  111.    if (blocks > POOLSZ)
  112.    {
  113.       p = (ZBLOCK *) malloc(blocks << ZSHIFT) ;
  114.       if (!p)  out_of_mem() ;
  115.       return (PTR) p ;
  116.    }
  117.  
  118.    if (p = pool[blocks - 1])
  119.    {
  120.       pool[blocks - 1] = p->link ;
  121.       return (PTR) p ;
  122.    }
  123.  
  124.    if (blocks > amt_avail)
  125.    {
  126.       if (amt_avail != 0)       /* free avail */
  127.       {
  128.          avail->link = pool[--amt_avail] ;
  129.          pool[amt_avail] = avail ;
  130.       }
  131.  
  132.       if (!(avail = (ZBLOCK *) malloc(CHUNK * ZBLOCKSZ)))
  133.       {
  134.          /* if we get here, almost out of memory */
  135.          amt_avail = 0 ;
  136.          p = (ZBLOCK *) malloc(blocks << ZSHIFT) ;
  137.          if (!p)  out_of_mem() ;
  138.          return (PTR) p ;
  139.       }
  140.       else  amt_avail = CHUNK ;
  141.    }
  142.  
  143.    /* get p from the avail pile */
  144.    p = avail ; avail += blocks ; amt_avail -= blocks ; 
  145.    return (PTR) p ;
  146. }
  147.  
  148. void
  149. bfree(p, blocks)
  150.    register PTR p ;
  151.    register unsigned blocks ;
  152. {
  153.  
  154.    if (blocks > POOLSZ)  free(p) ;
  155.    else
  156.    {
  157.       ((ZBLOCK *) p)->link = pool[--blocks] ;
  158.       pool[blocks] = (ZBLOCK *) p ;
  159.    }
  160. }
  161.  
  162. PTR
  163. zrealloc(p, old_size, new_size)
  164.    register PTR p ;
  165.    unsigned old_size, new_size ;
  166. {
  167.    register PTR q ;
  168.  
  169.    if (new_size > (POOLSZ << ZSHIFT) &&
  170.        old_size > (POOLSZ << ZSHIFT))
  171.    {
  172.       if (!(q = realloc(p, new_size)))  out_of_mem() ;
  173.    }
  174.    else
  175.    {
  176.       q = zmalloc(new_size) ;
  177.       memcpy(q, p, old_size < new_size ? old_size : new_size) ;
  178.       zfree(p, old_size) ;
  179.    }
  180.    return q ;
  181. }
  182.  
  183.  
  184.  
  185. #ifndef  __GNUC__
  186. /* pacifier for Bison , this is really dead code */
  187. PTR
  188. alloca(sz)
  189.    unsigned sz ;
  190. {
  191.    /* hell just froze over */
  192.    exit(100) ;
  193.    return (PTR) 0 ;
  194. }
  195. #endif
  196.