~kris/9p

9hist

4dce8a6f8a3588338dbec74b131d5201c52cd8f7 — David du Colombier 24 years ago da7ee71
Plan 9 from Bell Labs 2002-08-22
M alphapc/clock.c => alphapc/clock.c +10 -0
@@ 58,6 58,16 @@ fastticks(uvlong* hz)
	return ticks;
}

/*  
 *  performance measurement ticks.  must be low overhead.
 *  doesn't have to count over a second.
 */
ulong
perfticks(void)
{
	return rpcc(nil);
}

void
timerset(uvlong)
{

M alphapc/dat.h => alphapc/dat.h +1 -3
@@ 146,9 146,7 @@ struct Mach
	vlong	cpuhz;			/* hwrpb->cfreq */
	ulong	pcclast;
	uvlong	fastclock;
	vlong	intrts;			/* time stamp of last interrupt */
	ulong	inidle;			/* fastticks in idlehands() since last slowtick */
	ulong	avginidle;		/* avg fastticks in idlehands() per slowtick */
	Perf	perf;			/* performance counters */

	int	tlbfault;		/* only used by devproc; no access to tlb */
	int	tlbpurge;		/* ... */

M alphapc/trap.c => alphapc/trap.c +0 -1
@@ 291,7 291,6 @@ trap(Ureg *ur)
	char buf[ERRMAX];
	int user, x;

	m->intrts = fastticks(nil);
	user = ur->status&UMODE;

	if(user){

M bitsy/clock.c => bitsy/clock.c +10 -0
@@ 162,3 162,13 @@ microdelay(int µs)
		}
	}
}

/*  
 *  performance measurement ticks.  must be low overhead.
 *  doesn't have to count over a second.
 */
ulong
perfticks(void)
{
	return timerregs->oscr;
}

M bitsy/dat.h => bitsy/dat.h +1 -3
@@ 133,13 133,11 @@ struct Mach
	int	load;
	int	intr;
	vlong	fastclock;		/* last sampled value */
	vlong	intrts;			/* time stamp of last interrupt */
	uvlong	inidle;			/* time spent in idlehands() */
	ulong	spuriousintr;
	int	lastintr;
	int	ilockdepth;
	ulong	inidle;			/* fastticks in idlehands() since last slowtick */
	ulong	avginidle;		/* avg fastticks in idlehands() per slowtick */
	Perf	perf;			/* performance counters */

	int	flushmmu;		/* make current proc flush it's mmu state */
	Proc	*pid2proc[31];		/* what proc holds what pid */

M mtx/clock.c => mtx/clock.c +10 -0
@@ 94,3 94,13 @@ fastticks(uvlong *hz)
		*hz = HZ;
	return m->ticks;
}

/*  
 *  performance measurement ticks.  must be low overhead.
 *  doesn't have to count over a second.
 */
ulong
perfticks(void)
{
	return m->ticks;
}

M mtx/dat.h => mtx/dat.h +1 -3
@@ 141,9 141,7 @@ struct Mach

	ulong	pcclast;
	uvlong	fastclock;
	vlong	intrts;			/* time stamp of last interrupt */
	ulong	inidle;			/* fastticks in idlehands() since last slowtick */
	ulong	avginidle;		/* avg fastticks in idlehands() per slowtick */
	Perf	perf;			/* performance counters */

	int	tlbfault;		/* only used by devproc; no access to tlb */
	int	tlbpurge;		/* ... */

M mtx/trap.c => mtx/trap.c +0 -1
@@ 214,7 214,6 @@ trap(Ureg *ureg)
	int ecode, user;
	char buf[ERRMAX], *s;

	m->intrts = fastticks(nil);
	ecode = (ureg->cause >> 8) & 0xff;
	user = (ureg->srr1 & MSR_PR) != 0;
	if(user)

M pc/clock.c => pc/clock.c +15 -0
@@ 43,3 43,18 @@ microdelay(int microsecs)
		microsecs = 1;
	aamloop(microsecs);
}

/*  
 *  performance measurement ticks.  must be low overhead.
 *  doesn't have to count over a second.
 */
ulong
perfticks(void)
{
	uvlong x;

	if(!m->havetsc)
		return ticks;
	rdtsc(&x);
	return x;
}

M pc/dat.h => pc/dat.h +1 -3
@@ 175,11 175,9 @@ struct Mach
	int	syscall;
	int	load;
	int	intr;
	uvlong	intrts;			/* time stamp of last interrupt */
	int	flushmmu;		/* make current proc flush it's mmu state */
	int	ilockdepth;
	ulong	inidle;			/* fastticks in idlehands() since last slowtick */
	ulong	avginidle;		/* avg fastticks in idlehands() per slowtick */
	Perf	perf;			/* performance counters */

	ulong	spuriousintr;
	int	lastintr;

M pc/i8253.c => pc/i8253.c +15 -0
@@ 322,3 322,18 @@ microdelay(int microsecs)
		microsecs = 1;
	aamloop(microsecs);
}

/*  
 *  performance measurement ticks.  must be low overhead.
 *  doesn't have to count over a second.
 */
ulong
perfticks(void)
{
	uvlong x;

	if(!m->havetsc)
		return m->ticks;
	rdtsc(&x);
	return x;
}

M pc/main.c => pc/main.c +0 -5
@@ 104,11 104,6 @@ main(void)
	initseg();
	links();
conf.monitor = 1;
{int x; uvlong start, end;
rdtsc(&start);
for(x = 0; x < 10000; x++) rdtsc(&end);
print("%lld\n", end-start);
}
	chandevreset();
	i8253link();
	pageinit();

M pc/trap.c => pc/trap.c +16 -11
@@ 249,19 249,24 @@ static char* excname[32] = {
};

/*
 *  keep histogram of interrupt service times (tops off at 1/100 second)
 *  keep histogram of interrupt service times
 */
void
intrtime(Mach *m, int vno)
intrtime(Mach*, int vno)
{
	uvlong now;
	ulong diff;
	ulong x = perfticks();

	diff = x - m->perf.intrts;
	m->perf.intrts = x;

	m->perf.inintr += diff;
	if(up == nil && m->perf.inidle > diff)
		m->perf.inidle -= diff;

	rdtsc(&now);
	diff = now - m->intrts;
	diff /= m->cpumhz;
	if(diff >= 1000)
		diff = 999;
	if(diff >= Ntimevec)
		diff = Ntimevec-1;
	intrtimes[vno][diff]++;
}



@@ 280,8 285,7 @@ trap(Ureg* ureg)
	Vctl *ctl, *v;
	Mach *mach;

	if(m->havetsc)
		 rdtsc(&m->intrts);
	m->perf.intrts = perfticks();
	user = 0;
	if((ureg->cs & 0xFFFF) == UESEL){
		user = 1;


@@ 304,8 308,6 @@ trap(Ureg* ureg)
		}
		if(ctl->eoi)
			ctl->eoi(vno);
		if(ctl->isintr && m->havetsc)
			intrtime(m, vno);

		/* 
		 *  preemptive scheduling.  to limit stack depth,


@@ 319,11 321,14 @@ trap(Ureg* ureg)
		if(up->preempted == 0)
		if(!active.exiting){
			up->preempted = 1;
			intrtime(m, vno);
			sched();
			splhi();
			up->preempted = 0;
			return;
		}
		if(ctl->isintr)
			intrtime(m, vno);
	}
	else if(vno <= nelem(excname) && user){
		spllo();

M port/devcons.c => port/devcons.c +8 -23
@@ 641,27 641,6 @@ consclose(Chan *c)
	}
}

/*
 *  calculate duty cycle for a processor (100-(%time in idlehands()))
 */
static int
dutycycle(Mach *mp)
{
	static ulong ticks;
	uvlong hz;
	int x;

	if(ticks == 0){
		fastticks(&hz);
		ticks = hz/HZ;
	}
	x = ticks - mp->avginidle;
	if(x < 0)
		return 0;
	x *= 100;
	return x/ticks;
}

static long
consread(Chan *c, void *buf, long n, vlong off)
{


@@ 778,7 757,7 @@ consread(Chan *c, void *buf, long n, vlong off)
		return 0;

	case Qsysstat:
		b = smalloc(conf.nmach*(NUMSIZE*9+1) + 1);	/* +1 for NUL */
		b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1);	/* +1 for NUL */
		bp = b;
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {


@@ 799,7 778,13 @@ consread(Chan *c, void *buf, long n, vlong off)
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, dutycycle(mp), NUMSIZE);
				readnum(0, bp, NUMSIZE,
					(mp->perf.avg_inidle*100)/mp->perf.period,
					NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE,
					(mp->perf.avg_inintr*100)/mp->perf.period,
					NUMSIZE);
				bp += NUMSIZE;
				*bp++ = '\n';
			}

M port/portdat.h => port/portdat.h +15 -0
@@ 24,6 24,7 @@ typedef struct Mhead	Mhead;
typedef struct Note	Note;
typedef struct Page	Page;
typedef struct Palloc	Palloc;
typedef struct Perf	Perf;
typedef struct Pgrps	Pgrps;
typedef struct PhysUart	PhysUart;
typedef struct Pgrp	Pgrp;


@@ 861,6 862,20 @@ struct Edfinterface {
	void		(*edfdeadline)(Proc *p);
};

/*
 *  performance timers, all units in perfticks
 */
struct Perf
{
	ulong	intrts;		/* time of last interrupt */
	ulong	inintr;		/* time since last clock tick in interrupt handlers */
	ulong	avg_inintr;	/* avg time per clock tick in interrupt handlers */
	ulong	inidle;		/* time since last clock tick in idle loop */
	ulong	avg_inidle;	/* avg time per clock tick in idle loop */
	ulong	last;		/* value of perfticks() at last clock tick */
	ulong	period;		/* perfticks() per clock tick */
};

/* queue state bits,  Qmsg, Qcoalesce, and Qkick can be set in qopen */
enum
{

M port/portfns.h => port/portfns.h +1 -0
@@ 202,6 202,7 @@ void		pageinit(void);
void		pagersummary(void);
void		panic(char*, ...);
Cmdbuf*		parsecmd(char *a, int n);
ulong		perfticks(void);
void		pexit(char*, int);
void		printinit(void);
int		procindex(ulong);

M port/proc.c => port/proc.c +22 -11
@@ 211,9 211,9 @@ runproc(void)
	Schedq *rq, *xrq;
	Proc *p, *l;
	ulong rt;
	uvlong start;
	ulong start, now;

	start = 0;
	start = perfticks();

	if ((p = edf->edfrunproc()) != nil)
		return p;


@@ 265,9 265,12 @@ loop:
				}
			}
		}
		if(start == 0)
			start = fastticks(nil);

		/* remember how much time we're here */
		idlehands();
		now = perfticks();
		m->perf.inidle += now-start;
		start = now;
	}

found:


@@ 306,8 309,6 @@ found:
		p->movetime = MACHP(0)->ticks + HZ/10;
	p->mp = MACHP(m->machno);

	if(start)
		m->inidle += fastticks(nil)-start;
	return p;
}



@@ 1235,7 1236,7 @@ void
accounttime(void)
{
	Proc *p;
	ulong n;
	ulong n, per;
	static ulong nrun;

	p = m->proc;


@@ 1244,6 1245,20 @@ accounttime(void)
		p->time[p->insyscall]++;
	}

	/* calculate decaying duty cycles */
	n = perfticks();
	per = n - m->perf.last;
	m->perf.last = n;
	if(per == 0)
		per = 1;
	m->perf.period = (m->perf.period*(HZ-1)+per)/HZ;

	m->perf.avg_inidle = (m->perf.avg_inidle*(HZ-1)+m->perf.inidle)/HZ;
	m->perf.inidle = 0;

	m->perf.avg_inintr = (m->perf.avg_inintr*(HZ-1)+m->perf.inintr)/HZ;
	m->perf.inintr = 0;

	/* only one processor gets to compute system load averages */
	if(m->machno != 0)
		return;


@@ 1253,10 1268,6 @@ accounttime(void)
	nrun = 0;
	n = (nrdy+n)*1000;
	m->load = (m->load*19+n)/20;

	/* calculate decaying duty cycle average */
	m->avginidle = (m->avginidle*(HZ-1)+m->inidle)/HZ;
	m->inidle = 0;
}

static void