~kris/9p

9hist

a49d112bf1cebd590c182d9a1cd66e72a50cab1c — David du Colombier 28 years ago 751bb35
Plan 9 from Bell Labs 1998-05-13
2 files changed, 80 insertions(+), 76 deletions(-)

M port/page.c
M port/proc.c
M port/page.c => port/page.c +38 -34
@@ 73,7 73,6 @@ newpage(int clear, Segment **s, ulong va)


	lock(&palloc);
retry:
	color = getpgcolor(va);
	hw = swapalloc.highwater;
	for(;;) {


@@ 129,23 128,15 @@ retry:
		p->prev->next = p->next;
	else
		palloc.head = p->next;

	if(p->next)
		p->next->prev = p->prev;
	else
		palloc.tail = p->prev;

	palloc.freecount--;
	unlock(&palloc);

	lock(p);
	if(p->ref != 0) {	/* lookpage has priority on steal */
		unlock(p);
		print("stolen\n");
		lock(&palloc);
		palloc.freecount++;
		goto retry;
	}
	if(p->ref != 0)
		panic("newpage");

	uncachepage(p);
	p->ref++;


@@ 154,6 145,7 @@ retry:
	for(i = 0; i < MAXMACH; i++)
		p->cachectl[i] = ct;
	unlock(p);
	unlock(&palloc);

	if(clear) {
		k = kmap(p);


@@ 178,13 170,14 @@ putpage(Page *p)
		return;
	}

	lock(&palloc);
	lock(p);
	if(--p->ref > 0) {
		unlock(p);
		unlock(&palloc);
		return;
	}

	lock(&palloc);
	if(p->image && p->image != &swapimage) {
		if(palloc.tail) {
			p->prev = palloc.tail;


@@ 209,13 202,13 @@ putpage(Page *p)
		palloc.head = p;
		p->prev = 0;
	}

	palloc.freecount++;

	if(palloc.r.p != 0)
		wakeup(&palloc.r);

	unlock(&palloc);
	unlock(p);
	unlock(&palloc);
}

Page*


@@ 232,16 225,15 @@ auxpage()
	p->next->prev = 0;
	palloc.head = p->next;
	palloc.freecount--;
	unlock(&palloc);

	lock(p);
	if(p->ref != 0) {		/* Stolen by lookpage */
		unlock(p);
		return 0;
	}
	if(p->ref != 0)
		panic("auxpage");
	p->ref++;
	uncachepage(p);
	unlock(p);
	unlock(&palloc);

	return p;
}



@@ 250,12 242,31 @@ duppage(Page *p)				/* Always call with p locked */
{
	Page *np;
	int color;
	int retries;

	retries = 0;
retry:
	if(retries++ > 10000)
		panic("duppage");

	/* No dup for swap/cache pages */
	if(p->image->notext)
	if(p->ref == 0 || p->image == nil || p->image->notext)
		return;

	lock(&palloc);
	/*
	 *  normal lock ordering is to call
	 *  lock(&palloc) before lock(p).
	 *  To avoid deadlock, we have to drop
	 *  our locks and try again.
	 */
	if(!canlock(&palloc)){
		unlock(p);
		if(up)
			sched();
		lock(p);
		goto retry;
	}

	/* No freelist cache when memory is very low */
	if(palloc.freecount < swapalloc.highwater) {
		unlock(&palloc);


@@ 279,7 290,6 @@ duppage(Page *p)				/* Always call with p locked */
		np->prev->next = np->next;
	else
		palloc.head = np->next;

	if(np->next)
		np->next->prev = np->prev;
	else


@@ 297,15 307,10 @@ duppage(Page *p)				/* Always call with p locked */
		np->prev = np->next = 0;
	}

	lock(np);
	unlock(&palloc);

	lock(np);				/* Cache the new version */
	if(np->ref != 0) {			/* Stolen by lookpage */
		uncachepage(p);
		unlock(np);
		return;
	}

	/* Cache the new version */
	uncachepage(np);
	np->va = p->va;
	np->daddr = p->daddr;


@@ 399,33 404,32 @@ lookpage(Image *i, ulong daddr)
		if(f->image == i && f->daddr == daddr) {
			unlock(&palloc.hashlock);

			lock(&palloc);
			lock(f);
			if(f->image != i || f->daddr != daddr) {
				unlock(f);
				unlock(&palloc);
				return 0;
			}

			lock(&palloc);
			if(++f->ref == 1) {
				if(f->prev)
					f->prev->next = f->next;
				else
					palloc.head = f->next;

				if(f->next)
					f->next->prev = f->prev;
				else
					palloc.tail = f->prev;

				palloc.freecount--;
			}
			unlock(&palloc);

			unlock(f);

			return f;
		}
	}
	unlock(&palloc.hashlock);

	return 0;
}


M port/proc.c => port/proc.c +42 -42
@@ 378,68 378,68 @@ procinit0(void)		/* bad planning - clashes with devproc.c */
}

void
sleep1(Rendez *r, int (*f)(void*), void *arg)
sleep(Rendez *r, int (*f)(void*), void *arg)
{
	int s;

	/*
	 * spl is to allow lock to be called
	 * at interrupt time. lock is mutual exclusion
	 */
	s = splhi();

	lock(&up->rlock);
	if(r->p){
		print("double sleep %d %d\n", r->p->pid, up->pid);
		dumpstack();
	}
	r->p = up;

	coherence();	/* force memory state to reflect processor state */

	/*
	 * if condition happened, never mind
	 */
	if((*f)(arg)){
		r->p = 0;
		unlock(&up->rlock);
		splx(s);
		return;
	}

	/*
	 * now we are committed to
	 * change state and call scheduler
	 * Wakeup only knows there may be something to do by testing
	 * r->p in order to get something to lock on.
	 * Flush that information out to memory in case the sleep is
	 * committed.
	 */
	up->state = Wakeme;
	up->r = r;
	unlock(&up->rlock);
	splx(s);
}
	r->p = up;
	coherence();

void
sleep(Rendez *r, int (*f)(void*), void *arg)
{
	int s;
	if((*f)(arg) || up->notepending){
		/*
		 *  if condition happened or a note is pending
		 *  never mind
		 */
		r->p = nil;
		unlock(&up->rlock);
	} else {
		/*
		 *  now we are committed to
		 *  change state and call scheduler
		 */
		up->state = Wakeme;
		up->r = r;

	sleep1(r, f, arg);
	if(up->notepending == 0)
		sched();	/* notepending may go true while asleep */
		/* statistics */
		m->cs++;
	
		procsave(up);
		if(setlabel(&up->sched)) {
			/*
			 *  here when the process is awakened
			 */
			procrestore(up);
			spllo();
		} else {
			/*
			 *  here to go to sleep (i.e. stop Running)
			 */
			unlock(&up->rlock);
			gotolabel(&m->sched);
		}
	}

	if(up->notepending) {
		up->notepending = 0;
		s = splhi();
		lock(&up->rlock);
		if(r->p == up){
			/* undo the sleep1() */
			up->r = 0;
			r->p = 0;
			if(up->state == Wakeme)
				up->state = Running;
		}
		unlock(&up->rlock);
		splx(s);
		error(Eintr);
	}

	splx(s);
}

int