home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
LANGUAGS
/
XLISP
/
XLISP11.ARK
/
ALLOC.C
< prev
next >
Wrap
Text File
|
1986-10-12
|
3KB
|
123 lines
/*
Full K&R malloc() and free() for AZTEC C II
This module adapted for the CP/M environment from source code in Brian
W. Kernighan and Dennis M. Ritchie's "The C Programming Language" by
William C. Colley III -- 4 OCT 1982.
This module implements the functions alloc(), morecore(), xsbrk(), and
free() as per pp. 173-7 of Kernighan and Ritchie. Since xsbrk() is
responsible for preventing collision between the allocated data and
the stack, it must know how much space to leave for the stack. Thus,
a function rsvstk() is provided to override the default 1024 bytes.
The functions in this package are:
char *alloc(nb) allocates a block of nb bytes and
unsigned nb; returns a pointer to it. If no such
block is available, the value NULL (0)
is returned.
free(blk) Attaches the storage allocation block
char *blk; blk to the free list. Returns no
meaningful value.
HEADER *morecore(nb) Gets a storage allocation block of
unsigned nb; size nb from the heap and returns a
pointer to it. Returns NULL (0) if
not enough space is available.
char *xsbrk(nb) Gets nb bytes from the heap. Returns
unsigned nb; a pointer to the bytes or -1 if not
enough bytes are available.
char *xsettop(nb) Gets nb bytes from the heap. Returns
unsigned nb; a pointer to the bytes or NULL (0) if
not enough bytes are available.
rsvstk(stk) Changes the minimum allowable remaining
unsigned stk; stack size at a call to xsbrk() to stk
bytes. Default value is 1024 bytes.
*/
#define NULL 0
union header {
struct {
union header *ptr;
unsigned size;
} s;
long l;
};
typedef union header HEADER;
static HEADER base, *allocp = NULL;
char *alloc(nb)
unsigned nb;
{
HEADER *morecore();
register HEADER *p, *q;
register unsigned nu;
nu = ((nb + 3) >> 2) + 1;
if ((q = allocp) == NULL) {
base.s.ptr = allocp = q = &base;
base.s.size = 1;
}
for (p = q->s.ptr; ; q = p, p = p->s.ptr) {
if (p->s.size >= nu) {
if (p->s.size == nu) q->s.ptr = p->s.ptr;
else {
p->s.size -= nu;
p += p->s.size;
p->s.size = nu;
}
allocp = q; return (char *)(p + 1);
}
if (p == allocp)
if ((p = morecore(nu)) == NULL) return NULL;
}
}
HEADER *morecore(nu)
unsigned nu;
{
char *xsbrk();
register char *cp;
register HEADER *up;
if ((int)(cp = xsbrk(nu << 2)) == -1) return NULL;
up = (HEADER *)cp;
up->s.size = nu;
free((char *)(up + 1));
return allocp;
}
free(blk)
char *blk;
{
register HEADER *p, *q;
p = (HEADER *)blk - 1;
for (q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr)
if (q >= q ->s.ptr && (p > q || p < q->s.ptr)) break;
if (p + p->s.size == q->s.ptr) {
p->s.size += q->s.ptr->s.size;
p->s.ptr = q->s.ptr->s.ptr;
}
else p->s.ptr = q->s.ptr;
if (q + q->s.size == p) {
q->s.size += p->s.size;
q->s.ptr = p->s.ptr;
}
else q->s.ptr = p;
allocp = q;
}
/* The functions xsbrk(), xsettop(), and rsvstk() live in the module xsbrk.mac
as they have to beat on machine things like the stack pointer. */