Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/lib/malloc.c
There are 9 other files named malloc.c in the archive. Click here to see a list.
/*
** malloc - memory allocation for C programs (first fit with rover)
** David Eppstein / Stanford University / 26-Jul-84
**
** Blocks are an integral number of words long, and there is at least
** one data word (to ensure room for the freelist pointer). It is
** assumed that integer pointers are the same size as integers, and
** that sizeof(char) is 1.
**
** Block in use, pointed to by a byte pointer:
** ________________________________________________
** | |
** | Number of words in block (including this word) |
** |________________________________________________|
** Byte ptr-------->| |
** | Block data |
** \ \
** \ \
** |________________________________________________|
**
**
** Block on free list:
** ________________________________________________
** Ptr from prev--->| |
** | Number of words in block (including this word) |
** |________________________________________________|
** | |
** | Pointer to next block in circular freelist |
** |________________________________________________|
** | |
** | Rest of block unused |
** \ \
** \ \
** |________________________________________________|
**
**
** The variable rover points to some block in the circular free block list;
** when the freelist is empty rover contains NULL.
*/
entry malloc, free, realloc;
#define NBYTES (sizeof (int))
#define NULL 0
char *sbrk();
/* --------------------------------------------- */
/* initialization for freelist pointer */
/* --------------------------------------------- */
static int *zblock()
{
return NULL; /* fn not val so re-init on re-start */
}
static int *rover = zblock();
/* ------------------------------------ */
/* allocate a block of memory */
/* ------------------------------------ */
char *malloc(nbytes)
{
int *p, *q, nwords;
char *align;
/* calculate number of words needed in block */
if (nbytes < 0) return NULL; /* range check argument */
nwords = (nbytes + (2 * NBYTES - 1)) / NBYTES; /* calc num words needed */
/* look through the free list for a fit */
p = rover; /* remember where we started */
q = NULL; /* don't do at all if nothing there */
while (q != p) {
q = rover; /* remember old pointer */
rover = (int *) rover[1]; /* and move over one */
if (rover[0] >= nwords) { /* found a big enough block? */
p = rover; /* yes, remember where it is */
if (q == rover) rover = NULL; /* take last one from list */
else rover = (int *) (q[1] = rover[1]); /* or splice out of list */
split (p, nwords); /* maybe break off unneeded portion */
return (char *) (p + 1); /* return what we found */
}
}
/* no large enough blocks were found, make a new one */
align = sbrk (0); /* see how we're aligned */
if (align != (char *) (int *) align) brk ((char *) (1 + (int *) align));
align = sbrk (nwords * NBYTES); /* allocate a new memory block */
if ((int) align == -1) return NULL; /* no more room at the inn */
p = (int *) align; /* got one, make word pointer */
p[0] = nwords; /* remember how many words in it */
return (char *) (p + 1); /* return next word as char pointer */
}
/* --------------------------------------------------------------- */
/* break up a block into two smaller blocks if necessary */
/* --------------------------------------------------------------- */
static split(block,newsize)
int *block;
{
if (block[0] >= newsize+2) { /* enough room for another block? */
block[newsize] = block[0] - newsize; /* yes, make sizes of the */
block[0] = newsize; /* new smaller blocks */
free((char *) (block+newsize+1)); /* throw back unused part */
}
}
/* ------------------------------------------- */
/* free a previously allocated block */
/* ------------------------------------------- */
free(cp)
char *cp;
{
int *p;
p = ((int *) cp) - 1; /* point back to start of block */
if (rover == NULL) rover = (int *) (p[1] = (int) p); /* make circle list */
else {
p[1] = rover[1]; /* already have one, link to it */
rover[1] = (int) p; /* and splice in. */
}
}
/* ------------------------------------------------------------- */
/* make new block with old contents but different size */
/* ------------------------------------------------------------- */
char *
realloc(cp, nbytes)
char *cp;
{
char *op;
int *p, *q, nwords;
p = ((int *) cp) - 1; /* point back to start of block */
if (nbytes < 0) return NULL; /* range check argument */
nwords = (nbytes + (2 * NBYTES - 1)) / NBYTES; /* calc num words needed */
if (nwords <= p[0]) split(p, nwords); /* shrinking, break up block */
else { /* bigger, so reallocate and copy */
op = cp; /* first save the original pointer */
cp = malloc(nbytes); /* make a bigger block */
if (cp != NULL) {
q = ((int *) cp) - 1; /* get word pointer */
while (--nwords > 1) *++q = *++p; /* copy data portion */
}
free(op); /* get rid of old block */
}
return cp; /* return updated char pointer */
}