home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 11
/
AUCD11B.iso
/
LANGUAGES
/
WraithSet
/
AwkStuff
/
MawkSrc
/
c
/
zmalloc
< prev
Wrap
Text File
|
1999-11-28
|
4KB
|
196 lines
/********************************************
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