/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	vm_umap.h,v $
 * Revision 1.1.2.4  92/06/19  11:02:41  Robert_Picco
 * 	Segmentation code
 * 	[92/06/18  21:09:13  Robert_Picco]
 * 
 * Revision 1.1.2.3  92/03/10  09:58:43  Ronald_Widyono
 * 	bmerge with AG
 * 	[92/03/09  23:44:00  Ronald_Widyono]
 * 
 * 	Remove UNIX_LOCKS conditional.  simple_lock_addr() handles everything
 * 	[92/03/04  16:11:33  Ronald_Widyono]
 * 
 * 	Use simple_lock_addr() macro when passing simple lock addresses.
 * 	Fixes broken RT kernel build.
 * 	[92/03/03  02:21:15  Ronald_Widyono]
 * 
 * Revision 1.1.2.2  92/02/26  15:56:48  Charles_Briggs
 * 	UBC merge.
 * 	[92/02/22  14:52:40  Charles_Briggs]
 * 
 * $EndLog$
 */
/*
 * @(#)$RCSfile: vm_umap.h,v $ $Revision: 1.1.2.4 $ (DEC) $Date: 92/06/19 11:02:41 $
 */
#ifndef	__VM_UMAP__
#define	__VM_UMAP__ 1
#include <kern/lock.h>
#include <sys/unix_defs.h>
#include <vm/vm_vlock.h>
#include <sys/param.h>

/*
 * user mode private map structure
 */

struct u_map_private {

	vm_size_t		um_maxvas;	/* Maximum VAS allowed */
	udecl_simple_lock_data	(,um_resource)	/* Protect resource info */
	vm_size_t		um_maxwired;	/* Max wired space allowed */
	vm_size_t		um_wired;	/* Pages wired */
						/* 
						 * For a working set model.
						 * Any other policy leads
						 * to complication when
						 * maintaining these fields.
						 */
	int			um_vpage;	/* vpages allocated */
	vm_size_t		um_maxrss;	/* Maximum rss allowed */
	vm_size_t		um_rss;		/* Resident pages in map */
	unsigned int		
						/* lock all future pages */
				um_lock_future:1,
						/* unloading all address sp */
				um_unload_all:1,
				:30;
	struct vm_vlock		*um_vlock;	/* Virtual space lock by K */
};

/*
 * The vm_mape_faultlock is called by a thread that has
 * the address map write locked.  An anchor means that this
 * entry can't be mutated.  The thread goes to sleep on the 
 * fault lock until the anchor count goes to zero.  
 */

#define	vm_mape_lockaddr(VME) simple_lock_addr((VME)->vme_faultlock)
		
#define vm_mape_faultlock(VME) {					\
	if ((VME)->vme_anchor) {					\
		usimple_lock(&(VME)->vme_faultlock);			\
		if ((VME)->vme_anchor) {				\
			(VME)->vme_mutate = 1;				\
			do {						\
				(void) mpsleep(				\
				(vm_offset_t) (VME),			\
				PZERO, "FAULT", FALSE,			\
				vm_mape_lockaddr(VME),			\
				MS_LOCK_ON_ERROR|MS_LOCK_SIMPLE);	\
			} while ((VME)->vme_anchor);			\
		}							\
		usimple_unlock(&(VME)->vme_faultlock);			\
	}								\
}

#define vm_mape_fault(VME) {						\
	usimple_lock(&(VME)->vme_faultlock);		 		\
	(VME)->vme_anchor++;						\
	usimple_unlock(&(VME)->vme_faultlock);				\
}

#define vm_mape_faultdone(VME) {					\
	usimple_lock(&(VME)->vme_faultlock);				\
	(VME)->vme_anchor--;						\
	if ((VME)->vme_anchor == 0 && (VME)->vme_mutate) {		\
		thread_wakeup((vm_offset_t) (VME));			\
		(VME)->vme_mutate = 0;					\
	}								\
	usimple_unlock(&(VME)->vme_faultlock);				\
}

#ifdef	KERNEL
extern boolean_t u_map_entry_delete_check(vm_map_t map, vm_map_entry_t ep, 
			vm_offset_t start, vm_offset_t end);
extern boolean_t u_map_entry_clip_check(vm_map_t map, vm_map_entry_t ep,
			vm_offset_t start, vm_offset_t end);
#endif	/* KERNEL */

#endif /* !__VM_UMAP__ */
