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