103 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Header$ */
 | 
						|
 | 
						|
#define CLICK_SIZE	4096
 | 
						|
#if EM_WSIZE == EM_PSIZE
 | 
						|
typedef unsigned int vir_bytes;
 | 
						|
#else
 | 
						|
typedef long vir_bytes;
 | 
						|
#endif
 | 
						|
extern bcopy();
 | 
						|
 | 
						|
#define ALIGN(x, a)	(((x) + (a - 1)) & ~(a - 1))
 | 
						|
#define BUSY		1
 | 
						|
#define NEXT(p)		(* (char **) (p))
 | 
						|
 | 
						|
#ifdef pdp
 | 
						|
#define BUGFIX	64	/* cannot set break in top 64 bytes */
 | 
						|
#else
 | 
						|
#define BUGFIX	0
 | 
						|
#endif
 | 
						|
 | 
						|
extern char *sbrk(), *brk();
 | 
						|
static char *bottom, *top;
 | 
						|
 | 
						|
static grow(len)
 | 
						|
unsigned len;
 | 
						|
{
 | 
						|
  register char *p;
 | 
						|
  register int click = CLICK_SIZE;
 | 
						|
 | 
						|
  while (click >= 4) {
 | 
						|
  	p = (char *) ALIGN((vir_bytes) top + sizeof(char *) + len, click)
 | 
						|
							+ BUGFIX;
 | 
						|
	if (p > top && brk(p - BUGFIX) >= 0) break;
 | 
						|
	click >>= 1;
 | 
						|
  }
 | 
						|
  if (click < 4) return(0);
 | 
						|
  top = p - (BUGFIX + sizeof(char *));
 | 
						|
  for (p = bottom; NEXT(p) != 0; p = (char *) (* (vir_bytes *) p & ~BUSY))
 | 
						|
	;
 | 
						|
  NEXT(p) = top;
 | 
						|
  NEXT(top) = 0;
 | 
						|
  return(1);
 | 
						|
}
 | 
						|
 | 
						|
char *malloc(size)
 | 
						|
unsigned size;
 | 
						|
{
 | 
						|
  register char *p, *next, *new;
 | 
						|
  register unsigned len = ALIGN(size, sizeof(char *)) + sizeof(char *);
 | 
						|
 | 
						|
  if ((p = bottom) == 0) {
 | 
						|
	top = bottom = p = sbrk(sizeof(char *));
 | 
						|
	NEXT(p) = 0;
 | 
						|
  }
 | 
						|
  while ((next = NEXT(p)) != 0)
 | 
						|
	if ((vir_bytes) next & BUSY)			/* already in use */
 | 
						|
		p = (char *) ((vir_bytes) next & ~BUSY);
 | 
						|
	else {
 | 
						|
		while ((new = NEXT(next)) != 0 && !((vir_bytes) new & BUSY))
 | 
						|
			next = new;
 | 
						|
		if (next - p >= len) {			/* fits */
 | 
						|
			if ((new = p + len) < next)	/* too big */
 | 
						|
				NEXT(new) = next;
 | 
						|
			NEXT(p) = (char *) ((vir_bytes) new | BUSY);
 | 
						|
			return(p + sizeof(char *));
 | 
						|
		}
 | 
						|
		p = next;
 | 
						|
	}
 | 
						|
  return grow(len) ? malloc(size) : 0;
 | 
						|
}
 | 
						|
 | 
						|
char *realloc(old, size)
 | 
						|
char *old;
 | 
						|
unsigned size;
 | 
						|
{
 | 
						|
  register char *p = old - sizeof(char *), *next, *new;
 | 
						|
  register unsigned len = ALIGN(size, sizeof(char *)) + sizeof(char *), n;
 | 
						|
 | 
						|
  next = (char *) (* (vir_bytes *) p & ~BUSY);
 | 
						|
  n = next - old;					/* old size */
 | 
						|
  while ((new = NEXT(next)) != 0 && !((vir_bytes) new & BUSY))
 | 
						|
	next = new;
 | 
						|
  if (next - p >= len) {				/* does it still fit */
 | 
						|
	if ((new = p + len) < next) {			/* even too big */
 | 
						|
		NEXT(new) = next;
 | 
						|
		NEXT(p) = (char *) ((vir_bytes) new | BUSY);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		NEXT(p) = (char *) ((vir_bytes) next | BUSY);
 | 
						|
	return(old);
 | 
						|
  }
 | 
						|
  if ((new = malloc(size)) == 0)			/* it didn't fit */
 | 
						|
	return(0);
 | 
						|
  bcopy(old, new, n);					/* n < size */
 | 
						|
  * (vir_bytes *) p &= ~BUSY;
 | 
						|
  return(new);
 | 
						|
}
 | 
						|
 | 
						|
free(p)
 | 
						|
char *p;
 | 
						|
{
 | 
						|
  * (vir_bytes *) (p - sizeof(char *)) &= ~BUSY;
 | 
						|
}
 |