159 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Header$ */
 | 
						|
/*	M E M O R Y  A L L O C A T I O N  R O U T I N E S	*/
 | 
						|
 | 
						|
/*	The allocation of memory in this program, which plays an important
 | 
						|
	role in reading files, replacing macros and building expression
 | 
						|
	trees, is not performed by malloc etc.  The reason for having own
 | 
						|
	memory allocation routines (malloc(), realloc() and free()) is
 | 
						|
	plain: the garbage collection performed by the library functions
 | 
						|
	malloc(), realloc() and free() costs a lot of time, while in most
 | 
						|
	cases (on a VAX) the freeing and reallocation of memory is not
 | 
						|
	necessary.  The only reallocation done in this program is at
 | 
						|
	building strings in memory.  This means that the last
 | 
						|
	(re-)allocated piece of memory can be extended.
 | 
						|
 | 
						|
	The (basic) memory allocating routines offered by this memory
 | 
						|
	handling package are:
 | 
						|
 | 
						|
	char *malloc(n)		: allocate n bytes
 | 
						|
	char *realloc(ptr, n)	: reallocate buffer to n bytes
 | 
						|
					(works only if ptr was last allocated)
 | 
						|
	free(ptr)		: if ptr points to last allocated
 | 
						|
					memory, this memory is re-allocatable
 | 
						|
	Salloc(str, sz)		: save string in malloc storage
 | 
						|
*/
 | 
						|
 | 
						|
#include	<system.h>
 | 
						|
#include	"myalloc.h"	/* UF */
 | 
						|
#include	"debug.h"	/* UF */
 | 
						|
 | 
						|
#include	"alloc.h"
 | 
						|
#include	"assert.h"
 | 
						|
 | 
						|
#ifdef	OWNALLOC
 | 
						|
char *sys_break();
 | 
						|
/* the following variables are used for book-keeping		 */
 | 
						|
static int nfreebytes = 0;	/* # free bytes in sys_break space */
 | 
						|
static char *freeb;		/* pointer to first free byte	 */
 | 
						|
static char *lastalloc;		/* pointer to last malloced sp	 */
 | 
						|
static int lastnbytes;		/* nr of bytes in last allocated */
 | 
						|
				/* space			 */
 | 
						|
static char *firstfreeb = 0;
 | 
						|
 | 
						|
#endif	OWNALLOC
 | 
						|
 | 
						|
char *
 | 
						|
Salloc(str, sz)
 | 
						|
	register char str[];
 | 
						|
	register int sz;
 | 
						|
{
 | 
						|
	/*	Salloc() is not a primitive function: it just allocates a
 | 
						|
		piece of storage and copies a given string into it.
 | 
						|
	*/
 | 
						|
	char *res = Malloc(sz);
 | 
						|
	register char *m = res;
 | 
						|
 | 
						|
	while (sz--)
 | 
						|
		*m++ = *str++;
 | 
						|
	return res;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef	OWNALLOC
 | 
						|
 | 
						|
#define	ALIGN(m)	(ALIGNSIZE * (((m) - 1) / ALIGNSIZE + 1))
 | 
						|
 | 
						|
char *
 | 
						|
malloc(n)
 | 
						|
	unsigned n;
 | 
						|
{
 | 
						|
	/*	malloc() is a very simple malloc().
 | 
						|
	*/
 | 
						|
	n = ALIGN(n);
 | 
						|
	if (nfreebytes < n)	{
 | 
						|
		register nbts = (n <= ALLOCSIZ) ? ALLOCSIZ : n;
 | 
						|
 | 
						|
		if (!nfreebytes)	{
 | 
						|
			if ((freeb = sys_break(nbts)) == ILL_BREAK)
 | 
						|
				fatal("out of memory");
 | 
						|
		}
 | 
						|
		else	{
 | 
						|
			if (sys_break(nbts) == ILL_BREAK)
 | 
						|
				fatal("out of memory");
 | 
						|
		}
 | 
						|
		nfreebytes += nbts;
 | 
						|
	}
 | 
						|
	lastalloc = freeb;
 | 
						|
	freeb = lastalloc + n;
 | 
						|
	lastnbytes = n;
 | 
						|
	nfreebytes -= n;
 | 
						|
	return lastalloc;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
char *
 | 
						|
realloc(ptr, n)
 | 
						|
	char *ptr;
 | 
						|
	unsigned n;
 | 
						|
{
 | 
						|
	/*	realloc() is designed to append more bytes to the latest
 | 
						|
		allocated piece of memory. However reallocation should be
 | 
						|
		performed, even if the mentioned memory is not the latest
 | 
						|
		allocated one, this situation will not occur. To do so,
 | 
						|
		realloc should know how many bytes are allocated the last
 | 
						|
		time for that piece of memory. ????
 | 
						|
	*/
 | 
						|
	register int nbytes = n;
 | 
						|
 | 
						|
	ASSERT(ptr == lastalloc);	/* security		*/
 | 
						|
	nbytes -= lastnbytes;		/* # bytes required	*/
 | 
						|
	if (nbytes == 0)		/* no extra bytes	*/
 | 
						|
		return lastalloc;
 | 
						|
 | 
						|
	/*	if nbytes < 0: free last allocated bytes;
 | 
						|
		if nbytes > 0: allocate more bytes
 | 
						|
	*/
 | 
						|
	if (nbytes > 0)
 | 
						|
		nbytes = ALIGN(nbytes);
 | 
						|
	if (nfreebytes < nbytes)	{
 | 
						|
		register int nbts = (nbytes < ALLOCSIZ) ? ALLOCSIZ : nbytes;
 | 
						|
		if (sys_break(nbts) == ILL_BREAK)
 | 
						|
			fatal("out of memory");
 | 
						|
		nfreebytes += nbts;
 | 
						|
	}
 | 
						|
	freeb += nbytes;	/* less bytes			*/
 | 
						|
	lastnbytes += nbytes;	/* change nr of last all. bytes	*/
 | 
						|
	nfreebytes -= nbytes;	/* less or more free bytes	*/
 | 
						|
	return lastalloc;
 | 
						|
}
 | 
						|
 | 
						|
/* to ensure that the alloc library package will not be loaded:	*/
 | 
						|
/*ARGSUSED*/
 | 
						|
free(p)
 | 
						|
	char *p;
 | 
						|
{}
 | 
						|
 | 
						|
init_mem()
 | 
						|
{
 | 
						|
	firstfreeb = sys_break(0);
 | 
						|
	/* align the first memory unit to ALIGNSIZE ???	*/
 | 
						|
	if ((long) firstfreeb % ALIGNSIZE != 0) {
 | 
						|
		register char *fb = firstfreeb;
 | 
						|
 | 
						|
		fb = (char *)ALIGN((long)fb);
 | 
						|
		firstfreeb = sys_break(fb - firstfreeb);
 | 
						|
		firstfreeb = fb;
 | 
						|
		ASSERT((long)firstfreeb % ALIGNSIZE == 0);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#ifdef	DEBUG
 | 
						|
mem_stat()
 | 
						|
{
 | 
						|
	extern char options[];
 | 
						|
 | 
						|
	if (options['m'])
 | 
						|
		print("Total nr of bytes allocated: %d\n",
 | 
						|
			sys_break(0) - firstfreeb);
 | 
						|
}
 | 
						|
#endif	DEBUG
 | 
						|
#endif	OWNALLOC
 |