#ifdef __cplusplus
extern "C" {
/* (MRL) I have no idea for the prototypes of the functions in this file */
#endif
/*
 *		IX/370
 *		5667-126
 *	LICENSED MATERIALS - PROPERTY OF IBM
*	(c) Copyright 1985, 1986, 1989 IBM Corp.
*	(c) Copyright 1983, 1984, 1985, 1986,  1989 Locus Computing Corporation
 *	All Rights Reserved
 */

#ifndef H_SCCSID
#include <sccs.h>
#endif /* ~H_SCCSID */
H_SCCSID(@(#)inline.h	16.10	LCC)	/* Modified: 11:35:40 9/9/90 */

#ifndef _h_INLINE
#define _h_INLINE

/* 
 * Definitions of inlines, and macro replacements
 * for them if UNFAST (latter only scantily tested).
 */

#if	defined(NOLOCKCNT) || defined(NOCHECKS)
#define	lockinc(ip)
#define lockdec(ip)
#else   /* !(defined(NOLOCKCNT) || defined(NOCHECKS)) */
#define	lockinc(ip)	lockInc()
#define lockdec(ip)	lockDec()
#endif	/* !(defined(NOLOCKCNT) || defined(NOCHECKS)) */

#if	defined(NOCHECKS)
#define	_B_CHAIN_CHECK(bp)	/**/
#else	/* !defined(NOCHECKS) */
#define _B_CHAIN_CHECK(bp)	\
	if ((bp)->av_back->av_forw != (bp) || (bp)->av_forw->av_back != (bp)) \
		panic("Notavail: bad chain", (bp)); else
#endif	/* !defined(NOCHECKS) */

/* Notavailbody assumes that it is called at spl6() */
#define	Notavailbody(bp, lockflag) \
{ \
	_B_CHAIN_CHECK(bp); \
	(bp)->av_back->av_forw = (bp)->av_forw; \
	(bp)->av_forw->av_back = (bp)->av_back; \
	(bp)->av_forw = NULL; \
	if ( !( ((bp)->b_flags |= (lockflag)) & B_LOCKED) ) { \
		if ((bp)->b_flags & B_DELWRI) \
			freebufs.delwri--; \
		freebufs.total--; \
	} \
	(bp)->b_refcnt = 1; \
}

/* Change a buffer from being exclusively locked to being share locked.
 * N.B. the share bit is turned on before the exclusive bit is turned
 * off so that there's no window during which the buffer looks non-busy.
 * If we're at spl6 or higher the order the bits are flipped doesn't
 * matter.
 */
#define bxrelebody(bp)	\
	( (bp)->b_flags & B_DOWNGRADE \
	? ((bp)->b_flags |= B_SLOCK, (bp)->b_flags &= ~(B_XLOCK|B_DOWNGRADE)) \
	: 0 )

/*
 *  Inline code used to acquire and lock a file block token and an inode token.
 */
#define token_lock_body(fp) \
	(ft_lock(fp) && it_lock(fp->f_inode, (fp->f_flag & FWRITE)))

#define ft_lock(fp) \
	((fp->f_tcbdes == NULLTCB 	\
		     || (fp->f_flag&(FPRESENT|FTOKWNT)) == FPRESENT) \
	? ++fp->f_tlckcnt : acq_token(fp))

#define it_lock(ip, mod) \
	    ((((ip->i_flag&(IPRESENT|ITOKWNT)) == IMPRESENT) \
	    || (!mod && ((ip->i_flag&(IPRESENT|ITOKWNT)) == IRPRESENT))) \
	    ? ++ip->i_tlckcnt : iacq_token(ip, mod))

/*
 *  Inline code used to acquire and lock a file block token.
 */
#define ftk_lock_body(fp)						\
{	if (fp->f_tcbdes == NULLTCB ||					\
		(fp->f_flag&(FPRESENT|FTOKWNT)) == FPRESENT) {		\
		fp->f_tlckcnt++;					\
	} else acq_token(fp); /* get and lock file token */		\
}

/*
 *  Inline code used to acquire and lock an inode token.
 */
#define itk_lock_body(ip, mod)						\
{	if (((ip->i_flag&(IPRESENT|ITOKWNT)) == IMPRESENT) ||		\
	   (!mod && ((ip->i_flag&(IPRESENT|ITOKWNT)) == IRPRESENT))) {	\
		ip->i_tlckcnt++;					\
	} else iacq_token(ip,mod);	/* get and lock inode token */	\
}

/*
 *  Inline code used to unlock a file block token and an inode token.
 */
#define token_unlock_body(fp)						\
{	itk_unlock( (fp->f_inode) );					\
	ftk_unlock(fp);							\
}

/*
 *  Inline code used to unlock a file block token.
 */
#define ftk_unlock_body(fp)						\
{	if ( (--fp->f_tlckcnt == 0) && (fp->f_tcbdes != NULLTCB) &&	\
		(fp->f_flag&FTOKWNT)) {					\
		if (fp->f_wnttok > 0)					\
			wakeup((caddr_t)&(fp->f_wnttok));		\
		else							\
			prep_reltok(fp);				\
	}								\
}

/*
 *  Inline code used to unlock an inode token.
 */
#if ! defined(NOCHECKS)
#define itk_unlock_body(ip)						\
{	if (ip->i_tlckcnt == 0)						\
		panic("itk_unlock");					\
	if ( (--ip->i_tlckcnt == 0) && (ip->i_flag&ITOKWNT)) {		\
		if (ip->i_wnttok > 0)					\
			wakeup((caddr_t)&(ip->i_wnttok));		\
		else							\
			iprep_reltok(ip);				\
	}								\
}
#else /* defined(NOCHECKS) */
#define itk_unlock_body(ip)						\
{									\
	if ((--ip->i_tlckcnt == 0) && (ip->i_flag & ITOKWNT)) {		\
		if (ip->i_wnttok > 0)					\
			wakeup((caddr_t) &(ip->i_wnttok));		\
		else							\
			iprep_reltok(ip);				\
	}								\
}
#endif /* defined(NOCHECKS) */

#ifndef UNFAST
#ifndef CODE_COVERAGE
#define  geterror(bp)				\
{ if (bp->b_flags&B_ERROR)			\
	if ((u.u_error = bp->b_error)==0)	\
		u.u_error = EIO;		\
}
#endif /* ~CODE_COVERAGE */

/* Note: this trick only works if buffers are not mapped */
#define	 clrbuf(bp)				\
{	bzero( (bp)->b_un.b_addr, BSIZE );	\
	(bp)->b_resid = 0;			\
}

#define  token_lock(fp)		token_lock_body( (fp) )
#ifndef CODE_COVERAGE	/* Macros which contain if|for|while. */
#define  ftk_lock(fp)		ftk_lock_body( (fp) )
#define  itk_lock(ip, mod)	itk_lock_body( (ip), (mod) )
#endif /* ~CODE_COVERAGE */

#define  token_unlock(fp)	token_unlock_body( (fp) )
#ifndef CODE_COVERAGE	/* Macros which contain if|for|while. */
#define  ftk_unlock(fp)		ftk_unlock_body( (fp) )
#define  itk_unlock(ip)		itk_unlock_body( (ip) )
#endif /* ~CODE_COVERAGE */

#define	GETF(fp, fd) \
	if ((unsigned)(fd) >= NOFILE || ((fp) = u.u_ofile[fd]) == NULL) { \
		u.u_error = EBADF; \
		return; \
	} else

#define	ISSIG(p) (((p)->p_sig.sigs[0] || (p)->p_sig.sigs[1]) \
		 && ((p)->p_flag&STRC \
		    || ((p)->p_sig.sigs[0] & (~((p)->p_sigignore.sigs[0] | (p)->p_sigmask.sigs[0]) | sigmask(SIGCHLD))) \
		    || ((p)->p_sig.sigs[1] & ~((p)->p_sigignore.sigs[1] | (p)->p_sigmask.sigs[1]))) \
		 && issig())

#define Notavail(bp, lockflag)		Notavailbody( (bp), (lockflag) )

#define bxrele(bp)		bxrelebody(bp)

#else  /* UNFAST */

#define	GETF(fp, fd)  \
	if ( ((fp) = getf(fd)) == NULL) { \
		return; \
	} else

#define	ISSIG(p)	issig(p)

#endif	/* UNFAST */

#define notavail(bp)		Notavail( (bp), B_XLOCK )

#endif  /* ~_h_INLINE */
#ifdef __cplusplus
}
#endif
