~kris/9p

9hist

4e2e06df47b7a83960b79eba7db5ee0e909f21ca — David du Colombier 27 years ago 903a40d
Plan 9 from Bell Labs 1999-02-18
6 files changed, 162 insertions(+), 14 deletions(-)

M pc/archgeneric.c
M pc/clock.c
M pc/main.c
M port/devcons.c
M port/lib.h
M port/portfns.h
M pc/archgeneric.c => pc/archgeneric.c +1 -1
@@ 211,7 211,7 @@ void
cycletimerinit(void)
{
	wrmsr(0x10, 0);
	fasthz = 1000000LL*m->cpumhz;
	fasthz = m->cpuhz;
}

/*

M pc/clock.c => pc/clock.c +2 -0
@@ 38,9 38,11 @@ clockintr(Ureg* ureg, void*)
{
	Clock0link *lp;

	fastticks(nil);
	m->ticks++;
	if(m->proc)
		m->proc->pc = ureg->pc;
	fixtod();

	accounttime();
	if(kproftimer != nil)

M pc/main.c => pc/main.c +0 -1
@@ 153,7 153,6 @@ main(void)
	kbdinit();
	if(arch->clockenable)
		arch->clockenable();
print("arch %s\n", arch->id);
	procinit0();
	initseg();
	links();

M port/devcons.c => port/devcons.c +157 -12
@@ 350,6 350,7 @@ enum{
	Qhostdomain,
	Qhostowner,
	Qmsec,
	Qnsec,
	Qnull,
	Qpgrpid,
	Qpid,


@@ 378,6 379,7 @@ static Dirtab consdir[]={
	"hz",		{Qhz},		NUMSIZE,	0666,
	"key",		{Qkey},		DESKEYLEN,	0622,
	"msec",		{Qmsec},	NUMSIZE,	0444,
	"nsec",		{Qnsec},	NUMSIZE,	0664,
	"null",		{Qnull},	0,		0666,
	"pgrpid",	{Qpgrpid},	NUMSIZE,	0444,
	"pid",		{Qpid},		NUMSIZE,	0444,


@@ 393,10 395,111 @@ static Dirtab consdir[]={

ulong	boottime;		/* seconds since epoch at boot */

struct
{
	Lock;
	vlong	hz;		/* frequency of fast clock */
	vlong	last;		/* last reading of fast clock */
	vlong	off;		/* offset from epoch to last */
	vlong	lastns;		/* last return value from gettod */
	vlong	bias;		/* current bias */
	vlong	delta;		/* amount to add to bias each slow clock tick */
	int	n;		/* number of times to add in delta */
	int	i;		/* number of times we've added in delta */
} tod;

void
settod(vlong now, vlong delta, int n)
{
	ilock(&tod);
	tod.last = fastticks(nil);
	tod.off = now;
	tod.delta = delta;
	tod.n = n;
	tod.i = 0;
	iunlock(&tod);
}

// largest vlong devided by 10, 100, ...
static vlong vlmax[9] = {
	9223372036LL,
	92233720368LL,
	922337203685LL,
	9223372036854LL,
	92233720368547LL,
	922337203685477LL,
	9223372036854775LL,
	92233720368547758LL,
	922337203685477580LL,
};
static vlong vlmult[9] = {
	1000000000LL,
	100000000LL,
	10000000LL,
	1000000LL,
	100000LL,
	10000LL,
	1000LL,
	100LL,
	10LL,
};

vlong
gettod(void)
{
	vlong x;
	int i;

	ilock(&tod);
	if(tod.hz == 0)
		x = fastticks((uvlong*)&tod.hz);
	else
		x = fastticks(nil);
	x -= tod.last;

	/* convert to nanoseconds */
	for(i = 0; i < 9; i++)
		if(x < vlmax[i]){
			x *= vlmult[i];
			break;
		}
	x /= tod.hz;
	if(i > 0)
		x *= vlmult[9-i];

	/* convert to epoch */
	x += tod.off;

	/* add in bias */
	x += tod.bias;

	if(x < tod.lastns)
		x = tod.lastns;
	tod.lastns = x;
	iunlock(&tod);

	return x;
}

void
fixtod(void)
{
	ilock(&tod);
	if(tod.n > tod.i)
		tod.bias += tod.delta;
	iunlock(&tod);
}

long
seconds(void)
{
	return boottime + TK2SEC(MACHP(0)->ticks);
	vlong x;
	int i;

	x = gettod();
	x /= 1000000000LL;
	i = x;
	return i;
}

int


@@ 512,8 615,8 @@ consread(Chan *c, void *buf, long n, vlong off)
	char tmp[128];		/* must be >= 6*NUMSIZE */
	char *cbuf = buf;
	int ch, i, k, id, eol;
	vlong offset = off;
	uvlong ticks, fasthz;
	vlong offset = off, x;
	uvlong ticks;

	if(n <= 0)
		return n;


@@ 603,9 706,6 @@ consread(Chan *c, void *buf, long n, vlong off)
	case Qppid:
		return readnum((ulong)offset, buf, n, up->parentpid, NUMSIZE);

	case Qtime:
		return readnum((ulong)offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);

	case Qclock:
		k = offset;
		if(k >= 2*NUMSIZE)


@@ 618,7 718,10 @@ consread(Chan *c, void *buf, long n, vlong off)
		return n;

	case Qfastclock:
		ticks = fastticks(&fasthz);
		if(tod.hz == 0L)
			ticks = fastticks((uvlong*)&tod.hz);
		else
			ticks = fastticks(nil);

		k = offset;
		if(k >= 4*NUMSIZE)


@@ 626,7 729,7 @@ consread(Chan *c, void *buf, long n, vlong off)
		if(k+n > 4*NUMSIZE)
			n = 4*NUMSIZE - k;
		readvlnum(0, tmp, 2*NUMSIZE, ticks, 2*NUMSIZE);
		readvlnum(0, tmp+2*NUMSIZE, 2*NUMSIZE, fasthz, 2*NUMSIZE);
		readvlnum(0, tmp+2*NUMSIZE, 2*NUMSIZE, tod.hz, 2*NUMSIZE);
		memmove(buf, tmp+k, n);
		return n;



@@ 654,8 757,21 @@ consread(Chan *c, void *buf, long n, vlong off)
	case Qnull:
		return 0;

	case Qnsec:
		x = gettod();
		return readvlnum((ulong)offset, buf, n, x, 2*NUMSIZE);

	case Qmsec:
		return readnum((ulong)offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
		x = gettod();
		x /= 1000000LL;
		i = x;
		return readnum((ulong)offset, buf, n, i, NUMSIZE);

	case Qtime:
		x = gettod();
		x /= 1000000000LL;
		i = x;
		return readnum((ulong)offset, buf, n, i, NUMSIZE);

	case Qhz:
		return readnum((ulong)offset, buf, n, HZ, NUMSIZE);


@@ 731,6 847,7 @@ conswrite(Chan *c, void *va, long n, vlong off)
	int id, fd;
	Chan *swc;
	ulong offset = off;
	vlong f, nsec, delta;

	switch(c->qid.path){
	case Qcons:


@@ 781,9 898,37 @@ conswrite(Chan *c, void *va, long n, vlong off)
			return 0;
		if(n >= sizeof cbuf)
			n = sizeof cbuf - 1;
		memmove(cbuf, a, n);
		cbuf[n-1] = 0;
		boottime = strtoul(a, 0, 0)-TK2SEC(MACHP(0)->ticks);
		strncpy(cbuf, a, n);
		cbuf[n] = 0;
		nsec = strtol(cbuf, 0, 0);
		nsec *= 1000000000LL;
		settod(nsec, 0, 0);
		break;

	case Qfastclock:
		if(n<=0 || !iseve())
			return 0;
		if(n >= sizeof(cbuf))
			n = sizeof(cbuf)-1;
		strncpy(cbuf, a, n);
		cbuf[n] = 0;
		f = strtovl(cbuf, 0, 0);
		if(f <= 0L)
			error(Ebadarg);
		tod.hz = f;
		break;

	case Qnsec:
		if(n<=0 || !iseve())
			return 0;
		if(n >= sizeof cbuf)
			n = sizeof cbuf - 1;
		strncpy(cbuf, a, n);
		cbuf[n] = 0;
		nsec = strtovl(cbuf, &a, 0);
		delta = strtovl(a, &a, 0);
		n = strtol(a, &a, 0);
		settod(nsec, delta, n);
		break;

	case Qkey:

M port/lib.h => port/lib.h +1 -0
@@ 68,6 68,7 @@ extern	int	print(char*, ...);
 */
extern	long	strtol(char*, char**, int);
extern	ulong	strtoul(char*, char**, int);
extern	vlong	strtovl(char*, char**, int);
extern	char	etext[];
extern	char	edata[];
extern	char	end[];

M port/portfns.h => port/portfns.h +1 -0
@@ 96,6 96,7 @@ int		fault(ulong, int);
void		fdclose(int, int);
Chan*		fdtochan(int, int, int, int);
int		fixfault(Segment*, ulong, int, int);
void		fixtod(void);
void		flushmmu(void);
void		forkchild(Proc*, Ureg*);
void		forkret(void);