/*
 * jam 850321
 */

typedef struct kstathead
{
	char		*name;		/* Name of this group of statistics */
	short		nstats;		/* Number of statistics */
	struct kstat	*stats;		/* Statistics */
	short		version;	/* Version of kstat */
	short		statlen;	/* Size of kstat_t */
} kstathead_t;

typedef struct kstat
{
	long		count;		/* Number of counts */
	short		flags;		/* Flags field */
	char		*name;		/* Name of statistic */
} kstat_t;

#define KSTAT_TOTAL	0x0001		/* Total count */
#define KSTAT_CURRENT	0x0002		/* Current count */
#define KSTAT_MAX	0x0004		/* Maximum count at any time */
#define KSTAT_PREVNAME	0x0008		/* Use previous name */

#define KSTAT_1		1		/* Current version number */

#define KSTAT_DCLSTAT(name) \
		kstat_t	name
#define KSTAT_INITSTAT(name) \
		{ 0, KSTAT_TOTAL, "name" }

#define KSTAT_DCLMSTAT(name) \
		kstat_t	name/**/Total, name/**/Cur, name/**/Max
#define KSTAT_INITMSTAT(name) \
		{ 0, KSTAT_TOTAL, "name" }, \
		{ 0, KSTAT_CURRENT|KSTAT_PREVNAME, 0 }, \
		{ 0, KSTAT_MAX|KSTAT_PREVNAME, 0 }
#define KSTAT_HEAD(list,name) \
		kstathead_t list/**/_stathead = \
		{ \
			name, \
			sizeof(list/**/_statlist) / sizeof(kstat_t), \
			&list/**/_statlist, \
			KSTAT_1, \
			sizeof(kstat_t) \
		}

#define KSTAT_INCSTAT(list,name) \
		++list/**/_statlist.name.count
#define KSTAT_DECSTAT(list,name) \
		--list/**/_statlist.name.count
#define KSTAT_ADDSTAT(list,name,value) \
		list/**/_statlist.name.count += (value)
#define KSTAT_SUBSTAT(list,name,value) \
		list/**/_statlist.name.count -= (value)

#define KSTAT_INCMSTAT(list,name) \
		KSTAT_ADDMSTAT(list,name,1)
#define KSTAT_DECMSTAT(list,name) \
		--list/**/_statlist.name/**/Cur.count
#define KSTAT_ADDMSTAT(list,name,value) \
		list/**/_statlist.name/**/Total.count += (value), \
		(list/**/_statlist.name/**/Cur.count += (value)) > list/**/_statlist.name/**/Max.count ? \
			(list/**/_statlist.name/**/Max.count = list/**/_statlist.name/**/Cur.count) : 0
#define KSTAT_SUBMSTAT(list,name,value) \
		list/**/_statlist.name/**/Cur.count -= (value)
