/*
 * $Header: netmp.h,v 1.9.98.2 96/04/18 15:52:17 indnetwk Exp $
 * $Source: /usr/local/kcs/sys.DAVIS_800/net/RCS/netmp.h,v $
 * $Revision: 1.9.98.2 $		$Author: indnetwk $
 * $State: Exp $		$Locker: indnetwk $
 * $Date: 96/04/18 15:52:17 $
 */

#ifndef _SYS_NETMP_INCLUDED
#define _SYS_NETMP_INCLUDED

#ifdef _KERNEL_BUILD
#include "../h/semglobal.h"
#include "../h/spinlock.h"
#include "../h/sem_beta.h"
#include "../h/rw_lock.h"
#include "../h/malloc.h"
#include "../h/mp.h"
#else  /*  !_KERNEL_BUILD  */
#include <sys/semglobal.h>
#include <sys/spinlock.h>
#include <sys/sem_beta.h>
#include <sys/rw_lock.h>
#include <sys/mp.h>
#endif /* _KERNEL_BUILD */


static char *	inpcb_name = "inpcb_rc_lock";

typedef	lock_t *simple_lock_t, *simple_lock_data_t;
typedef b_sema_t sock_lock_data_t, *sock_lock_t;

#ifdef _KERNEL_BUILD

/* 
 *  The delay field, RW_DELAY, indicates whether the process is to busy-wait
 *  for a little while before blocking.  This is done on the chance
 *  that the lock being waited on might become valid in this
 *  short period of time and thus avoiding the overhead of context
 *  switches.  This helps performance a lot, specially on a busy system.
 */

#define rw_lockinit(lock, order, name) { \
	lock_init3(lock, TRUE, RW_DELAY, TRUE, order, name);  \
 	}

#define alloc_spinlock_nowait(lockptr,name, order)     { \
	MALLOC(*lockptr,lock_t *, sizeof(lock_t),M_SPINLOCK,M_NOWAIT|M_ALIGN); \
	if (*lockptr)					\
		initlock(*lockptr, order, name); \
}
#endif /* _KERNEL_BUILD */


#define VAGUE_STATS	0

#define LOCK_ASSERT(string, cond)

#define LOCK_NETSTATS	 0

#if	LOCK_NETSTATS
#define NETSTAT_LOCKINIT(lockp)	*lockp = alloc_spinlock(NETSTAT_LOCK_ORDER,"netstat_lock")

#define NETSTAT_LOCK(lockp)	MP_SPINLOCK(*lockp)
#define NETSTAT_UNLOCK(lockp)	MP_SPINUNLOCK(*lockp)

#else
#define NETSTAT_LOCKINIT(lockp)
#define NETSTAT_LOCK(lockp)
#define NETSTAT_UNLOCK(lockp)
#endif

#define NET_SPLNET(s)		{ if (uniprocessor) s = splnet(); }
#define NET_SPLX(s)		{ if (uniprocessor) splx(s); }
#define NET_SPLIMP(s)		{ if (uniprocessor) s = splimp(); }

/* LOCK ORDERS */
/* semaphores */
#define RAW_LOCK_ORDER          149
#define SOCKET_LOCK_ORDER	150
#define SOTIMEQ_LOCK_ORDER	200	/* must be less than SOCKET_LOCK_ORDER*/
#define ARP_LOCK_ORDER	        200	/* must be less than ROUTE_LOCK_ORDER */
#define INIFADDR_LOCK_ORDER	200	/* must be less than ROUTE_LOCK_ORDER */
#define IPFRAG_LOCK_ORDER       LAST_HELD_ORDER-100  

/* spinlocks */

/*
** The IF_LOCK_ORDER must be less then the SEMAPHORE_LOCK_ORDER
*/
#define INHEAD_LOCK_ORDER	200	/* must be less than ROUTE_LOCK_ORDER */
					/* and INPHASH_LOCK_ORDER	      */
#define INPHASH_LOCK_ORDER	250
#define ROUTE_LOCK_ORDER	300     /* must be lower than INPCB_RTHASH */  
#define INPCB_RTHASH_LOCK_ORDER 350
#define AC_LOCK_ORDER			LAST_HELD_ORDER-400
#define IF_LOCK_ORDER			LAST_HELD_ORDER-350

#define IFQ_LOCK_ORDER			LAST_HELD_ORDER-100
#define INPCBRC_LOCK_ORDER		LAST_HELD_ORDER-100
#define TCP_GLOBALS_LOCK_ORDER		LAST_HELD_ORDER-100
#define IP_GLOBALS_LOCK_ORDER		LAST_HELD_ORDER-100
#define UNP_GLOBALS_LOCK_ORDER		LAST_HELD_ORDER-100
#define NETSTAT_LOCK_ORDER		LAST_HELD_ORDER-100
#define IF_STAT_LOCK_ORDER		LAST_HELD_ORDER-100
#define UNPCONN_LOCK_ORDER		LAST_HELD_ORDER-100
 
/*
**  The following are defined in semglobal.h
**  eventually all of these should be in semglobal.h (?)

  #define NM_LOCK_ORDER			LAST_HELD_ORDER-400
  #define XPORT_MIB_LOCK_ORDER		LAST_HELD_ORDER-100
  #define MBUF_LOCK_ORDER                 18     must be lower than MALLOC,
                                                 and higher than LAN LOCK 


**
*/

#endif /* _SYS_NETMP_INCLUDED */


