4.3BSD/usr/contrib/pathalias/mem.c

Compare this file to the similar file:
Show the results in this format:

/* pathalias -- by steve bellovin, as told to peter honeyman */
#ifndef lint
static char	*sccsid = "@(#)mem.c	8.1 (down!honey) 86/01/19";
#endif

#include "def.h"

/* imported */
extern char *sbrk();

link	*
newlink()
{
	link	*rval;

	if ((rval = (link * ) calloc(1, sizeof(link))) == 0)
		nomem();
	return(rval);
}

node	*
newnode()
{
	node	*rval;

	if ((rval = (node * ) calloc(1, sizeof(node))) == 0)
		nomem();
	Ncount++;
	return(rval);
}

char	*
strsave(s)
char	*s;
{
	char *r;

	if ((r = malloc((unsigned int) strlen(s) + 1)) == 0)
		nomem();
	(void) strcpy(r, s);
	return(r);
}

#ifndef strclear
void
strclear(dst, len)
register char *dst;
register int len;
{
	while (--len >= 0)
		*dst++ = 0;
}
#endif /*strclear*/

node	**
newtable(size)
long	size;
{
	node	**rval;

	if ((rval = (node **) calloc(1, (unsigned int) (size * sizeof(*rval)))) == 0) 
		nomem();
	return(rval);
}

freetable(t, size)
node	**t;
long	size;
{
#ifdef MYMALLOC
	addtoheap((char *) t, (long) (size * sizeof(*t)));
#else
	free((char *) t);
#endif
}

nomem()
{
	fprintf(stderr, "%s: Out of memory (%ldk allocated)\n",
			ProgName, allocation());
	badmagic(1);
}

/* data space allocation -- main sets End very early */
allocation()
{
	static char	*dataspace;

	if (dataspace == 0) {	/* first time */
		dataspace = sbrk(0);		/* &end? */
		return(0);
	}
	return((sbrk(0) - dataspace)/1024);
}

#ifdef MYMALLOC

/* use c library malloc/calloc here, and here only */
#undef malloc
#undef calloc
extern char *malloc(), *calloc();

/* allocate in MBUFSIZ chunks.  4k works ok (less 16 for malloc quirks). */
#define MBUFSIZ (4 * 1024 - 16)

/* 
 * mess with ALIGN at your peril.  longword (== 0 mod 4)
 * alignment seems to work everywhere.
 */

#define ALIGN 2

typedef struct heap heap;
struct heap {
	heap *h_next;
	long h_size;
};

static heap *Mheap;	/* not to be confused with a priority queue */

addtoheap(p, size)
char *p;
long size;
{
	int adjustment;
	heap *pheap;

	/* p is aligned, but it doesn't hurt to check */
	adjustment = align(p);
	p += adjustment;
	size -= adjustment;

	if (size < 1024)
		return;		/* can't happen */
	pheap = (heap *) p;	/* pheap is shorthand */
	pheap->h_next = Mheap;
	pheap->h_size = size;
	Mheap = pheap;
}

/*
 * buffered malloc()
 *	returns space initialized to 0.  calloc isn't used, since
 *	strclear can be faster.
 *
 * free is ignored, except for very large objects,
 * which are returned to the heap with addtoheap(). 
 */

char	*
mymalloc(n)
register unsigned int	n;
{
	static long	size;		/* how much do we have on hand? */
	static char	*mstash;	/* where is it?  (kept aligned) */
	register char	*rval;

	n += align((char *) n);	/* keep everything aligned */
	if (n >= 1024) {		/* from hash table */
		rval = malloc(n);	/* aligned */
		strclear(rval, n);
		return(rval);
	}
	

	if (n > size) {
		/* look in the heap (already aligned) */
		if (Mheap) {
			mstash = (char *) Mheap;
			size = Mheap->h_size;
			Mheap = Mheap->h_next;
		} else {
			mstash = malloc(MBUFSIZ);	/* aligned */
			if (mstash == 0) {
				size = 0;
				return(0);
			}
			size = MBUFSIZ;
		}
		strclear(mstash, size);
	}
	rval = mstash;
	mstash += n;
	size -= n;
	return(rval);
}

/* what's the (mis-)alignment of n?  return the complement of (n mod 2^ALIGN) */
align(n)
char	*n;
{
	int	abits;	/* misalignment bits in n */

	abits = (int) n & ~(0xff << ALIGN) & 0xff;
	if (abits == 0)
		return(0);
	return((1 << ALIGN) - abits);
}

#endif /*MYMALLOC*/