~kris/9p

9hist

fe68274bb8cac7ae435a941858cd312124d49016 — David du Colombier 31 years ago c8588c0
Plan 9 from Bell Labs 1995-09-10
5 files changed, 111 insertions(+), 2 deletions(-)

M pc/clock.c
M port/devcons.c
M port/portdat.h
M port/portfns.h
M port/proc.c
M pc/clock.c => pc/clock.c +1 -0
@@ 44,6 44,7 @@ clock(Ureg *ur, void *arg)
	hardclock();
	uartclock();
	mouseclock();
	randomclock();

	if(up && up->state == Running){
		if(anyready())

M port/devcons.c => port/devcons.c +105 -1
@@ 27,9 27,11 @@ static struct
	int	ctlpoff;
} kbd;


char	sysname[NAMELEN];

static ulong randomread(uchar*, ulong);
static void randomreset(void);

void
printinit(void)
{


@@ 330,6 332,7 @@ enum{
	Qpgrpid,
	Qpid,
	Qppid,
	Qrandom,
	Qswap,
	Qsysname,
	Qsysstat,


@@ 356,6 359,7 @@ Dirtab consdir[]={
	"pgrpid",	{Qpgrpid},	NUMSIZE,	0444,
	"pid",		{Qpid},		NUMSIZE,	0444,
	"ppid",		{Qppid},	NUMSIZE,	0444,
	"random",	{Qrandom},	0,		0664,
	"swap",		{Qswap},	0,		0664,
	"sysname",	{Qsysname},	0,		0664,
	"sysstat",	{Qsysstat},	0,		0666,


@@ 406,6 410,7 @@ readstr(ulong off, char *buf, ulong n, char *str)
void
consreset(void)
{
	randomreset();
}

void


@@ 642,6 647,9 @@ consread(Chan *c, void *buf, long n, ulong offset)
	case Qsysname:
		return readstr(offset, buf, n, sysname);

	case Qrandom:
		return randomread(buf, n);

	default:
		print("consread %lux\n", c->qid);
		error(Egreg);


@@ 879,3 887,99 @@ setterm(char *f)
	sprint(buf, f, conffile);
	ksetenv("terminal", buf);
}

static struct
{
	QLock;
	Rendez	r;
	uchar	buf[4096];
	uchar	*ep;
	uchar	*rp;
	uchar	*wp;
	uchar	next;
	uchar	bits;
	uchar	wakeme;
} rb;

ulong randomcount;

void
randomreset(void)
{
	rb.ep = rb.buf + sizeof(rb.buf);
	rb.rp = rb.wp = rb.buf;
}

/*
 *  produce random bits in a circular buffer
 */
void
randomclock(void)
{
	int i;
	uchar *p;

	i = rb.rp - rb.wp;
	if(i == 1 || i == (1 - sizeof(rb.buf)))
		return;

	rb.bits = (rb.bits<<2) ^ randomcount;
	rb.next += 2;
	if(rb.next != 8)
		return;

	rb.next = 0;
	*rb.wp ^= rb.bits;
	p = rb.wp+1;
	if(p == rb.ep)
		p = rb.buf;
	rb.wp = p;

	if(rb.wakeme)
		wakeup(&rb.r);
}

static int
notempty(void*)
{
	return rb.wp != rb.rp;
}

/*
 *  consume random bytes from a circular buffer
 */
static ulong
randomread(uchar *p, ulong n)
{
	int i, sofar;
	uchar *e;

	if(waserror()){
		qunlock(&rb);
		nexterror();
	}

	qlock(&rb);
	for(sofar = 0; sofar < n; sofar += i){
		i = rb.wp - rb.rp;
		if(i == 0){
			rb.wakeme = 1;
			sleep(&rb.r, notempty, 0);
			rb.wakeme = 0;
			continue;
		}
		if(i < 0)
			i = rb.ep - rb.rp;
		if(i > n)
			i = n;
		memmove(p + sofar, rb.rp, i);
		e = rb.rp + i;
		if(e == rb.ep)
			e = rb.buf;
		rb.rp = e;
	}
	qunlock(&rb);
	poperror();

	return n;
}

M port/portdat.h => port/portdat.h +1 -0
@@ 704,3 704,4 @@ extern int nsyscall;
extern Physseg physseg[];
extern ulong crasharea;
extern ulong crashend;
extern ulong randomcount;

M port/portfns.h => port/portfns.h +1 -0
@@ 216,6 216,7 @@ long		qiwrite(Queue*, void*, int);
long		qwrite(Queue*, void*, int);
void		qsetlimit(Queue*, int);
void		qnoblock(Queue*, int);
void		randomclock(void);
int		readnum(ulong, char*, ulong, ulong, int);
int		readstr(ulong, char*, ulong, char*);
void		ready(Proc*);

M port/proc.c => port/proc.c +3 -1
@@ 47,6 47,8 @@ char *statename[] =
	"Rendez",
};

ulong randomcount;

/*
 * Always splhi()'ed.
 */


@@ 183,7 185,7 @@ loop:
	 *  or one that hasn't moved in a while (load balancing).
	 */
	spllo();
	for(;;){
	for(randomcount++;;randomcount++){
		/*
		 *  Once a second we look for a long waiting process
		 *  in the lowest priority queue to make sure nothing