/* 
 * Copyright (c) 1986-1987 The Regents of the University of California.
 * All rights reserved.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * The above licensing information supersedes all licensing information
 * below.
 */

#ifndef HEAP_
#define HEAP_

/*
 *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
 *    Copying of this file is granted according to the provisions 
 *    specified in the file COPYING which must accompany this file.
 */


/*
 *		heap.h
 */

#define	qi(M)			(M + MIN_QUARTERWORD)
#define	qo(M)			(M - MIN_QUARTERWORD)
#define	hi(M)			(M + MIN_HALFWORD)
#define	ho(M)			(M - MIN_HALFWORD)

#ifdef NULL
#undef NULL
#endif
#define	NULL			MIN_HALFWORD

global	mword			mem[];
global	ptr			lo_mem_max;
global	ptr			hi_mem_min;

global	int			var_used;
global	int			max_var_used;
global	int			dyn_used;

#define	link(M)			mem[M].hh.hh1.rh
#define	info(M)			mem[M].hh.hh1.lh

global	ptr	 		avail;
global	ptr			mem_end;

ptr get_avail();


#ifdef	STAT
#define	fast_get_avail(M) \
	{M = avail; \
	if (M == NULL) M = get_avail(); \
	else {avail = link(M); link(M) = NULL; incr(dyn_used);}}
#else
#define	fast_get_avail(M) \
	{M = avail; \
	if (M == NULL) M = get_avail(); \
	else {avail = link(M); link(M) = NULL;}}
#endif

#ifdef STAT
#ifdef	VORTEX
#ifdef	NEWMEM
#define	free_avail(M) \
		new_free_avail(M);
#else	NEWMEM
#define	free_avail(M) \
	if (M >= MEM_TOP) \
		{link(M) = avail; avail = M; decr(dyn_used);}
#endif	NEWMEM
#else	VORTEX
#ifdef	NEWMEM
#define	free_avail(M) \
		new_free_avail(M);
#else	NEWMEM
#define free_avail(M) \
	{link(M) = avail; avail = M; decr(dyn_used);}
#endif	NEWMEM
#endif	VORTEX
#else	STAT
#ifdef	VORTEX
#ifdef	NEWMEM
#define	free_avail(M) \
		new_free_avail(M);
#else	NEWMEM
#define free_avail(M) \
	if (M >= MEM_TOP) \
		{link(M) = avail; avail = M;}
#endif	NEWMEM
#else	VORTEX
#ifdef	NEWMEM
#define	free_avail(M) \
		new_free_avail(M);
#else	NEWMEM
#define free_avail(M) \
	{link(M) = avail; avail = M;}
#endif	NEWMEM
#endif	VORTEX
#endif	STAT

int				flush_list();

#define	is_empty(M)		(link(M) == EMPTY_FLAG)
#define	EMPTY_FLAG		MAX_HALFWORD
#define	node_size		info
#define	llink(M)		info(M + 1)
#define	rlink(M) 		link(M + 1)

global	ptr	rover;

ptr		get_node();
int		free_node();

global	ptr	temp_ptr;

#define	zero_glue 		MEM_BOT
#define	fil_glue 		(zero_glue + GLUE_SPEC_SIZE)
#define	fill_glue 		(fil_glue + GLUE_SPEC_SIZE)
#define	ss_glue  		(fill_glue + GLUE_SPEC_SIZE)
#define	fil_neg_glue 		(ss_glue + GLUE_SPEC_SIZE)

#define	LO_MEM_STAT_MAX		(fil_neg_glue + GLUE_SPEC_SIZE - 1)

#define	page_ins_head 		(MEM_TOP)
#define	contrib_head  		(MEM_TOP - 1)
#define	page_head  		(MEM_TOP - 2)
#define	temp_head  		(MEM_TOP - 3)
#define	hold_head  		(MEM_TOP - 4)
#define	adjust_head		(MEM_TOP - 5)
#define	active  		(MEM_TOP - 7)
#define	align_head  		(MEM_TOP - 8)
#define	end_span  		(MEM_TOP - 9)
#define omit_template		(MEM_TOP - 10)
#define null_list		(MEM_TOP - 11)
#define	lig_trick  		(MEM_TOP - 12)
#define	garbage  		(MEM_TOP - 12)
#define backup_head 	    	(MEM_TOP - 13)


#define	HI_MEM_STAT_MIN		(MEM_TOP - 13)
#define	HI_MEM_STAT_USAGE	14

global int	init_mem();

#ifdef INIT
int		sort_avail();
#endif

#endif
