/
umud/DOC/
umud/DOC/examples/
umud/DOC/internals/
umud/DOC/wizard/
umud/MISC/
umud/MISC/dbchk/
umud/RWHO/rwhod/
/*
	Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/

#ifndef	lint
static	char	RCSid[] = "$Header: /usr/users/mjr/hacks/umud/RCS/alloc.c,v 1.1 91/07/04 17:32:24 mjr Rel $";
#endif

/* configure all options BEFORE including system stuff. */
#include	"config.h"

#include	"mud.h"

/*
routines that handle copying stuff in memory, and other main
memory allocation shenanigans.
*/


/*
#define	ALLOC_DEBUG
*/


/*
temporary data is managed by keeping a list of allocated stuff, which
can be traversed and freed. this is not too terribly efficient, but
is not a load-bearing section of code.
*/
struct	tmplist	{
	struct	tmplist	*next;
	mall_t	dat;
};


/* list of currently active temporaries */
static	struct	tmplist	*tmpl;

/* list of temp list structures that have been freed and stacked */
static	struct	tmplist	*freetmpl;



/* just like malloc() but keep track of the storage */
mall_t
tmpalloc(siz)
int	siz;
{
	struct	tmplist	*lp;

	if(freetmpl != (struct tmplist *)0) {
		lp = freetmpl;
#ifdef	ALLOC_DEBUG
		printf("take holder %d from tmp holder list\n",lp);
#endif
		freetmpl = freetmpl->next;
	} else {
		if((lp = (struct tmplist *)malloc(sizeof(struct tmplist))) == 0)
			return(0);
	}
	lp->dat = malloc((unsigned)siz);

	/* add to the chain */
	lp->next = tmpl;
	tmpl = lp;

#ifdef	ALLOC_DEBUG
	printf("tmpalloc %d bytes at %d (holder is %d)\n",siz,lp->dat,lp);
#endif
	return(lp->dat);
}




/*
put something on the temp list to free later.
this results in what is basically a deferred free() - executed
at the end of each machine run.
*/
void
deferfree(p)
mall_t	p;
{
	struct	tmplist	*lp;

	if(freetmpl != (struct tmplist *)0) {
		lp = freetmpl;
#ifdef	ALLOC_DEBUG
		printf("take holder %d from tmp holder list\n",lp);
#endif
		freetmpl = freetmpl->next;
	} else {
		if((lp = (struct tmplist *)malloc(sizeof(struct tmplist))) == 0) {
#ifdef	ALLOC_DEBUG
			printf("deferfree can't allocate holder, leaks memory\n");
#endif
			return;
		}
	}
	lp->dat = p;
	lp->next = tmpl;
	tmpl = lp;

#ifdef	ALLOC_DEBUG
	printf("tmpputonfree ? bytes at %d (holder is %d)\n",lp->dat,lp);
#endif
}




/* free all the temporaries */
void
tmp_sync()
{
	register struct	tmplist	*lp = tmpl;
	register struct	tmplist	*np;

	if(tmpl == (struct tmplist *)0)
		return;

	while(lp != (struct tmplist *)0) {
		if(lp->dat != 0)
			(void)free(lp->dat);
#ifdef	ALLOC_DEBUG
		printf("tmpsync at %d (holder is %d)\n",lp->dat,lp);
#endif
		np = lp->next;
		lp->next = freetmpl;
		freetmpl = lp;
#ifdef	ALLOC_DEBUG
		printf("stack holder %d on tmp holder list\n",lp);
#endif
		lp = np;
	}
	tmpl = (struct tmplist *)0;
}