/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ident	"$Header: proc.h 1.30 90/06/27 $"

#ifndef	_SYS_PROC_H_

/*
 * proc.h
 *	Memory resident process structure.
 *
 * All references to "quota" are removed.
 * Many flags used to block swapper are removed, using p_noswap instead.
 */

/* $Log:	proc.h,v $
 */


/*
 * structure of proc members which can be overlayed with process
 * exit statistics once the process is turning into a zombie.
 */
struct overlay {
	/*
	 * Quasi-static fields gated by proc_list.
	 */
	uid_t		pu_uid;		/* real UID */
	uid_t		pu_suid;	/* saved effective UID */
	gid_t		pu_sgid;	/* saved effective GID */
	short		pu_ndx;		/* proc idx for memall (due to vfork) */
	short		pu_idhash;	/* based on p_pid for kill+exit+... */
	/*
	 * Queue for swapout, based on proc index; zero terminates list 
	 * (swapper doesn't swap self).
	 */
	short		pu_swpq;		/* queue for swapout */
	/*
	 * Paging related fields.  Gated implicitly.
	 */
	short		pu_szpt;	/* # HW pages to hold page-table */
	size_t		pu_dsize;	/* # HW pages of text+data */
	size_t		pu_ssize;	/* # HW pages of stack */
	size_t 		pu_rssize; 	/* # user pages in Rset */
	size_t		pu_maxrss;	/* copy of u.u_limit[MAXRSS] */
	swblk_t		pu_swaddr;	/* disk addr of u area when swapped */
	/*
	 * Implementation specific paging fields.
	 */
	size_t		pu_rshand;	/* RS hand for replacement */
	long		pu_rscurr;	/* current RS size */

	struct itimerval pu_realtimer;	/* time of next alarm signal */
	int		pu_rtid;		/* real timer id */
};
/*
 * One structure allocated per active process. It contains all data needed
 * about the process while the process may be swapped out.
 *
 * Other per process data (user.h) is swapped with the process.
 */

typedef struct	proc	{
	/*
	 * Links used by run-Q's and sema Q's.
	 */
	struct	proc	*p_link;	/* linked list of running processes */
	struct	proc	*p_rlink;
	/*
	 * For processor/process affinity.
	 */
	short		p_affinity;	/* Engine proc must run on */
	short		p_engno;	/* Engine proc running on */
	/*
	 * Semaphore related fields.
	 */
	sema_t		*p_wchan;	/* event process is awaiting */
	caddr_t		p_yawc;		/* yet-another-wchan (see sleep()) */
	int		p_noswap;	/* count of reasons not to swap */
	/*
	 * Vfork related fields.
	 */
	sema_t		p_vfork;	/* vfork synchronization */
	struct	proc	*p_vflink;	/* parent->child chain */
	/*
	 * State variables, gated via p_state.
	 */
	lock_t		p_state;	/* lock for state info */
	char		p_usrpri;	/* user-prio based on p_cpu & p_nice */
	char		p_pri;		/* priority, negative is high */
	char		p_cpu;		/* cpu usage for scheduling */
	char		p_stat;		/* current process state */
	char		p_time;		/* resident time for scheduling */
	char		p_slptime;	/* time since last block */
	int		p_flag;		/* various flags; see below */
	long		p_pctcpu;	/* %cpu for this proc during p_time */
	short		p_cpticks;	/* ticks of cpu time */
	pid_t		p_ppid;		/* process id of parent */
	pid_t		p_mptpid;	/* pid of MP debugger */
	pid_t		p_pgrp;		/* name of process group leader */
	pid_t		p_sid;		/* name of session group leader */
	struct	proc	*p_pptr;	/* -> process structure of parent */
#define p_parent	p_pptr		/* SYS V */
	struct	session	*p_session;	/* session pointer */
	char		p_nice;		/* nice for cpu usage */
	char		p_fpa;		/* process using FPA? */
#define	FPA_NONE	0		/* no usage of the FPA entirely */
#define	FPA_HW		1		/* hardware usage of the FPA */
#define	FPA_SW		2		/* software emulation of the FPA */
#define	FPA_FRCSW	3		/* force the process to use the emulation (testing only) */
	/*
	 * Signal fields; also gated by p_state.
	 */
	char		p_mptstop;	/* reason for MP debugger stop */
	unchar		p_cursig;	/* current signal */
	sigset_t	p_sig;		/* signals pending to this process */
	sigset_t	p_sigmask;	/* current signal mask */
	sigset_t	p_sigignore;	/* signals being ignored */
	sigset_t	p_sigcatch;	/* signals being caught by user */
	/*
	 * Quasi-static fields gated by proc_list.
	 */
	pid_t		p_pid;		/* unique process id */
	/*
	 * Child/sibling fields; gated by parent.
	 */
	struct	proc	*p_cptr;	/* pointer to head of child list */
#define	p_child	p_cptr			/* SYS V */
	struct	proc	*p_sptr;	/* pointer to sibling processes */
#define	p_sibling	p_sptr		/* SYS V */
	sema_t		p_zombie;	/* for waiting on dead children */
	/*
	 * process group and session group linkage.
	 */
	struct	proc	*p_pgrpf;	/* forward pgroup link */
	struct	proc	*p_pgrpb;	/* backward pgroup link */
	struct	proc	*p_sessf;	/* forward session group link */
	struct	proc	*p_sessb;	/* backward session group link */
	/*
	 * Fields used only by child, then parent after wait() (ie, no gating)
	 */
	union {
		struct process_stats	pu_pst;
		struct overlay		pu_ovr;
	}		p_un;
	ushort		p_xstat;	/* Exit status for wait */
	/*
	 * Paging related fields.  Gated implicitly.
	 */
	sema_t		p_pagewait;	/* waiting for in-transit page */
	struct	proc	*p_spwait;	/* waiters list for in-transit page */
	unsigned	p_ptb1;		/* phys address of UL1PT for dispatch */
	struct	user	*p_uarea;	/* u-area kernel virtual address */
#ifdef	ns32000
	struct	pte	*p_upte;	/* point at U-area pte's for dispatch */
#endif	/* ns32000 */
	struct	pte	*p_ul2pt;	/* virtual address of UL2PT */
	struct	pte	*p_pttop;	/* top of UL2PT, for efficiency */

	/*
	 * Multi-process debugger process list.  Gated by proclist.
	 * Maintained as seperate list from p_cptr,p_sptr since
	 * intermediate process can exit.
	 */
	ushort		p_mptc;		/* multi-process trace child */
	ushort		p_mpts;		/* multi-process trace sibling */

	int		p_b1_rsvd[2];	/* reserved for b1 product */

	/*
	 * The following entry is used to keep track of asynchronous
	 * I/O request.
	 */
	struct	AIO	*p_aio;		/* ptr to async I/O structure */

	/*
         * The following space is reserved for future use.  If the
         * NEED arises to add another field to the proc structure, we
         * can use a portion of the p_pad space, thus maintaining binary
         * compatibility.  Also, in the unlikely event that we no longer
         * need an existing entry, the excess space should be returned to
         * p_pad (to maintain the exact size of the proc table).
         */
	unsigned char 	p_pad[4];
} proc_t ;

#define		p_uid		p_un.pu_ovr.pu_uid
#define		p_suid		p_un.pu_ovr.pu_suid
#define		p_sgid		p_un.pu_ovr.pu_sgid
#define		p_ndx		p_un.pu_ovr.pu_ndx
#define		p_idhash	p_un.pu_ovr.pu_idhash
#define		p_swpq		p_un.pu_ovr.pu_swpq
#define		p_szpt		p_un.pu_ovr.pu_szpt
#define		p_dsize		p_un.pu_ovr.pu_dsize
#define		p_ssize		p_un.pu_ovr.pu_ssize
#define 	p_rssize	p_un.pu_ovr.pu_rssize
#define		p_maxrss	p_un.pu_ovr.pu_maxrss
#define		p_swaddr	p_un.pu_ovr.pu_swaddr
#define		p_rshand	p_un.pu_ovr.pu_rshand
#define		p_rscurr	p_un.pu_ovr.pu_rscurr
#define		p_realtimer	p_un.pu_ovr.pu_realtimer
#define		p_rtid		p_un.pu_ovr.pu_rtid


#define	PIDHSZ		64
#define	PIDHASH(pid)	((pid) & (PIDHSZ - 1))

#ifdef	INKERNEL
struct	proc	*pfind();
extern	short	pidhash[PIDHSZ];	/* (indexs into proc table) */
extern	struct	proc *proc, *procNPROC;	/* the proc table itself */
extern	lock_t	proc_list;		/* proc-list locker */

/*
 * QUEUEDSIG(p) is true if process has a queued signal it should look at.
 */

#define	QUEUEDSIG(p)	((p)->p_sig && ((p)->p_flag&SDBG || \
			((p)->p_sig & ~((p)->p_sigignore | (p)->p_sigmask))))
#endif

/* affinity code */
#define	ANYENG -2

/* stat codes */
#define	SSLEEP	1		/* awaiting an event */
#define	SWAIT	2		/* (abandoned state) */
#define	SRUN	3		/* runnable (on runQ's) */
#define	SIDL	4		/* intermediate state in process creation */
#define	SZOMB	5		/* intermediate state in process termination */
#define	SSTOP	6		/* process being traced */
#define	SONPROC	7		/* process running on a processor */

/*
 * Flag codes.
 */

#define	SLOAD	0x00000001	/* in core */
#define	SSYS	0x00000002	/* swapper or pager (system) process */

#define	STRC	0x00000010	/* process is being traced */
#define	SWTED	0x00000020	/* tracing flag (has been seen by wait) */
#define	SWSIG	0x00000040	/* tracing flag (will signal parent )*/

#define	SVFORK	0x00000100	/* process resulted from vfork() */
#define	SNOVM	0x00000200	/* no vm, parent in a vfork() */
#define	SEXEC	0x00000400	/* processed has forked but not execed */

#define	SORPH	0x00001000	/* process is an orphaned process group */
#define	SIGWOKE	0x00002000	/* signal woke process up, not v_sema() */
#define	SWPSYNC	0x00004000	/* synch with swapper during swapout */
#define	SFSWAP	0x00008000	/* force swap self, swapper couldn't */

#define	SNOSWAP	0x00010000	/* process can't be swapped (set via syscall) */
#define	SNOAGE	0x00020000	/* don't age process priority */
#define	SMPDBGR	0x00040000	/* process is a multi-process debugger */
#define	SMPTRC	0x00080000	/* process debugged by a MP debugger */

#define	SMPSTOP	0x00100000	/* process is stopped for MP debugger */
#define	SMPWTED	0x00200000	/* MP debugger has seen stopped process */
#define	STRCSTP	0x00400000	/* process is stopped for old flavor debugger */
	/* STRCSTP is only read !!!!!!! */
#define	SNOPFF	0x00800000	/* process shouldn't auto-adjust resident-set */

#define SNWAKE	0x01000000	/* process can't be awakened by a signal */
				/* only valid if p_stat == SSLEEP */
#define SPOLL	0x02000000	/* process in a stream poll */

/*
 * SMPTRC is only turned on/off while holding both proc_list and process
 * state.  Thus holding either lock guarantees consistency of SMPTRC.
 */

/*
 * SFORK defines flags unconditionally inherited across fork.
 * SDBG defines flags that imply process is being debugged (traced). 
 */

#define	SFORK	(SLOAD|SNOSWAP|SNOAGE|SNOPFF|SORPH|SWSIG)
#define	SDBG	(STRC|SMPTRC)

/*
 * define priority to lock proc_list at
 */
#define SPL_PROC_LIST	SPLHI

#define	_SYS_PROC_H_
#endif	/* _SYS_PROC_H_ */
