/* 
 * header file for collecting read/write trace info
 */

#define TRACEBUFSZ	8192	/* must be a power of 2 */

struct tracerecord {
	short pid;	/* pid of requesting process */
	short op;	/* operation */
	unsigned i_num;	/* g_number of accessed file */
	unsigned i_dev;	/* g_dev of accessed file */
	unsigned offset;	/* offset in file */
	unsigned count;	/* size of access */
	unsigned time;	/* TALC real clock timer */
};
#define fdes	offset	/* offset field is used for file descriptors */


struct trace_seg {
	struct tracerecord records[TRACEBUFSZ];
	int recd;
	int ptr;
	int write_begin, write_end;
};

struct tracesegstruct {
	int smid;
	int offset;
};

extern struct trace_seg traceseg;

#ifdef TAL
extern volatile unsigned *talcclock_addr;	/* copied from if_tal_timing.h*/
#define TIMER	(*talcclock_addr)
#else
#define TIMER  	(time.tv_sec)
#endif

extern struct proc *trace_recproc;
extern int global_tracevm_pid;

#define USESIGNAL	SIGUSR1
			/* which signal to use for trace_recproc*/

#define rec_trace(OP, GNUM, DEV, CBUF, COUNT)	{	\
	if (traceseg.recd) {	\
		int s = splimp();	\
		register int p = traceseg.ptr;	\
		register struct tracerecord *tp = &(traceseg.records[p]); \
		if (u.u_procp != trace_recproc) {	\
			tp->time = TIMER;  \
			tp->pid = (u.u_procp)->p_pid; tp->op = OP; \
			tp->i_num = GNUM; tp->i_dev = DEV; \
			tp->offset = (unsigned)(CBUF); tp->count = COUNT; \
			traceseg.ptr = (p+1) & (TRACEBUFSZ -1); \
			if (p == (TRACEBUFSZ/2 -1)) {	\
				traceseg.write_begin = 0;	\
				traceseg.write_end = (TRACEBUFSZ/2 -1);	\
				psignal(trace_recproc, USESIGNAL); \
			} else if (p == (TRACEBUFSZ - 1)) { \
				traceseg.write_begin = TRACEBUFSZ/2;	\
				traceseg.write_end = (TRACEBUFSZ - 1);	\
				psignal(trace_recproc, USESIGNAL); \
			} \
		} \
		(void)splx(s);	\
	} \
}

/* op for tracerecord */

// system calls
#define MYTRACE_READ		1
#define MYTRACE_WRITE		2
#define MYTRACE_READV		3     // not in trace
#define MYTRACE_WRITEV		4     // not in trace
#define MYTRACE_OPEN		5
#define MYTRACE_CLOSE		6
#define MYTRACE_CREATE		7
#define MYTRACE_LSEEK		8
#define MYTRACE_FTRUNCATE	9     // not in trace
#define MYTRACE_FSYNC		10    // not in trace 
#define MYTRACE_STAT		11
#define MYTRACE_IOCTL		12    // not in trace
#define MYTRACE_TRUNCATE	13    // not in trace
#define MYTRACE_FSTAT		14    // not in trace
#define MYTRACE_FDOPEN		15
#define MYTRACE_FDCREATE	16
#define MYTRACE_FCNTL		17
#define MYTRACE_UNLINK		18
#define MYTRACE_LINK		19    // not in trace
#define MYTRACE_FORK		20
#define MYTRACE_EXIT		21

// don't consider below record
#define MYTRACE_RDBEGIN		1001
#define MYTRACE_RDBEGIN2		2001
#define MYTRACE_WRBEGIN		1002
#define MYTRACE_BREADHIT	1003
#define MYTRACE_BREADMISS	1004
#define MYTRACE_RDEND		1005
#define MYTRACE_RDEND2			2005
#define MYTRACE_WREND		1006
#define MYTRACE_RARDBEGIN	1007
#define MYTRACE_BUSYWAIT	1008
#define MYTRACE_BUSYEND		1009
#define MYTRACE_CANDIDATE	1010
#define MYTRACE_REPLACE		1011

#define MYTRACE_RDHIT		1012
#define MYTRACE_BWREND		1013
#define MYTRACE_RWEND		1014

#define MYTRACE_RDBEGIN_INBREAD	1015
#define MYTRACE_RDEND_INBREAD	1016
#define MYTRACE_RDBEGIN_INBRDA	1017
#define MYTRACE_RDNEXT_INBRDA	1018
#define MYTRACE_RDEND_INBRDA	1019
#define MYTRACE_BWRBEGIN	1020
#define MYTRACE_BIODONE		1022

#define MYTRACE_TAKENOFF	1023
#define MYTRACE_REPLACE_TBU	1024
#define MYTRACE_MOVE_LASTHOLE	1025

#define MYTRACE_PREFETCH	1026

#define MYTRACE_FLIST_IGNORED	1027
#define MYTRACE_FLIST_TRACK	1028

#define MYTRACE_ADLIST_IGDESC	1029
#define MYTRACE_ADLIST_IGNORED 	1030
#define MYTRACE_ADLIST_TRACK 	1031

#define MYTRACE_TOUCHPREF	1032

#define REF_CAUGHT		3001
#define REF_FRECLAIM		3002
#define REF_RECLAIM		3003
#define REF_TRCLAIM		3004
#define REF_ZFOD		3005
#define REF_SWAPIN		3006
#define REF_PUTTOF		3007
#define REF_PAGEREP		3008

#define MYTRACE_TIMESTAMP	100

/* do not change the following. */
/* op for SIOCTALSTIMING call, as _clockstruct.smid value */

#define MYTRACE_GETTRSEG	14
#define MYTRACE_STARTTRACE	11
#define MYTRACE_STOPTRACE	10
#define MYTRACE_SETRECPROC	12
#define MYTRACE_SETVMTRACE	20


/* routine for recording last four chars of file names */

#define FOURCHAR(FNM)	last_four_char(FNM)

