/* $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: vmmeter.h 1.11 89/08/07 $"

#ifndef	_SYS_VMMETER_H_

/*
 * Virtual memory related instrumentation
 */

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

/*
 * define CPU states
 */

#define	V_CPU_STATES	3

#define	V_CPU_IDLE		0
#define	V_CPU_USER		1
#define	V_CPU_KERNEL		2

struct vmmeter
{
	/*
	 * Misc. system statistics
	 */
#define	v_first	v_swtch
	ulong v_swtch;	/* context switches */
	ulong v_trap;	/* calls to trap */
	ulong v_syscall;	/* calls to syscall() */
	ulong v_intr;	/* device interrupts */
	/*
	 * Swap statistics
	 */
	ulong v_swpin;	/* swapins */
	ulong v_swpout;	/* swapouts */
	ulong v_pswpin;	/* pages swapped in */
	ulong v_pswpout;	/* pages swapped out */
	/*
	 * Paging  statistics
	 */
	ulong v_pgin_file;	/* pageins from a file (fod) */
	ulong v_pgin_swap;	/* pageins from swap */
	ulong v_pgout_file;	/* pageouts to a file */
	ulong v_pgout_swap;	/* pageouts to swap */
	ulong v_pgpgin_file;	/* pages paged in from a file (fod) */
	ulong v_pgpgin_swap;	/* pages paged in from swap */
	ulong v_pgpgout_file;	/* pages paged out to a file */
	ulong v_pgpgout_swap;	/* pages paged out to swap */
	ulong v_intrans;	/* intransit blocking page faults */
	ulong v_pgfrec;	/* page reclaims from free list */
	ulong v_pgdrec;	/* dirty page reclaims */
	ulong v_zfod;	/* pages zero filled on demand */
	ulong v_nffod;	/* number of file fod's created */
	ulong v_nzfod;	/* number of zfod's created */
	ulong v_realloc;	/* ptes realloc'd before reclaimed */
	ulong v_redofod;	/* ptes re-built to FOD (realloc'd pre-paged) */
	ulong v_faults;	/* total faults taken */
	ulong v_dfree;	/* pages freed by pageout daemon */
	ulong v_pffincr;	/* times that PFF increased process RSS */
	ulong v_pffdecr;	/* times that PFF decreased process RSS */
	ulong v_tlbflush;	/* number of explicit TLB flushes */
	/*
	 * Cpu time statistics
	 */
	ulong v_time[V_CPU_STATES];
	/*
	 * Tty statistics
	 */
	ulong v_rcvint;	/* tty receive interrupts */
	ulong v_xmtint;	/* tty transmit interrupts */
	ulong v_mdmint;	/* tty modem interrupts */
	ulong v_rawch;	/* no. of tty raw mode input chars */
	ulong v_canch;	/* no. of tty cooked (canon) input chars */
	ulong v_outch;	/* no. of tty chars output */
	/*
	 * Fork/Vfork statistics
	 */
	ulong v_cntfork;
	ulong v_cntvfork;
	ulong v_sizfork;
	ulong v_sizvfork;
	/*
	 * Exec statistics
	 */
	ulong v_cntexec;	/* number of execs */
	/*
	 * Path name translation statistics
	 */
	ulong v_lookup;		/* name translation calls */
	ulong v_iget;		/* inode reads */
	ulong v_dirblk;		/* directory reads */
	ulong v_symlink;		/* symbolic link traversals */
	ulong v_nc_hits;		/* hits in name cache */
	ulong v_nc_misses;		/* name cache misses */
	ulong v_nc_long_look;	/* long names tried to look up */
	ulong v_nc_long_enter;	/* long names tried to enter */
	ulong v_nc_lru_empty;	/* LRU list empty */
	ulong v_nc_purges;		/* number of purges of cache */
	ulong v_nc_badname;		/* # times name purge made bad name */
	/*
	 * System V IPC
	 */
	ulong v_msg;			/* system V msg operations */
	ulong v_sema;		/* system V semaphore operations */
	/*
	 * read/write stats (Sys V)
	 */
	ulong v_sysread;	/* read system calls */
	ulong v_syswrite;	/* write system calls */
	ulong v_readch;	/* chars transferred via read */
	ulong v_writech;	/* chars trasnferred via write */
	/*
	 * Buf Cache statistics
	 */
	ulong v_lread;	/* logical read count ie. bread?() */
	ulong v_lwrite;	/* logical write count ie. bwrite?() */
	ulong v_delayedwrite;	/* delayed write actually written */
			/* SysV lwrite = v_lwrite + v_delayedwrite */
	ulong v_bread;	/* number of reads actual to disk */
	ulong v_bwrite;	/* number of writes that call driver strat */
	ulong v_rdahead;	/* read ahead call count */
	ulong v_rainbc;	/* count of r.a. blks was already in bcache */
	ulong v_rawasted;	/* count of unused r.a. blks bcache dropped */
	ulong v_bhitra;	/* Hit and block was in because of r.a. */
	ulong v_bhitru;	/* Hit and block was in because of reuse */
	ulong v_bnotavail;	/* number of waits for unavailable buffer */
	/*
	 * Physio stats
	 */
	ulong v_phread;	/* Number of physio (read) driver strat calls */
	ulong v_phwrite;	/* Number of physio (write) drver strat calls */
	ulong v_phreadblks;	/* Number of blocks (DEV_BSIZE) read */
	ulong v_phwriteblks;	/* Number of blocks (DEV_BSIZE) write */

#define	v_last v_phwriteblks
};


/*
 * memory usage statistics.
 */
struct mem_stats
{
	/*
	 * These are updated every tick
	 */
	ulong m_freemem[2];	/* 64 bit sum of free memory in HW pages */
	ulong m_dirtymem[2];	/* 64 bit sum of dirty memory in HW pages */
	/*
	 * This is updated every second
	 */
	ulong m_totalvm;	/* total virtual memory in use */
};

#ifdef INKERNEL
extern struct mem_stats mem_stats;
#endif /* INKERNEL */


/*
 * Wait statistic defines
 */
#define PS_WAITS		4

#define	PS_W_IO			0
#define	PS_W_SWAP			1
#define	PS_W_PIO			2
#define	PS_W_PAGE			3

#define PS_SCALE	100


/*
 * process scheduling statistics.
 */

struct procstate {
	/*
	 * These are update on the fly by the appropriate routines.
	 *	all but ps_pagewait must be incremented and decremented using
	 *	atomic instructions, from the asm functions L_INCR and
	 *	L_DECR defined below.
	 */
	ulong ps_swoutq;	/* processes queued to be swapped out */
	ulong ps_swinq;		/* processes queued to be swapped in */
	ulong ps_pagewait;	/* processes in page wait */
					/* protected by MEM_LOCK */
	ulong ps_filewait;	/* processes waiting on filesystem I/O */
	ulong ps_physwait;	/* processes waiting on physical/raw I/O */
	/*
	 * The existence of wait time statistics here is a little tenuous.
	 * However, they must be kept globally and are related to the
	 * statistics above.
	 */
	ulong ps_cpuwait;	/* sum of: at each tick number of processors */
				/* idle, but processes waiting */
	ulong ps_wait[PS_WAITS]; /* Why processes were waiting at tick */
	/*
	 * This next set of counters are updated once per second by
	 * scanning the process table.
	 */
	ulong ps_onproc;	/* processes running on a processor */
	ulong ps_runq;		/* current length of run queue */
	ulong ps_fastwait;	/* processes sleeping at neg priority */
	ulong ps_sleep;		/* processes sleeping in memory */
	ulong ps_swap;		/* processes swapped */
	/*
	 * This next set of counters are updated once per second by
	 * scanning the process table.
	 */
	ulong ps_rqsum;		/* sum of run queue lengths */
	ulong ps_rqocc;		/* run queue occupancy: no. of seconds */
				/* at least one process is in the run queue */
	ulong ps_swinqsum;	/* sum of swap in "queue" lengths */
	ulong ps_swinqocc;	/* swap queue occupancy: no. of seconds at */
                                /* least one process is runnable and swapped */
	ulong ps_swoutqsum;	/* sum of swap out queue lengths */
	ulong ps_swoutqocc;	/* swap out queue occupancy: no. of seconds */
                                /* at least one process q'd to be swapped out */
};

#ifdef INKERNEL
extern struct procstate procstate;
#endif /* INKERNEL */

/*
 * Table overflow statistics. Fields are accessed behind the locks
 * used by the individual allocation procedures.
 */

struct resource_ovf {
	ulong	ov_inode;		/* inode table overflow */
	ulong	ov_file;		/* file table overflow */
	ulong	ov_mfile;		/* mfile table overflow */
	ulong	ov_proc;		/* proc table overflow */
	ulong	ov_ofile;		/* ofile extension table overflow */
	ulong	ov_fifo;		/* fifo table overflow */
	ulong	ov_dquot;		/* disk quota table overflow */
};

#ifdef	INKERNEL
extern struct resource_ovf resource_ovf;
#endif	/* INKERNEL */

#ifdef INKERNEL
#if !defined(lint)
/*
 * void L_INCR(addr)
 *	int *addr
 *
 * atomic add to addr
 */
asm L_INCR(addr)
{
%mem addr;
	movl	addr, %eax
	lock
	incl	(%eax)
}

/*
 * void L_INCR(addr)
 *	int *addr
 *
 * atomic decrement from addr
 */
asm L_DECR(addr)
{
%mem addr;
	movl	addr, %eax
	lock
	decl	(%eax)
}
#else
void L_DECR();
void L_INCR();
#endif /* lint */
#endif /* INKERNEL */

#define	_SYS_VMMETER_H_
#endif	/* _SYS_VMMETER_H_ */
