~kris/9p

9hist

6affaa48b03cee73b8c4b312d63d1efb8d7315e7 — David du Colombier 34 years ago d885a1f
Plan 9 from Bell Labs 1992-06-02
M gnot/fns.h => gnot/fns.h +0 -1
@@ 36,7 36,6 @@ void	procrestore(Proc*);
void	procsave(Proc*);
void	procsetup(Proc*);
void	putkmmu(ulong, ulong);
void	restartprint(Alarm*);
void	restfpregs(FPsave*);
void	screeninit(void);
void	screenputc(int);

M gnot/main.c => gnot/main.c +0 -1
@@ 50,7 50,6 @@ main(void)
	initseg();
	grpinit();
	chaninit();
	alarminit();
	chandevreset();
	streaminit();
/*	serviceinit(); /**/

M pc/devuart.c => pc/devuart.c +0 -15
@@ 70,7 70,6 @@ struct Uart
	/* stream interface */
	Queue	*wq;		/* write queue */
	Rendez	r;		/* kproc waiting for input */
	Alarm	*a;		/* alarm for waking the kernel process */
 	int	kstarted;	/* kproc started */

	/* error statistics */


@@ 401,7 400,6 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud)
	}
}

static void	uarttimer(Alarm*);
static int	uartputc(IOQ *, int);
static void	uartstopen(Queue*, Stream*);
static void	uartstclose(Queue*);


@@ 416,19 414,6 @@ Qinfo uartinfo =
	"uart"
};

/*
 *  create a helper process per port
 */
static void
uarttimer(Alarm *a)
{
	Uart *up = a->arg;

	cancel(a);
	up->a = 0;
	wakeup(&up->iq->r);
}

static void
uartstopen(Queue *q, Stream *s)
{

M pc/main.c => pc/main.c +0 -1
@@ 32,7 32,6 @@ main(void)
	initseg();
	grpinit();
	chaninit();
	alarminit();
	chandevreset();
	streaminit();
	swapinit();

M port/alarm.c => port/alarm.c +43 -168
@@ 5,93 5,14 @@
#include	"fns.h"
#include	"io.h"

struct {
	Lock;
	Alarm	*tab;	/* table of all alarm structures */
	void	*list;	/* busy alarms */
	Rendez	r;
} alarmalloc;

Alarms	alarms;

Alarm*
alarm(int ms, void (*f)(Alarm*), void *arg)
{
	Alarm *a, *w, *pw;
	int s;

	if(ms < 0)
		ms = 0;
	a = newalarm();
	a->when = MACHP(0)->ticks+MS2TK(ms);
	a->f = f;
	a->arg = arg;
	s = splhi();
	lock(&alarmalloc);
	pw = 0;
	for(w=alarmalloc.list; w; pw=w, w=w->next){
		if(w->when > a->when)
			break;
	}
	insert(&alarmalloc.list, pw, a);
	unlock(&alarmalloc);
	splx(s);
	return a;
}
Rendez	alarmr;
Talarm	talarm;

void
cancel(Alarm *a)
{
	a->f = 0;
}

Alarm*
newalarm(void)
{
	int i;
	Alarm *a;

	for(i=0,a=alarmalloc.tab; i<conf.nalarm; i++,a++)
		if(a->busy==0 && a->f==0 && canlock(a)){
			if(a->busy){
				unlock(a);
				continue;
			}
			a->f = 0;
			a->arg = 0;
			a->busy = 1;
			unlock(a);
			return a;
		}
	panic("newalarm");
	return 0;	/* not reached */
}

/* allocate locks here since you can't allocate them at interrupt time (on the SGI) */
void
alarminit(void)
{
	int i;

	alarmalloc.tab = ialloc(conf.nalarm*sizeof(Alarm), 0);
	for(i=0; i<conf.nalarm; i++){
		lock(&alarmalloc.tab[i]);
		unlock(&alarmalloc.tab[i]);
	}
	lock(&alarmalloc);
	unlock(&alarmalloc);
	qlock(&alarms);
	qunlock(&alarms);
}

#define NA 10		/* alarms per wakeup */
void
alarmkproc(void *arg)
{
	int i, n;
	Alarm *a;
	void (*f)(void*);
	Alarm *alist[NA];
	ulong now;
	Proc *rp;
	int s;


@@ 100,40 21,6 @@ alarmkproc(void *arg)

	for(;;){
		now = MACHP(0)->ticks;

		s = splhi();
		lock(&alarmalloc);
		a = alarmalloc.list;
		if(a){
			for(n=0; a && a->when<=now && n<NA; n++){
				alist[n] = a;
				delete(&alarmalloc.list, 0, a);
				a = alarmalloc.list;
			}
			unlock(&alarmalloc);
			splx(s);

			/*
			 *  execute alarm functions outside the lock since they
			 *  might call alarm().
			 */
			f = 0;
			if(waserror()){
				print("alarm func %lux caused error %s\n", f, u->error);
			} else {
				for(i = 0; i < n; i++){
					f = alist[i]->f; /* avoid race with cancel */
					if(f)
						(*f)(alist[i]);
					alist[i]->busy = 0;
				}
				poperror();
			}
		}else{
			unlock(&alarmalloc);
			splx(s);
		}

		qlock(&alarms);
		while((rp = alarms.head) && rp->alarm <= now){
			if(rp->alarm != 0L){


@@ 151,7 38,7 @@ alarmkproc(void *arg)
		}
		qunlock(&alarms);

		sleep(&alarmalloc.r, return0, 0);
		sleep(&alarmr, return0, 0);
	}
}



@@ 161,90 48,78 @@ alarmkproc(void *arg)
void
checkalarms(void)
{
	ulong now;
	Proc *p;
	Alarm *a;
	ulong now;

	a = alarmalloc.list;
	p = alarms.head;
	now = MACHP(0)->ticks;

	if((a && a->when <= now) || (p && p->alarm <= now))
		wakeup(&alarmalloc.r);
	if(p && p->alarm <= now)
		wakeup(&alarmr);

	if(talarm.list == 0 || canlock(&talarm) == 0)
		return;

	for(;;) {
		p = talarm.list;
		if(p == 0)
			break;

		if(p->twhen == 0) {
			talarm.list = p->tlink;
			continue;
		}
		if(now < p->twhen)
			break;
		talarm.list = p->tlink;
		wakeup(p->trend);
	}

	unlock(&talarm);
}

ulong
procalarm(ulong time)
{
	Proc **l, *f;
	Proc **l, *f, *p;
	ulong when, old;

	old = TK2MS(u->p->alarm - MACHP(0)->ticks);
	if(time == 0){
		u->p->alarm = 0;
	p = u->p;
	old = TK2MS(p->alarm - MACHP(0)->ticks);
	if(time == 0) {
		p->alarm = 0;
		return old;
	}
	when = MS2TK(time);
	when += MACHP(0)->ticks;
	when = MS2TK(time)+MACHP(0)->ticks;

	qlock(&alarms);
	l = &alarms.head;
	for(f = *l; f; f = f->palarm){
		if(u->p == f){
	for(f = *l; f; f = f->palarm) {
		if(p == f){
			*l = f->palarm;
			break;
		}
		l = &f->palarm;
	}

	u->p->palarm = 0;
	if(alarms.head){
	p->palarm = 0;
	if(alarms.head) {
		l = &alarms.head;
		for(f = *l; f; f = f->palarm){
			if(f->alarm > when){
				u->p->palarm = f;
				*l = u->p;
		for(f = *l; f; f = f->palarm) {
			if(f->alarm > when) {
				p->palarm = f;
				*l = p;
				goto done;
			}
			l = &f->palarm;
		}
		*l = u->p;
		*l = p;
	}
	else
		alarms.head = u->p;
		alarms.head = p;
done:
	u->p->alarm = when;
	p->alarm = when;
	qunlock(&alarms);

	return old;			
}

/*
 * Insert new into list after where
 */
void
insert(List **head, List *where, List *new)
{
	if(where == 0){
		new->next = *head;
		*head = new;
	}else{
		new->next = where->next;
		where->next = new;
	}
		
}

/*
 * Delete old from list.  where->next is known to be old.
 */
void
delete(List **head, List *where, List *old)
{
	if(where == 0){
		*head = old->next;
		return;
	}
	where->next = old->next;
}


M port/devcons.c => port/devcons.c +1 -3
@@ 513,10 513,8 @@ consread(Chan *c, void *buf, long n, ulong offset)
			do{
				lock(&lineq);
				ch = getc(&kbdq);
				if(raw){
					unlock(&lineq);
				if(raw)
					goto Default;
				}
				switch(ch){
				case '\b':
					if(lineq.in != lineq.out){

M port/devip.c => port/devip.c +5 -5
@@ 1048,7 1048,7 @@ bsdoput(Queue *q, Block *bp)
	}

	/* collect into a single block */
	lock(q);
	qlock(&q->rlock);
	if(q->first == 0)
		q->first = pullup(bp, blen(bp));
	else{


@@ 1058,7 1058,7 @@ bsdoput(Queue *q, Block *bp)
	}
	bp = q->first;
	if(bp == 0){
		unlock(q);
		qunlock(&q->rlock);
		bsdclose(q);
		return;
	}


@@ 1066,12 1066,12 @@ bsdoput(Queue *q, Block *bp)
	/* look for 2 nulls to indicate stderr port and local user */
	luser = memchr(bp->rptr, 0, BLEN(bp));
	if(luser == 0){
		unlock(q);
		qunlock(&q->rlock);
		return;
	}
	luser++;
	if(memchr(luser, 0, bp->wptr - luser) == 0){
		unlock(q);
		qunlock(&q->rlock);
		return;
	}



@@ 1084,5 1084,5 @@ bsdoput(Queue *q, Block *bp)
	q->first = 0;
	bp->flags |= S_DELIM;
	PUTNEXT(q, bp);
	unlock(q);
	qunlock(&q->rlock);
}

M port/devscc.c => port/devscc.c +0 -1
@@ 103,7 103,6 @@ struct SCC
	/* stream interface */
	Queue	*wq;		/* write queue */
	Rendez	r;		/* kproc waiting for input */
	Alarm	*a;		/* alarm for waking the kernel process */
 	int	kstarted;	/* kproc started */

	/* idiot flow control */

M port/fault.c => port/fault.c +1 -0
@@ 17,6 17,7 @@ fault(ulong addr, int read)

	sps = u->p->psstate;
	u->p->psstate = "Fault";
	spllo();

	m->pfault++;
	for(;;) {

M port/pgrp.c => port/pgrp.c +2 -3
@@ 199,9 199,8 @@ resrcwait(char *reason)
	}
	if(u == 0)
		panic("resrcwait");
	u->p->state = Wakeme;
	alarm(1000, wakeme, u->p);
	sched();

	tsleep(&u->p->sleep, return0, 0, 1000);
	u->p->psstate = p;
}


M port/portdat.h => port/portdat.h +10 -8
@@ 1,4 1,3 @@
typedef struct Alarm	Alarm;
typedef struct Alarms	Alarms;
typedef struct Block	Block;
typedef struct Blist	Blist;


@@ 35,6 34,7 @@ typedef struct Rendez	Rendez;
typedef struct RWlock	RWlock;
typedef struct Segment	Segment;
typedef struct Stream	Stream;
typedef struct Talarm	Talarm;
typedef struct Waitq	Waitq;
typedef int    Devgen(Chan*, Dirtab*, int, int, Dir*);



@@ 71,14 71,10 @@ struct RWlock
	int	readers;		/* Count of readers in lock */
};

struct Alarm
struct Talarm
{
	List;
	Lock;
	int	busy;
	ulong	when;			/* may underflow in clock(); must be signed */
	void	(*f)(void*);
	void	*arg;
	Proc	*list;
};

struct Alarms


@@ 550,7 546,7 @@ struct Proc
	ulong	pc;			/* DEBUG only */

	Rendez	*r;			/* rendezvous point slept on */
	Rendez	sleep;			/* place for tsleep/syssleep/debug */
	Rendez	sleep;			/* place for syssleep/debug */
	int	notepending;		/* note issued but not acted on */
	int	kp;			/* true if a kernel process */
	Proc	*palarm;		/* Next alarm time */


@@ 561,6 557,11 @@ struct Proc
	ulong	rendtag;		/* Tag for rendezvous */ 
	ulong	rendval;		/* Value for rendezvous */
	Proc	*rendhash;		/* Hash list for tag values */

	ulong	twhen;
	Rendez	*trend;
	Proc	*tlink;

	/*
	 *  machine specific MMU goo
	 */


@@ 696,6 697,7 @@ extern	int	nrdy;
extern	char	sysname[NAMELEN];
extern	int	cpuserver;
extern  Ref	noteidalloc;
extern	Talarm	talarm;

#define	CHDIR		0x80000000L
#define	CHAPPEND 	0x40000000L

M port/portfns.h => port/portfns.h +0 -7
@@ 1,5 1,3 @@
Alarm*	alarm(int, void (*)(Alarm*), void*);
void	alarminit(void);
void	alarmkproc(void*);
Block*	allocb(ulong);
int	anyready(void);


@@ 9,7 7,6 @@ int	blen(Block *);
int	bround(Block *, int);
void	buzz(int, int);
void	cachepage(Page*, Image*);
void	cancel(Alarm*);
int	cangetc(void*);
int	canlock(Lock*);
int	canpage(Proc*);


@@ 73,7 70,6 @@ void	firmware(void);
int	fixfault(Segment*, ulong, int, int);
void	flowctl(Queue*, Block*);
void	flushmmu(void);
void	freealarm(Alarm*);
void	freeb(Block*);
int	freebroken(void);
void	freechan(Chan*);


@@ 133,7 129,6 @@ long	netread(Chan*, void*, long, ulong, Network*);
void	netstat(Chan*, char*, Network*);
int	netwalk(Chan*, char*, Network*);
void	netwstat(Chan*, char*, Network*);
Alarm*	newalarm(void);
Chan*	newchan(void);
Egrp*	newegrp(void);
Fgrp*	newfgrp(void);


@@ 236,7 231,6 @@ void	swapinit(void);
long	syscall(Ureg*);
void	tcpinit(void);
void	tsleep(Rendez*, int (*)(void*), void*, int);
void	twakeme(Alarm*);
void	uncachepage(Page*);
long	unionread(Chan*, void*, long);
void	unlock(Lock*);


@@ 246,7 240,6 @@ void	userinit(void);
ulong	userpc(void);
void	validaddr(ulong, ulong, int);
void*	vmemchr(void*, int, int);
void	wakeme(Alarm*);
void	wakeup(Rendez*);
void	rlock(RWlock*);
void	runlock(RWlock*);

M port/proc.c => port/proc.c +22 -36
@@ 317,29 317,32 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
}

void
tsleep(Rendez *r, int (*f)(void*), void *arg, int ms)
tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms)
{
	Alarm *a;
	Proc *p;
	int s;
	ulong when;
	Proc *p, *f, **l, **i;

	p = u->p;
	sleep1(r, f, arg);
	if(p->notepending == 0){
		a = alarm(ms, twakeme, r);
		sched();	/* notepending may go true while asleep */
		cancel(a);
	}
	if(p->notepending){
		p->notepending = 0;
		s = splhi();
		lock(r);
		if(r->p == p)
			r->p = 0;
		unlock(r);
		splx(s);
		error(Eintr);
	when = MS2TK(ms)+MACHP(0)->ticks;
	i = &talarm.list;

	lock(&talarm);
	l = &talarm.list;
	for(f = talarm.list; f; f = f->tlink) {
		if(f == p)
			*l = p->tlink;
		if(f->twhen && f->twhen < when)
			i = &f->tlink;
		l = &f->tlink;
	}
	p->trend = r;
	p->twhen = when;
	p->tlink = *i;
	*i = p;
	unlock(&talarm);

	sleep(r, fn, arg);
	p->twhen = 0;
}

void


@@ 356,29 359,12 @@ wakeup(Rendez *r)
		if(p->state != Wakeme) 
			panic("wakeup: state");
		p->r = 0;
if((p->sched.pc&KZERO) != KZERO){
	spllo();
	panic("wakeup");
}
		ready(p);
	}
	unlock(r);
	splx(s);
}

void
wakeme(Alarm *a)
{
	ready((Proc*)(a->arg));
	cancel(a);
}

void
twakeme(Alarm *a)
{
	wakeup((Rendez*)(a->arg));
}

int
postnote(Proc *p, int dolock, char *n, int flag)
{

M port/taslock.c => port/taslock.c +11 -6
@@ 5,6 5,9 @@
#include "fns.h"
#include "../port/error.h"

ulong spinner;
ulong spinpc;

void
lock(Lock *l)
{


@@ 13,10 16,12 @@ lock(Lock *l)
	ulong pc;

	pc = getcallerpc(((uchar*)&l) - sizeof(l));
if(l == 0){
print("pc= %lux", pc);
for(;;);
}
    	if (tas(&ll->key) == 0){
		if(u)
			u->p->hasspin = 1;
		ll->pc = pc;
		return;
	}
	for(i = 0; i < 1000000; i++){
    		if (tas(&ll->key) == 0){
			if(u)


@@ 24,8 29,8 @@ for(;;);
			ll->pc = pc;
			return;
		}
		if(u && u->p->state == Running)
			sched();
spinner++;
spinpc = pc;
	}
	i = l->key;
	l->key = 0;

M power/main.c => power/main.c +6 -10
@@ 56,7 56,6 @@ main(void)
	grpinit();
	chaninit();
	clockinit();
	alarminit();
	ioboardinit();
	chandevreset();
	streaminit();


@@ 600,7 599,7 @@ confinit(void)
 *  we do this because the arguments are in memory that may be allocated
 *  to processes or kernel buffers.
 */
#define SYSENV "netaddr="
#define IPADDRENV "netaddr="
void
arginit(void)
{


@@ 614,16 613,13 @@ arginit(void)
	/*
	 *  get the system name from the environment
	 */
	if(*sysname == 0){
		for(argv = _env; *argv; argv++){
			if(strncmp(*argv, SYSENV, sizeof(SYSENV)-1)==0){
				strcpy(sysname, (*argv) + sizeof(SYSENV)-1);
				break;
			}
	strcpy(envbuf, IPADDRENV);
	for(argv = _env; *argv; argv++){
		if(strncmp(*argv, IPADDRENV, sizeof(IPADDRENV)-1)==0){
			strcat(envbuf, (*argv) + sizeof(IPADDRENV)-1);
			break;
		}
	}
	strcpy(envbuf, SYSENV);
	strcat(envbuf, sysname);
	env[0] = envbuf;
	env[1] = 0;


M ss/fns.h => ss/fns.h +0 -1
@@ 55,7 55,6 @@ void	putwD(ulong, ulong);
void	putwE16(ulong, ulong);
void	putwE(ulong, ulong);
void	systemreset(void);
void	restartprint(Alarm*);
void	restfpregs(FPsave*);
void	screeninit(void);
void	screenputc(int);

M ss/main.c => ss/main.c +0 -1
@@ 36,7 36,6 @@ main(void)
	initseg();
	grpinit();
	chaninit();
	alarminit();
	chandevreset();
	streaminit();
	pageinit();