/*  DO NOT EDIT THIS FILE.

    It has been auto-edited by fixincludes from:

	"/usr/include/sys/spinlock.h"

    This had to be done to correct non-standard usages in the
    original, manufacturer supplied header file.  */

/*
 * @(#)spinlock.h: $Revision: 1.15.98.4 $ $Date: 95/12/06 00:08:07 $
 * $Locker: BERT $
 */

#ifndef	_SPINLOCK_INCLUDED
#define	_SPINLOCK_INCLUDED


#ifdef _KERNEL_BUILD
#include "../h/types.h"
#include <machine/cpu.h>
#else  /* ! _KERNEL_BUILD */
#include <sys/types.h>
#include <machine/cpu.h>
#endif /* _KERNEL_BUILD */

#ifndef	LOCORE

/*
 *  Lock.  Simple protection mechanism for protecting critical sections.  
 *  Building block for semaphores.
 *
 *  If either of these macros (LOCK_FIELDS or DEBUG_FIELDS) changes be
 *  sure to change the padding (sl_spares[]) in the struct lock if
 *  necessary to maintain cache line size.
 */

typedef union 	{
		int word;
		char byte[4];
	} sl_count_t;

	/* 
	 * sl_indirect  0 = sl_name_ptr is a ptr to name
	 *		1 = sl_name_ptr is a ptr to auxillary
	 *		    data structure
	 * sl_name_ptr	((ptr to name)>>2)
	 *	or	((ptr to aux data_structure)>>2)
	 *		NOTE; if the ptr won't fit in the 23 bits,
	 *		then zero is placed in sl_name_ptr.
	 */
#define LOCK_FIELDS /* 3 words */					\
 	int	sl_owner;	/* MP id of owning processor	*/	\
	sl_count_t sl_count;						\
	u_int	sl_indirect:1;	/* what does sl_name_ptr mean? */	\
	u_int	sl_name_ptr:23; /* 23 bit pointer */			\
	u_char	sl_turn;	/* arbitration			*/

#define LOCK16_FIELDS /* 5 words */					      \
	sl_count_t sl_count2[4];				      \
	u_char	sl_turn2[4];		/* 16-way */

#define DEBUG_FIELDS /* 8 words */					      \
	struct	{							      \
		unsigned short maj;					      \
		unsigned short min;					      \
	} sl_order;	        	/* (DEBUG) lock order		*/    \
	char *	sl_name;		/* (DEBUG) lock name            */    \
	struct lock	*sl_g_link;	/* (DEBUG) list of all locks	*/    \
	struct lock	*sl_link;	/* (DEBUG) link of owned locks	*/    \
	u_int	sl_lock_caller;	 	/* (DEBUG) last locker's rp 	*/    \
	u_int	sl_unlock_caller;	/* (DEBUG) last unlocker's rp	*/    \
	u_int	sl_start_lock;		/* (DEBUG) cr16 when lock taken */    \
	u_int	sl_start_stu;		/* (DEBUG) mpinfo->spintime_stu */

#define SPIN_TIMING_FIELDS /* 8 words */                                     \
	u_int sl_initialized_at;/* TIMING ticks_since_boot units         */  \
	u_int sl_spare2;	/* TIMING  XXX	 */  \
	u_int sl_lsumlo;	/* TIMING cr16 locked sum mod 4 Gig      */  \
	u_int sl_lsumhi;	/* TIMING cr16 locked sum div 4 Gig      */  \
	u_int sl_asumlo;	/* TIMING cr16 spinning sum mod 4 Gig	 */  \
	u_int sl_asumhi;	/* TIMING cr16 spinning sum div 4 Gig	 */  \
	u_int sl_nlocks;	/* TIMING number of instances locked 	*/   \
	u_int sl_nspins;	/* TIMING number of times had to spin	*/   

/*
 * These fields are used by some special gprof hooks for spinlocks.
 */
#define GPROF_SPECIAL_FIELDS /* 8 words */				    \
	u_int   sl_lock_caller;	/* caller who acquired spinlock last */     \
	u_int   sl_spares[7];

#ifndef _LOCK_T
#define _LOCK_T
typedef struct lock lock_t;
#endif /* _LOCK_T */

struct lock
{
	LOCK_FIELDS
	LOCK16_FIELDS
#ifdef SPIN_TIMING
	SPIN_TIMING_FIELDS
#endif /* SPIN_TIMING */
#if defined(GPROF) && defined(GP_SPIN_SPECIAL)
	GPROF_SPECIAL_FIELDS
#endif
};

#ifdef SPIN_TIMING_SUMMED
#define OVERFLOW_TICKS 1000
struct spin_ts_struct{	/* spin time save struct */
	u_int sts_initialized_at;

	u_int sts_total;
	u_int sts_n_overflow;
	double sts_sum_overflow;
	double sts_sum_sq_overflow;
	u_int sts_ticks[OVERFLOW_TICKS];
	u_int sts_over_ticks[OVERFLOW_TICKS]; /* 100 times as big */
};
#endif /* SPIN_TIMING_SUMMED */


#ifdef _KERNEL
typedef struct lock_nopad
{
	LOCK_FIELDS
	LOCK16_FIELDS
} lock_nopad_t;
#endif /*_KERNEL */


#undef LOCK_FIELDS
#undef DEBUG_FIELDS

typedef	lock_t		*vm_lock_t;

#ifdef _KERNEL
typedef	struct {
	lock_t *saved;
} sv_lock_t;

extern	lock_t *sched_lock;
extern	lock_t *rpregs_lock;
extern	lock_t *activeproc_lock;
extern  lock_t *activethread_lock;
extern	lock_t	lock_init_lock;
extern	lock_t _spl_lock;
extern	lock_t *spl_lock;
extern	lock_t *semaphore_log_lock;
extern	lock_t *crash_monarch_lock;
extern	lock_t *callout_lock;
extern	lock_t *cred_lock;
extern	lock_t *vmsys_lock;
extern  lock_t *file_table_lock;
extern	lock_t *devvp_lock;
extern	lock_t *biodone_lock;
extern	lock_t *bbusy_lock;
extern	lock_t *ioserv_lock;
extern	lock_t *io_tree_lock;
extern	lock_t *dma_lock;
extern	lock_t *v_count_lock;
extern	lock_t *unrm_table_lock;
extern	lock_t *inode_lock;
extern  lock_t *inode_move_lock;
extern  lock_t *rootvfs_lock;
extern	lock_t *lpmc_log_lock;
extern	lock_t *itmr_sync_lock;
extern	lock_t *itmr_state_lock;
extern	lock_t *pdce_proc_lock;
extern	lock_t *pfail_cntr_lock;
extern	lock_t *dnlc_lock;
extern	lock_t *audit_spinlock;
extern	lock_t *time_lock;
extern	lock_t *space_id_lock;
extern  lock_t *lofs_lo_lock;
extern  lock_t *lofs_lfs_lock;
extern  lock_t *lofs_li_lock;

/* networking spinlocks */
extern	lock_t *netisr_lock;
extern	lock_t *ntimo_lock;
extern	lock_t *bsdskts_lock;
extern	lock_t *mbuf_lock;
extern	lock_t *nm_lock;

/* NFS spinlock */
extern	lock_t *nfs_exi_lock;

/* Network Trace/Log spinlocks */
extern	lock_t *log_mask_lock;
extern	lock_t *log_que_lock;
extern	lock_t *trace_mask_lock;
extern	lock_t *trace_que_lock;

extern	lock_t *alloc_spinlock();

/*
 * Locking operations.  
 */
#ifdef _KERNEL_BUILD
#include <machine/inline.h>
#include <machine/psl.h>
#else /* _KERNEL_BUILD */
#include <machine/inline.h>
#include <machine/psl.h>
#endif /* _KERNEL_BUILD */


#ifdef	WEAKLY_ORDERED
	Error:  The implementation of the software mutual exclusion
	algorithms for spinlock primitives depends on strongly ordered
	accesses to the sl_count field in the lock_t structure.
	Appropriate ordering hints need to be added to these algorithms.
#endif	/* WEAKLY_ORDERED */

/*
 * The following "SL_" macros are  for use by spinlock.c
 * Mostly by the spin-waiting code and the debug "C"
 * versions.
 */

#define SL_CELLS_PW	4	/* Cells per word */
/*
 * The SL_NLKWRDS2 value tells us how many of the 
 * secondary lock words are being used (although
 * 4 are always defined.  If you have less than 5
 * processors, you can set SL_NLKWRDS2 to 1 which
 * forces all the secondary locks into the same
 * word.
 * NB: SL_NLKWRDS2 can never be greater than 4
 */
#define SL_NLKWRDS2	4	/* Secondary lock words (of 4) IN USE */
/* #define SL_NLKWRDS2	2	/* TEST - forces all into 2 words  */
/* #define SL_NLKWRDS2	1	/* TEST - forces all into 1 word  */

	/*
 	 * For sl_count lock
 	 */
#define SL_HAVE_LOCK(LOCK,SPU)\
	SL_HAVE_LOCKWORD(((LOCK)->sl_count),SPU%SL_CELLS_PW)
#define SL_TRY_LOCK(LOCK,SPU)\
	SL_TRY_LOCKWORD(((LOCK)->sl_count),SPU%SL_CELLS_PW)
#define SL_FREE_LOCK(LOCK,SPU)\
	SL_FREE_LOCKWORD(((LOCK)->sl_count),SPU%SL_CELLS_PW)

	/*
 	 * For sl_count2 lock
 	 */
#define SL_HAVE_LOCK2(LOCK,SPU)\
	SL_HAVE_LOCKWORD(((LOCK)->sl_count2[SPU % SL_NLKWRDS2]),SPU/SL_NLKWRDS2)
#define SL_TRY_LOCK2(LOCK,SPU)\
	SL_TRY_LOCKWORD(((LOCK)->sl_count2[SPU % SL_NLKWRDS2]),SPU/SL_NLKWRDS2)
#define SL_FREE_LOCK2(LOCK,SPU)\
	SL_FREE_LOCKWORD(((LOCK)->sl_count2[SPU % SL_NLKWRDS2]),SPU/SL_NLKWRDS2)

	/*
 	 * Locking by byte number
 	 */
#define	SL_HAVE_LOCKWORD(LOCKWORD, BYTENUM)\
		((LOCKWORD).word == SL_BYTE_SHIFT(BYTENUM))
#define	SL_LOCK_CELL(LOCKWORD, BYTENUM)\
		(&((LOCKWORD).byte[BYTENUM]))
#define	SL_TRY_LOCKWORD(LOCKWORD, BYTENUM)\
		(*SL_LOCK_CELL(LOCKWORD, BYTENUM) = 1)
#define	SL_FREE_LOCKWORD(LOCKWORD, BYTENUM)\
		(*SL_LOCK_CELL(LOCKWORD, BYTENUM) = 0)

#ifndef NBBY
#define NBBY 8
#else
#if NBBY != 8
Game Over.  Some fundamental changes are in store
#endif /* Tilt */
#endif /* NBBY */


#define SL_BYTE_SHIFT(INDEX)	(1<<(SL_BYTE_POS(INDEX)*NBBY))
#ifdef	_BIG_ENDIAN
#define	SL_BYTE_POS(INDEX)	(((sizeof(((lock_t *)0)->sl_count))-1)-(INDEX))
#else	/* ! _BIG_ENDIAN */
#define	SL_BYTE_POS(INDEX)	(INDEX)
#endif	/* ! _BIG_ENDIAN */


#define	DISABLE_INT(VAR)	_RSM(PSW_I, VAR)
#define	ENABLE_INT(VAR)		((PSW_I & VAR) ? (_SSM(PSW_I, 0),0) : 0 )
#define	INTS_ENABLED(VAR)	(_RSM(0, VAR), (VAR & PSW_I))
#define	INTS_DISABLED(VAR)	(_RSM(0, VAR), !(VAR & PSW_I))

#define spinlocks_held()	(getproc_info()->spinlock_depth)

#define TERMLOCK(x)

/*
      Lower overhead spinlocks.
*/

extern u_int spinlock_usav();
#define SPINLOCK_USAV(lock, context)	context = spinlock_usav(lock)
#define SPINUNLOCK_USAV(lock, context)	spinunlock_usav(lock, context)
#define CONVERT_USAV(context)  ((void)convert_usav(context))


extern int uniprocessor;

#define MP_SPINLOCK_USAV(lock, context)		\
		if (!uniprocessor) SPINLOCK_USAV(lock,context)
#define MP_SPINUNLOCK_USAV(lock, context)	\
		if (!uniprocessor) SPINUNLOCK_USAV(lock, context)



/*
 *  The sleep/wakeup race is protected with spinlocks.
 *
 *  get_sleep_lock()/MP_GET_SLEEP_LOCK() will acquire the appropriate sleep lock
 *  for going to sleep in one indivisible step, without a "lost wakeup"
 *  occuring in between. They return the spinlock acquired. The caller
 *  can then release the spinlock, if desired, through a call to 
 *  MP_SPINUNLOCK()/spinunlock().
 *
 *  sleep_spinunlock()/MP_SLEEP_SPINUNLOCK() will release a specified spinlock
 *  after acquiring the sleep lock and before going to sleep.
 *  
 */
/*
 * MP_GET_SLEEP_LOCK() returns the lock address which may then be unlocked
 * using MP_SPINLOCK().
 */
#define MP_GET_SLEEP_LOCK(WCHAN)	(uniprocessor ?0:get_sleep_lock(WCHAN))


#define MP_SPINLOCK(lock)	(uniprocessor ? 0 : spinlock(lock))
#define MP_SPINUNLOCK(lock)	(uniprocessor ? 0 : spinunlock(lock))

#define	MP_AQUIRESPL_LOCK()	(uniprocessor ? 0 : aquirespl_lock())
#define	MP_RELEASESPL_LOCK()	(uniprocessor ? 0 : releasespl_lock())

#define MP_SLEEP_SPINUNLOCK(wchan,disp,lock) \
		sleep_spinunlock(wchan,disp,((uniprocessor)?(lock_t *)-1:lock))


#define	MP_SPINLOCKX(lock,ss)	(uniprocessor ? 0 : spinlockx(lock,ss))
#define	MP_SPINUNLOCKX(lock,ss)	(uniprocessor ? 0 : spinunlockx(lock,ss))

/* hashed spinlocks */
/*
 * Description:
 *
 * Hashed spinlocks are used typically when each instance of a 
 * particular data structure is to be protected by a spinlock and there
 * are several such instances. 
 * 
 * For eg: The vnode data structure. There are several instances of this 
 * in the system. The manipulation of the count field of any instance is 
 * to be protected by a spinlock. Using a single spinlock leads to a lot of 
 * contention. Using one spinlock per vnode is an overkill. A pool of hashed 
 * spinlocks can be used. 
 * 
 * The spinlock corresponding to an instance would then be chosen by hashing
 * on the address or some unique attribute of the instance.
 *
 * A pool of hashed spinlocks must be allocated using alloc_h_spinlock_pool()
 * with the appropriate spinlock order. Typically, this is done in the 
 * routine init_hashed_spinlocks(), called during system boot.
 * The pool id returned is one of the
 * parameters to be used for all the locking primitives. The locking 
 * primitives come in two flavors: the short version and the long version
 * (ends in _L). The long version gives the user some flexibility to 
 * choose his/her own hash macro. The short version uses the default hash
 * macro defined below. 
 *
 * All the locking primitives return a pointer to the hash lock acquired.
 * This is to be used as the parameter to MP_SPINUNLOCK in order to unlock 
 * the hash lock.
 */

typedef struct hash_sl_pool {
		unsigned int hash_sl_mask;
		int 	n_hash_spinlocks;
		int     padding[5];
		lock_t  **hash_sl_table;
	} pool_id_t;

/* declarations for pools currently in use */
extern pool_id_t *vn_h_sl_pool;
extern pool_id_t *sysv_h_sl_pool;
extern pool_id_t *reg_h_sl_pool;
extern pool_id_t *ft_h_sl_pool;
extern pool_id_t *chanq_h_sl_pool;
extern pool_id_t *pfd_h_sl_pool;

/* hash macro definitions. Add as necessary. */
#define DEFAULT_HASH_TYPE 	0
#define SINGLE_L_HASH_TYPE 	1
#define IO_HASH_TYPE  		2
#define SYSV_SEM_HASH_TYPE  	3
#define CHANQ_USER_HASH_TYPE  	4
#define CHANQ_KERNEL_HASH_TYPE  5

/* hash macros */
#define DEFAULT_HASH_MACRO(pool_id,addr) \
	(( ((int)addr>>15) ^ ((int)addr>>5) ) & pool_id->hash_sl_mask)
#define SINGLE_L_HASH_MACRO(pool_id,addr) 0
#define IO_HASH_MACRO(pool_id,addr)     \
	(((int)addr) & pool_id->hash_sl_mask)
#define SYSV_SEM_HASH_MACRO(pool_id,addr) \
	(((int)addr) & pool_id->hash_sl_mask)
#define CHANQ_KERNEL_HASH_MACRO(pool_id,addr) \
	(((((int)addr >> 15) ^ ((int)addr>>5)) & pool_id->hash_sl_mask))
#define CHANQ_USER_HASH_MACRO(pool_id,addr) \
	((((int)addr) ^ ((int)addr>>12)) & pool_id->hash_sl_mask)

/* extend this as necessary. NB: This expression is expanded at compile time */
#define MY_HASH_M(pool_id,addr,type) 			\
	((type == DEFAULT_HASH_TYPE) 			\
		? (DEFAULT_HASH_MACRO(pool_id,addr)) 	\
	: (type == SINGLE_L_HASH_TYPE)			\
		? (SINGLE_L_HASH_MACRO(pool_id,addr))	\
	: (type == IO_HASH_TYPE)                        \
		? (IO_HASH_MACRO(pool_id,addr))         \
	: (type == SYSV_SEM_HASH_TYPE)                  \
		? (SYSV_SEM_HASH_MACRO(pool_id,addr))   \
	: (type == CHANQ_USER_HASH_TYPE)		\
		? (CHANQ_USER_HASH_MACRO(pool_id,addr)) \
	: (type == CHANQ_KERNEL_HASH_TYPE)		\
		? (CHANQ_KERNEL_HASH_MACRO(pool_id,addr)) \
	: panic("Invalid hash type"))

/* hashlock primitives: short version */
#define MP_H_SPINLOCK(pool_id,addr,lockpp) \
		MP_H_SPINLOCK_L(pool_id,addr,lockpp,DEFAULT_HASH_TYPE)
#define MP_H_SPINLOCKX(pool_id,addr,lockpp,ssp) \
		MP_H_SPINLOCKX_L(pool_id,addr,lockpp,ssp,DEFAULT_HASH_TYPE)
#define MP_H_SPINLOCK_USAV(pool_id,addr,lockpp,contextp) \
	MP_H_SPINLOCK_USAV_L(pool_id,addr,lockpp,contextp,DEFAULT_HASH_TYPE)

#define h_spinlock(pool_id,addr,lockpp)	\
		h_spinlock_l(pool_id,addr,lockpp,DEFAULT_HASH_TYPE)
#define h_spinlockx(pool_id,addr,lockpp,ssp) \
		h_spinlockx_l(pool_id,addr,lockpp,ssp,DEFAULT_HASH_TYPE)
#define h_spinlock_usav(pool_id,addr,lockpp,contextp) \
		h_spinlock_usav_l(pool_id,addr,lockpp,contextp,DEFAULT_HASH_TYPE)	

/* NB: H_OWNS_SPINLOCK() and H_CSPINLOCK() "return" a value */
#define H_OWNS_SPINLOCK(pool_id,addr) \
		H_OWNS_SPINLOCK_L(pool_id,addr,DEFAULT_HASH_TYPE)
#define H_CSPINLOCK(pool_id,addr,lockpp) \
		H_CSPINLOCK_L(pool_id,addr,lockpp,DEFAULT_HASH_TYPE)
		

/* hashlock primitives: long version */
#define MP_H_SPINLOCK_L(pool_id,addr,lockpp,type) { 	\
		if (!uniprocessor) {			\
			*(lockpp) = 			\
				pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))];\
			spinlock(*(lockpp));		\
		}					\
	}

#define MP_H_SPINLOCKX_L(pool_id,addr,lockpp,ssp,type) {\
		if (!uniprocessor) {			\
			*(lockpp) =			\
				pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))];\
			spinlockx(*(lockpp),ssp);	\
		}					\
	}
#define h_spinlock_l(pool_id,addr,lockpp,type) { 	\
		*(lockpp) = 			     	\
			pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))];\
		spinlock(*(lockpp));		     	\
	}
#define h_spinlockx_l(pool_id,addr,lockpp,ssp,type)	{\
		*(lockpp) =				\
			pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))];\
		spinlockx(*(lockpp),ssp);		\
	}

#define MP_H_SPINLOCK_USAV_L(pool_id,addr,lockpp,contextp,type) { \
		if (!uniprocessor) {				\
			*(lockpp) = 				\
				pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))];\
			*(contextp)=spinlock_usav(*(lockpp));	\
		}						\
	}
#define	h_spinlock_usav_l(pool_id,addr,lockpp,contextp,type)	{\
		*(lockpp) = 					\
			pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))];\
		*(contextp)=spinlock_usav(*(lockpp));		\
	}

#define H_OWNS_SPINLOCK_L(pool_id,addr,type) 		\
    owns_spinlock(pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))])
#define H_CSPINLOCK_L(pool_id,addr,lockpp,type) 		\
    cspinlock((*(lockpp)=pool_id->hash_sl_table[(MY_HASH_M(pool_id,addr,type))]))



/* 
 * These are obsolete, all instances should be MP_<name> 
 * We should go through the code and remove these, but no time now.
 */

/* BEGIN OBSOLETE */

#define SPINLOCK(lock)		MP_SPINLOCK(lock)	/* OBSOLETE */
#define SPINUNLOCK(lock)	MP_SPINUNLOCK(lock)	/* OBSOLETE */

#define	AQUIRESPL_LOCK()	MP_AQUIRESPL_LOCK()	/* OBSOLETE */
#define	RELEASESPL_LOCK()	MP_RELEASESPL_LOCK()	/* OBSOLETE */

#define	SPINLOCKX(lock,ss)	MP_SPINLOCKX(lock,ss)	/* OBSOLETE */
#define	SPINUNLOCKX(lock,ss)	MP_SPINUNLOCKX(lock,ss)	/* OBSOLETE */
/* END OBSOLETE */


#define SPL_REPLACEMENT(lock,func,var)	if (uniprocessor) var=func(); \
					else spinlock(lock)
#define SPLX_REPLACEMENT(lock,var)	if (uniprocessor) splx(var); \
					else spinunlock(lock)
#define	UP_SPL7()		(uniprocessor ? spl7() : 0)
#define	UP_SPL6()		(uniprocessor ? spl6() : 0)
#define	UP_SPL5()		(uniprocessor ? spl5() : 0)
#define	UP_SPL2()		(uniprocessor ? spl2() : 0)
#define	UP_SPLX(var)		(uniprocessor ? splx(var) : 0)

#ifdef  SPINLOCK_DEBUG
#define PFAIL_DISABLE(X)        (X = pfail_disable())
#define PFAIL_ENABLE(X)         pfail_enable(X)
#else   /* ! SPINLOCK_DEBUG */
#define PFAIL_DISABLE(X)        (DISABLE_INT(X), X)
#define PFAIL_ENABLE(X)         ENABLE_INT(X)
#endif  /* ! SPINLOCK_DEBUG */

#define T_SPINLOCK(lock)	MP_ASSERT(owns_spinlock(lock),	\
	"Should own spinlock!")
#define TBAR_SPINLOCK(lock)	MP_ASSERT(!owns_spinlock(lock),	\
	"Can't own spinlock!")
#define DOT_SPINLOCK(lock)	DO_ASSERT(owns_spinlock(lock),	\
	"Should own spinlock!")
#define DOTBAR_SPINLOCK(lock)	DO_ASSERT(!owns_spinlock(lock),	\
	"Can't own spinlock!")

#define	T_SPL(SPL_LVL)						\
	DO_ASSERT(spl_bitcheck(SPL_LVL), "Spl not high enough")
#define	T_UPSPL(SPL_LVL)					\
	UP_ASSERT(spl_bitcheck(SPL_LVL), "Spl not high enough")

/*
 *  These spinlocks are only meaningful on an MP system
 */
#define vmemp_slock()		MP_SPINLOCK(vmsys_lock)
#define vmemp_sunlock()		MP_SPINUNLOCK(vmsys_lock)
#define vmemp_slockx()		MP_SPINLOCKX(vmsys_lock, &sema_state.lock)
#define vmemp_sunlockx()	MP_SPINUNLOCKX(vmsys_lock, &sema_state.lock)

/*
 *  These are the macro names used in the VM system
 *  Some day we can just rename everything to be clean.  For now...
 */
#define	vm_spinlock(SMP)	spinlock(SMP)
#define	vm_spinunlock(SMP)	spinunlock(SMP)
#define	vm_valulock(LOCK)		( owns_spinlock(LOCK) ? 0 : 1 )
#define vm_initlock(LOCK, ORDER, NAME)	{ LOCK = alloc_spinlock(ORDER, NAME); }

#endif	/* _KERNEL */
#endif	/* ! LOCORE */
#endif	/* ! _SPINLOCK_INCLUDED */
