/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.3 */
#ifdef debug
botch(s)
char *s;
{
printf("assertion botched: %s\n",s);
abort();
}
#else
#define ASSERT(p)
#endif
/* C storage allocator
* circular first-fit strategy
* works with noncontiguous, but monotonically linked, arena
* each block is preceded by a ptr to the (pointer of)
* the next following block
* blocks are exact number of words long
* aligned to the data type requirements of ALIGN
* pointers to blocks must have BUSY bit 0
* bit in ptr is 1 for busy, 0 for idle
* gaps in arena are merely noted as busy blocks
* last block of arena is empty and
* has a pointer to first
* idle blocks are coalesced during space search
*
* a different implementation may need to redefine
* ALIGN, NALIGN, BLOCK, BUSY, INT
* where INT is integer type to which a pointer can be cast
*/
#define INT int
#define ALIGN int
#define NULL 0
union store {
};
extern char *sbrk();
char *
unsigned nbytes;
{
register union store *p, *q;
register nw;
register temp;
register union store *r = 0;
for(; ; ) { /* done at most twice */
p = allocp;
for(temp=0; ; ) {
ASSERT(q>p);
allocp = p;
}
goto found;
r = p;
}
q = p;
if(p <= q) {
if(p != allocb)
return(NULL);
if(++temp>1)
break;
}
}
temp -= p - r - 1;
if(p+temp <= p)
return(NULL);
for(; ; ) {
if((INT)q != -1)
break;
return(NULL);
}
}
if(q>allocp) {
}
return((char *)(p+1));
}
/* freeing strategy tuned for LIFO allocation
*/
char *ap;
{
allocp = --p;
}
/* ialloc(q, nbytes) inserts a block that did not come
* from malloc into the arena
*
* q points to new block
* r points to last of new block
* p points to last cell of arena before new block
* s points to first cell of arena after new block
*/
char *qq;
unsigned nbytes;
{
register union store *p, *q, *s;
union store *r;
q->ptr = r;
for(p=allocb; ; p=s) {
if(s==allocb)
break;
ASSERT(s>p);
if(s>r) {
if(p<q)
break;
else
ASSERT(p>r);
}
}
if(allocb > q)
allocb = q;
}
/* realloc(p, nbytes) reallocates a block obtained from malloc()
* and freed since last call of malloc()
* to have new size nbytes, and old content
* returns new location, or 0 on failure
*/
char *
char *pp;
unsigned nbytes;
{
register union store *q;
union store *s, *t;
register unsigned nw;
unsigned onw;
free((char *)p);
if(q==NULL || q==p)
return((char *)q);
s = p;
t = q;
while(onw--!=0)
*t++ = *s++;
if(q<p && q+nw>=p)
return((char *)q);
}
#ifdef debug
allock(q)
union store *q;
{
#ifdef longdebug
register union store *p, *r;
int x;
x = 0;
p = allocb;
return(1);
if(p==q)
x++;
}
return(r==allocb&(x==1|p==q));
#else
return(q>=allocb);
#endif
}
#endif