~kris/9p

9hist

ae37eaa082570514122fee906fb7a28e7b51b212 — David du Colombier 25 years ago ace5c08
Plan 9 from Bell Labs 2001-05-10
8 files changed, 148 insertions(+), 29 deletions(-)

M bitsy/devuda1341.c
M pc/devarch.c
M pc/etherelnk3.c
M port/devenv.c
M port/devproc.c
M port/portdat.h
M port/portfns.h
M port/proc.c
M bitsy/devuda1341.c => bitsy/devuda1341.c +49 -26
@@ 114,7 114,7 @@ enum
	Vinvert,
	Nvol,

	Bufsize		= /* 4* */ 1024,	/* 46 ms each */
	Bufsize		= 4* 1024,	/* 46 ms each */
	Nbuf		= 32,		/* 1.5 seconds total */

	Speed		= 44100,


@@ 222,8 222,8 @@ static	struct
[Vinvert]	{"invert",	Fin|Fout|Fmono,	  0,		  0},
[Nvol]	{0}
};

static int rate = Speed;		/* Current sample rate */
static int bufsize = Bufsize;	/* Current buffer size */
static void	setreg(char *name, int val, int n);

/*


@@ 758,7 758,7 @@ sendaudio(IOstate *s) {
	ilock(&s->ilock);
	if ((audio.amode &  Aread) && s->next == s->filling && dmaidle(s->dma)) {
		// send an empty buffer to provide an input clock
		zerodma |= dmastart(s->dma, Flushbuf, Bufsize) & 0xff;
		zerodma |= dmastart(s->dma, Flushbuf, bufsize) & 0xff;
		if (zerodma == 0)
			if (debug) print("emptyfail\n");
		iostats.empties++;


@@ 803,7 803,7 @@ recvaudio(IOstate *s) {
	ilock(&s->ilock);
	while (s->next != s->emptying) {
		assert(s->next->nbytes == 0);
		if ((n = dmastart(s->dma, s->next->phys, Bufsize)) == 0) {
		if ((n = dmastart(s->dma, s->next->phys, bufsize)) == 0) {
			iostats.faildma++;
			break;
		}


@@ 879,7 879,7 @@ audiointr(void *x, ulong ndma) {
		/* A dma, not of a zero buffer completed, update current
		 * Only interrupt routine touches s->current
		 */
		s->current->nbytes = (s == &audio.i)? Bufsize: 0;
		s->current->nbytes = (s == &audio.i)? bufsize: 0;
		s->current++;
		if (s->current == &s->buf[Nbuf])
			s->current = &s->buf[0];


@@ 1107,7 1107,7 @@ audioread(Chan *c, void *v, long n, vlong off)
			}

			m = (s->emptying->nbytes > n)? n: s->emptying->nbytes;
			memmove(p, s->emptying->virt + Bufsize - 
			memmove(p, s->emptying->virt + bufsize - 
					  s->emptying->nbytes, m);

			s->emptying->nbytes -= m;


@@ 1127,7 1127,7 @@ audioread(Chan *c, void *v, long n, vlong off)

	case Qspeed:
		buf[0] = '\0';
		snprint(buf, sizeof(buf), "speed %d\n", rate);
		snprint(buf, sizeof(buf), "speed %d\ndmasize %d\n", rate, bufsize);
		return readstr(offset, p, n, buf);

	case Qvolume:


@@ 1174,6 1174,29 @@ audioread(Chan *c, void *v, long n, vlong off)
	return n0-n;
}

static void
setrate(int newrate)
{
	switch (newrate) {
	case 16000:
	case 22050:
	case 44100:
	case 48000:
		volumes[Vspeed].ilval = volumes[Vspeed].irval = rate = newrate;
		break;
	default:
		error(Ebadarg);
	}
}

static void
setbufsize(int newbufsize)
{
	if (newbufsize < 0 || newbufsize > 8 * 1024 || newbufsize % sizeof(ulong))
		error(Ebadarg);
	bufsize = newbufsize;
}

static long
audiowrite(Chan *c, void *vp, long n, vlong)
{


@@ 1196,24 1219,24 @@ audiowrite(Chan *c, void *vp, long n, vlong)
		memmove(buf, p, n);
		buf[n] = '\0';
		nf = getfields(buf, field, Ncmd, 1, " \t\n");
		if (nf != 2 && nf != 1) error(Ebadarg);
		if (nf == 2) {
			if (strcmp(field[0], "speed")) 
				error(Ebadarg);
			i = 1;
		}
		else
		if (nf == 1)
			/* The user just supplied a number */
			setrate((int)strtol(field[0], (char **)nil, 0));
		else {
			i = 0;
		i = (int)strtol(field[i], (char **)nil, 0);
		switch (i) {
		case 16000:
		case 22050:
		case 44100:
		case 48000:
			volumes[Vspeed].ilval = volumes[Vspeed].irval = rate = i;
			break;
		default:
			error(Ebadarg);
			while (i < nf) {
				int newval;

				if (i + 1 >= nf) error(Ebadarg);
				newval = (int)strtol(field[i + 1], (char **)nil, 0);
				if (!strcmp(field[i], "speed"))
					setrate(newval);
				else if (!strcmp(field[i], "dmasize"))
					setbufsize(newval);
				else
					error(Ebadarg);
				i += 2;
			}
		}
		break;
		


@@ 1316,7 1339,7 @@ audiowrite(Chan *c, void *vp, long n, vlong)
				if (debug > 1) print("#A: sleep\n");
				sleep(&a->vous, audioqnotfull, a);
			}
			m = Bufsize - a->filling->nbytes;
			m = bufsize - a->filling->nbytes;
			if(m > n)
				m = n;
			memmove(a->filling->virt + a->filling->nbytes, p, m);


@@ 1324,7 1347,7 @@ audiowrite(Chan *c, void *vp, long n, vlong)
			a->filling->nbytes += m;
			n -= m;
			p += m;
			if(a->filling->nbytes >= Bufsize) {
			if(a->filling->nbytes >= bufsize) {
				if (debug > 1) print("#A: filled @%p\n", a->filling);
				a->filling++;
				if (a->filling == &a->buf[Nbuf])

M pc/devarch.c => pc/devarch.c +5 -0
@@ 133,6 133,11 @@ ioalloc(int port, int size, int align, char *tag)
			return -1;
		}
	} else {
		// Only 64KB I/O space on the x86.
		if((port+size) >= 0x10000){
			unlock(&iomap);
			return -1;
		}
		// see if the space clashes with previously allocated ports
		for(l = &iomap.m; *l; l = &(*l)->next){
			m = *l;

M pc/etherelnk3.c => pc/etherelnk3.c +6 -0
@@ 1443,6 1443,12 @@ tcm59Xpci(void)

	p = nil;
	while(p = pcimatch(p, 0x10B7, 0)){
		/*
		 * Not prepared to deal with memory-mapped
		 * devices yet.
		 */
		if(!(p->mem[0].bar & 0x01))
			continue;
		port = p->mem[0].bar & ~0x01;
		if(ioalloc(port, p->mem[0].size, 0, "tcm59Xpci") < 0){
			print("tcm59Xpci: port 0x%uX in use\n", port);

M port/devenv.c => port/devenv.c +17 -1
@@ 57,7 57,23 @@ envattach(char *spec)
static int
envwalk(Chan *c, char *name)
{
	return devwalk(c, name, 0, 0, envgen);
	Evalue *e;
	Egrp *eg;
	int rv;

	if(c->qid.path == CHDIR && name[0] != '.'){
		rv = 0;
		eg = up->egrp;
		qlock(eg);
		for(e = eg->entries; e; e = e->link)
			if(strcmp(e->name, name) == 0){
				rv = 1;
				c->qid = e->qid;
			}
		qunlock(eg);
		return rv;
	} else
		return devwalk(c, name, 0, 0, envgen);
}

static void

M port/devproc.c => port/devproc.c +15 -1
@@ 150,7 150,21 @@ procattach(char *spec)
static int
procwalk(Chan *c, char *name)
{
	return devwalk(c, name, 0, 0, procgen);
	int s;
	int pid;

	if(c->qid.path == CHDIR && name[0] != '.'){
		/* this is a hack to speed walks through a large directory */
		pid = strtol(name, &name, 0);
		if(pid < 0 || *name != 0)
			return 0;
		s = procindex(pid);
		if(s < 0)
			return 0;
		c->qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid};
		return 1;
	} else
		return devwalk(c, name, 0, 0, procgen);
}

static void

M port/portdat.h => port/portdat.h +1 -0
@@ 543,6 543,7 @@ struct Proc
	QLock	seglock;	/* locked whenever seg[] changes */
	ulong	pid;
	ulong	noteid;		/* Equivalent of note group */
	Proc	*pidhash;	/* next proc in pid hash */

	Lock	exl;		/* Lock count and waitq */
	Waitq	*waitq;		/* Exited processes wait children */

M port/portfns.h => port/portfns.h +2 -1
@@ 211,8 211,9 @@ ulong		procalarm(ulong);
int		proccounter(char *name);
void		procctl(Proc*);
void		procdump(void);
void		procinit0(void);
void		procflushseg(Segment*);
void		procinit0(void);
int		procindex(int);
Proc*		proctab(int);
void		procwired(Proc*, int);
Pte*		ptealloc(void);

M port/proc.c => port/proc.c +53 -0
@@ 11,6 11,7 @@ Ref	noteidalloc;
struct Procalloc
{
	Lock;
	Proc*	ht[128];
	Proc*	arena;
	Proc*	free;
}procalloc;


@@ 48,6 49,9 @@ char *statename[] =
	"Rendez",
};

static void pidhash(Proc*);
static void pidunhash(Proc*);

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


@@ 342,6 346,7 @@ newproc(void)
	p->error[0] = '\0';
	memset(p->seg, 0, sizeof p->seg);
	p->pid = incref(&pidalloc);
	pidhash(p);
	p->noteid = incref(&noteidalloc);
	if(p->pid==0 || p->noteid==0)
		panic("pidalloc");


@@ 825,6 830,7 @@ pexit(char *exitstr, int freemem)
	qunlock(&up->seglock);

	lock(&up->exl);		/* Prevent my children from leaving waits */
	pidunhash(up);
	up->pid = 0;
	wakeup(&up->waitr);
	unlock(&up->exl);


@@ 1213,3 1219,50 @@ accounttime(void)
	n = (nrdy+n)*1000;
	m->load = (m->load*19+n)/20;
}

static void
pidhash(Proc *p)
{
	int h;

	h = p->pid % nelem(procalloc.ht);
	lock(&procalloc);
	p->pidhash = procalloc.ht[h];
	procalloc.ht[h] = p;
	unlock(&procalloc);
}

static void
pidunhash(Proc *p)
{
	int h;
	Proc **l;

	h = p->pid % nelem(procalloc.ht);
	lock(&procalloc);
	for(l = &procalloc.ht[h]; *l != nil; l = &(*l)->pidhash)
		if(*l == p){
			*l = p->pidhash;
			break;
		}
	unlock(&procalloc);
}

int
procindex(int pid)
{
	Proc *p;
	int h;
	int s;

	s = -1;
	h = pid % nelem(procalloc.ht);
	lock(&procalloc);
	for(p = procalloc.ht[h]; p != nil; p = p->pidhash)
		if(p->pid == pid){
			s = p - procalloc.arena;
			break;
		}
	unlock(&procalloc);
	return s;
}