Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/segment.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/segment.c 1991/0705
## diff -e /dev/null /n/bootesdump/1991/0705/sys/src/9/port/segment.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"ureg.h"
#include	"errno.h"

#define DPRINT

Page *lkpage(ulong addr);
Page *snewpage(ulong addr);
void lkpgfree(Page*);

/* System specific segattach devices */
#include "segment.h"

#define IHASHSIZE	64
#define ihash(s)	imagealloc.hash[s%IHASHSIZE]
struct Imagealloc
{
	Lock;
	Image	*free;
	Image	*hash[IHASHSIZE];
}imagealloc;

struct segalloc
{
	Lock;
	Segment *free;
}segalloc;

void
initseg(void)
{
	Segment *s, *se;
	Image *i, *ie;

	segalloc.free = ialloc(conf.nseg*sizeof(Segment), 0);
	imagealloc.free = ialloc(conf.nimage*sizeof(Image), 0);

	se = &segalloc.free[conf.nseg-1];
	for(s = segalloc.free; s < se; s++)
		s->next = s+1;
	s->next = 0;

	ie = &imagealloc.free[conf.nimage-1];
	for(i = imagealloc.free; i < ie; i++)
		i->next = i+1;
	i->next = 0;
}

Segment *
newseg(int type, ulong base, ulong size)
{
	Segment *s;

	if(size > (SEGMAPSIZE*PTEPERTAB))
		errors("segment too large");

	for(;;) {
		lock(&segalloc);
		if(s = segalloc.free) {
			segalloc.free = s->next;
			unlock(&segalloc);

			s->ref = 1;
			s->steal = 0;
			s->type = type;
			s->base = base;
			s->top = base+(size*BY2PG);
			s->size = size;
			s->image = 0;
			s->fstart = 0;
			s->flen = 0;
			s->pgalloc = 0;
			s->pgfree = 0;
			memset(s->map, 0, sizeof(s->map));

			return s;
		}
		unlock(&segalloc);
		resrcwait("no segments");
	}
}

void
putseg(Segment *s)
{
	Pte **pp, **emap;
	Image *i;

	if(s && decref(s) == 0) {
		emap = &s->map[SEGMAPSIZE];
		for(pp = s->map; pp < emap; pp++)
			if(*pp)
				freepte(s, *pp);

		if(i = s->image) {
			lock(i);
			if(i->s == s)
				i->s = 0;
			unlock(i);
			putimage(i);
		}

		lock(&segalloc);
		s->next = segalloc.free;		
		segalloc.free = s;
		unlock(&segalloc);
	}
}

void
relocateseg(Segment *s, ulong offset)
{
	Pte **p, **endpte;
	Page **pg, **endpages;

	endpte = &s->map[SEGMAPSIZE];
	for(p = s->map; p < endpte; p++)
		if(*p) {
			endpages = &((*p)->pages[PTEPERTAB]);
			for(pg = (*p)->pages; pg < endpages; pg++)
				if(*pg)
					(*pg)->va += offset;
		}
}

Segment*
dupseg(Segment *s)
{
	Pte *pte;
	Segment *n;
	int i;

	switch(s->type&SG_TYPE) {
	case SG_TEXT:		/* new segment shares pte set */
	case SG_SHARED:
	case SG_PHYSICAL:
		incref(s);
		return s;
	case SG_DATA:		/* copy on write both old and new plus demand load info */
		lock(s);
		n = newseg(s->type, s->base, s->size);

		incref(s->image);
		n->image = s->image;
		n->fstart = s->fstart;
		n->flen = s->flen;
	copypte:
		for(i = 0; i < SEGMAPSIZE; i++)
			if(pte = s->map[i])
				n->map[i] = ptecpy(pte);
		unlock(s);
		return n;	
	case SG_BSS:		/* Just copy on write */
	case SG_STACK:
		lock(s);
		n = newseg(s->type, s->base, s->size);
		goto copypte;
	}

	panic("dupseg");
}

void
segpage(Segment *s, Page *p)
{
	Pte **pte;
	ulong off;

	if(p->va < s->base || p->va >= s->top)
		panic("segpage");

	off = p->va - s->base;
	pte = &s->map[off/PTEMAPMEM];
	if(*pte == 0)
		*pte = ptealloc();

	(*pte)->pages[(off&(PTEMAPMEM-1))/BY2PG] = p;
}

Image*
attachimage(int type, Chan *c, ulong base, ulong len)
{
	Image *i, **l;

	lock(&imagealloc);

	for(i = ihash(c->qid.path); i; i = i->hash) {
		if(c->qid.path == i->qid.path) {
			lock(i);
			if(eqqid(c->qid, i->qid))
			if(eqqid(c->mqid, i->mqid))
			if(c->mchan == i->mchan)
			if(c->type == i->type) {
				i->ref++;
				goto found;
			}
			unlock(i);
		}
	}
	
	while(!(i = imagealloc.free)) {
		unlock(&imagealloc);
		resrcwait("no images");
		lock(&imagealloc);
	}

	imagealloc.free = i->next;

	lock(i);
	incref(c);
	i->c = c;
	i->type = c->type;
	i->qid = c->qid;
	i->mqid = c->mqid;
	i->mchan = c->mchan;
	i->ref = 1;
	l = &ihash(c->qid.path);
	i->hash = *l;
	*l = i;
found:
	unlock(&imagealloc);

	if(i->s == 0) {
		i->s = newseg(type, base, len);
		i->s->image = i;
	}
	else
		incref(i->s);

	unlock(i);
	return i;
}

void
putimage(Image *i)
{
	Image *f, **l;
	Chan *c;

	if(i == &swapimage)
		return;

	lock(i);
	if(--i->ref == 0) {
		l = &ihash(i->qid.path);
		i->qid = (Qid){~0, ~0};	
		unlock(i);
		c = i->c;
	
		lock(&imagealloc);
		for(f = *l; f; f = f->hash) {
			if(f == i) {
				*l = i->hash;
				break;
			}
			l = &f->hash;
		}

		i->next = imagealloc.free;
		imagealloc.free = i;
		unlock(&imagealloc);

		close(c);		/* Delay close because we could error */
		return;
	}
	unlock(i);
}

long
ibrk(ulong addr, int seg)		/* Called with a locked segment */
{
	Segment *s, *ns;
	ulong newtop, newsize;
	int i;

	s = u->p->seg[seg];
	if(s == 0)
		errors("no segment");

	qlock(&s->lk);

	if(addr == 0)
		return s->base;

	if(addr < s->base) {
		/* We may start with the bss overlapping the data */
		if(seg != BSEG || u->p->seg[DSEG] == 0 || addr < u->p->seg[DSEG]->base) {
			qunlock(&s->lk);
			pprint("addr below segment\n");
 		}
		addr = s->base;
	}
		
	newtop = PGROUND(addr);
	newsize = (newtop-s->base)/BY2PG;
	if(newtop < s->top) {
		print("down brk\n");
		mfreeseg(s, newtop, (s->top-newtop)/BY2PG);
		qunlock(&s->lk);
		return 0;
	}

	if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) {
		qunlock(&s->lk);
		pprint("exceeded max segment size\n");
		pexit("Suicide", 0);
		error(Esegaddr);
	}

	for(i = 0; i < NSEG; i++) {
		ns = u->p->seg[i];
		if(ns == 0 || ns == s)
			continue;
		if(newtop >= ns->base && newtop < ns->top) {
			qunlock(&s->lk);
			pprint("segments overlap\n");
			pexit("Suicide", 0);
			error(Esegaddr);
		}
	}

	s->top = newtop;
	s->size = newsize;

	qunlock(&s->lk);
	return 0;
}

void
mfreeseg(Segment *s, ulong start, int pages)
{
	int i, j;
	ulong soff;
	Page *pg;

	soff = start-s->base;
	j = (soff&(PTEMAPMEM-1))/BY2PG;

	for(i = soff/PTEMAPMEM; i < SEGMAPSIZE; i++) {
		if(pages <= 0) 
			goto done;
		if(s->map[i]) {
			while(j < PTEPERTAB) {
				if(pg = s->map[i]->pages[j]) {
					putpage(pg);
					s->map[i]->pages[j] = 0;	
				}
				if(--pages == 0)
					goto done;
				j++;
			}
			j = 0;
		}
		else
			pages -= PTEMAPMEM/BY2PG;
	}
done:
	flushmmu();
}

ulong
segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
{
	Segment *s, *ns, *new;
	Physseg *ps;
	ulong newtop;
	int i, sno;

	if(va&KZERO)					/* BUG: Only ok for now */
		errors("bad virtual address");

	validaddr((ulong)name, 1, 0);
	vmemchr(name, 0, ~0);

	for(sno = 0; sno < NSEG; sno++)
		if(u->p->seg[sno] == 0 && sno != ESEG)
			break;

	if(sno == NSEG)
		errors("no per process segments");

	va = va&~(BY2PG-1);
	len = PGROUND(len);
	newtop = va+len;
	for(i = 0; i < NSEG; i++) {
		ns = u->p->seg[i];
		if(ns == 0)
			continue;	
		if(newtop >= ns->base && newtop < ns->top) 
			errors("segments overlap");
	}

	for(ps = physseg; *(ps->name); ps++)
		if(strcmp(name, ps->name) == 0)
			goto found;

	errors("bad segment name");
found:
	if(len > ps->size)
		errors("segment too long");

	attr &= ~SG_TYPE;			/* Turn off what we are not allowed */
	attr |= ps->attr;			/* Copy in defaults */

	s = newseg(attr, va, len/BY2PG);
	s->pgalloc = ps->pgalloc;
	s->pgfree = ps->pgfree;
	u->p->seg[sno] = s;

	/* Need some code build mapped devices here */

	return 0;
}

long
syssegflush(ulong *arg)
{
	Segment *s;
	int i, j, pages;
	ulong soff;
	Page *pg;

	s = seg(u->p, arg[0], 1);
	if(s == 0)
		errors("bad segment address");

	soff = arg[0]-s->base;
	j = (soff&(PTEMAPMEM-1))/BY2PG;
	pages = ((arg[0]+arg[1]+(BY2PG-1))&~(BY2PG-1))-(arg[0]&~(BY2PG-1));

	for(i = soff/PTEMAPMEM; i < SEGMAPSIZE; i++) {
		if(pages <= 0) 
			goto done;
		if(s->map[i]) {
			while(j < PTEPERTAB) {
				if(pg = s->map[i]->pages[j]) 
					memset(pg->cachectl, PG_TXTFLUSH, sizeof pg->cachectl);
				if(--pages == 0)
					goto done;
				j++;
			}
			j = 0;
		}
		else
			pages -= PTEMAPMEM/BY2PG;
	}
done:
	qunlock(&s->lk);
	flushmmu();
}

Page*
snewpage(ulong addr)
{
	return newpage(1, 0, addr);
}
.
## diffname port/segment.c 1991/0706
## diff -e /n/bootesdump/1991/0705/sys/src/9/port/segment.c /n/bootesdump/1991/0706/sys/src/9/port/segment.c
429a

	s->flushme = 1;
.
274c
ibrk(ulong addr, int seg)
.
238a
imagereclaim(void)
{
	Page *p;

	if(!canqlock(&ireclaim))	/* Somebody is already cleaning the page cache */
		return;

	lock(&palloc);
	for(p = palloc.head; p; p = p->next) {
		if(p->image == 0)
			continue;

		unlock(&palloc);
		lockpage(p);
		if(p->ref == 0 && p->image != &swapimage)
			uncachepage(p);
		unlockpage(p);
		lock(&palloc);
	}

	unlock(&palloc);

	qunlock(&ireclaim);
}

void
.
206a
		imagereclaim();
.
190a
	/* Search the image cache for remains of the text from a previous incarnation */
.
157,161d
155c

		n->flushme = s->flushme;
		qunlock(&s->lk);
.
146a
	case SG_DATA:			/* Copy on write plus demand load info */
		qlock(&s->lk);
		n = newseg(s->type, s->base, s->size);

.
145a
		goto copypte;
.
143,144c

	case SG_BSS:			/* Just copy on write */
	case SG_STACK:
		qlock(&s->lk);
.
138c
	case SG_TEXT:			/* New segment shares pte set */
.
77a
			s->flushme = 0;
.
32a
static QLock ireclaim;

.
13a
void imagereclaim(void);
.
## diffname port/segment.c 1991/0710
## diff -e /n/bootesdump/1991/0706/sys/src/9/port/segment.c /n/bootesdump/1991/0710/sys/src/9/port/segment.c
217c
		resrcwait(0);
.
## diffname port/segment.c 1991/0724
## diff -e /n/bootesdump/1991/0710/sys/src/9/port/segment.c /n/bootesdump/1991/0724/sys/src/9/port/segment.c
244d
213a
	/*
	 * imagereclaim dumps pages from the free list which are cached by image
	 * structures. This should free some image structures.
	 */
.
199c
	/*
	 * Search the image cache for remains of the text from a previous 
	 * or currently running incarnation 
	 */
.
## diffname port/segment.c 1991/0726
## diff -e /n/bootesdump/1991/0724/sys/src/9/port/segment.c /n/bootesdump/1991/0726/sys/src/9/port/segment.c
401c
			pages -= PTEPERTAB-j;
		j = 0;
.
398d
103,110d
97c
	if(s == 0)
		return;

	i = s->image;
	if(i && i->s == s && s->ref == 1){
		lock(i);
		if(s->ref == 1)
			i->s = 0;
		unlock(i);
	}

	if(decref(s) == 0) {
		if(i)
			putimage(i);

.
## diffname port/segment.c 1991/0731
## diff -e /n/bootesdump/1991/0726/sys/src/9/port/segment.c /n/bootesdump/1991/0731/sys/src/9/port/segment.c
445c
	for(ps = physseg; ps->name; ps++)
.
## diffname port/segment.c 1991/0803
## diff -e /n/bootesdump/1991/0731/sys/src/9/port/segment.c /n/bootesdump/1991/0803/sys/src/9/port/segment.c
441c
		if((newtop > ns->base && newtop <= ns->top) ||
		   (va >= ns->base && va < ns->top))
.
## diffname port/segment.c 1991/0830
## diff -e /n/bootesdump/1991/0803/sys/src/9/port/segment.c /n/bootesdump/1991/0830/sys/src/9/port/segment.c
357,359c
		return -1;
.
## diffname port/segment.c 1991/1005
## diff -e /n/bootesdump/1991/0830/sys/src/9/port/segment.c /n/bootesdump/1991/1005/sys/src/9/port/segment.c
349d
## diffname port/segment.c 1991/1024
## diff -e /n/bootesdump/1991/1005/sys/src/9/port/segment.c /n/bootesdump/1991/1024/sys/src/9/port/segment.c
280,281d
278d
273a
		if(p == 0)
			break;

.
268,271c
	for(;;) {
		lock(&palloc);
		for(p = palloc.head; p; p = p->next)
			if(p->image && p->ref == 0 && p->image != &swapimage)
				break;
.
## diffname port/segment.c 1991/1105
## diff -e /n/bootesdump/1991/1024/sys/src/9/port/segment.c /n/bootesdump/1991/1105/sys/src/9/port/segment.c
367d
## diffname port/segment.c 1991/1109
## diff -e /n/bootesdump/1991/1105/sys/src/9/port/segment.c /n/bootesdump/1991/1109/sys/src/9/port/segment.c
115a

		qunlock(&s->lk);
.
108a
		qlock(&s->lk);
.
## diffname port/segment.c 1991/1115
## diff -e /n/bootesdump/1991/1109/sys/src/9/port/segment.c /n/bootesdump/1991/1115/sys/src/9/port/segment.c
420a
	USED(p);
.
## diffname port/segment.c 1991/1122
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/segment.c /n/bootesdump/1991/1122/sys/src/9/port/segment.c
198c
	pg = &(*pte)->pages[(off&(PTEMAPMEM-1))/BY2PG];
	*pg = p;
	if(pg < (*pte)->first)
		(*pte)->first = pg;
	if(pg > (*pte)->last)
		(*pte)->last = pg;
.
188a
	Page **pg;
.
## diffname port/segment.c 1991/1125
## diff -e /n/bootesdump/1991/1122/sys/src/9/port/segment.c /n/bootesdump/1991/1125/sys/src/9/port/segment.c
351,352c
			errors("addr below segment");
		}
.
346a
	qlock(&s->lk);

.
342,343d
## diffname port/segment.c 1991/1219
## diff -e /n/bootesdump/1991/1125/sys/src/9/port/segment.c /n/bootesdump/1991/1219/sys/src/9/port/segment.c
9,10d
## diffname port/segment.c 1992/0111
## diff -e /n/bootesdump/1991/1219/sys/src/9/port/segment.c /n/bootesdump/1992/0111/sys/src/9/port/segment.c
7c
#include	"../port/error.h"
.
## diffname port/segment.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/segment.c /n/bootesdump/1992/0114/sys/src/9/port/segment.c
483c
		error(Ebadarg);
.
458c
		error(Enovmem);
.
455c
	error(Ebadarg);
.
448c
			error(Enovmem);
.
437c
		error(Enovmem);
.
427c
		error(Ebadarg);
.
374c
			error(Enovmem);
.
349c
			error(Enovmem);
.
338c
		error(Ebadarg);
.
60c
		error(Enovmem);
.
## diffname port/segment.c 1992/0120
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/segment.c /n/bootesdump/1992/0120/sys/src/9/port/segment.c
6d
## diffname port/segment.c 1992/0225
## diff -e /n/bootesdump/1992/0120/sys/src/9/port/segment.c /n/bootesdump/1992/0225/sys/src/9/port/segment.c
285c
		if(p->ref == 0)
.
277c
			if(p->image)
			if(p->ref == 0)
			if(p->image != &swapimage)
.
## diffname port/segment.c 1992/0307
## diff -e /n/bootesdump/1992/0225/sys/src/9/port/segment.c /n/bootesdump/1992/0307/sys/src/9/port/segment.c
434c
		if(u->p->seg[sno] == 0)
		if(sno != ESEG)
.
372c
		if(newtop >= ns->base)
		if(newtop < ns->top) {
.
150a
	case SG_SHDATA:
.
## diffname port/segment.c 1992/0310
## diff -e /n/bootesdump/1992/0307/sys/src/9/port/segment.c /n/bootesdump/1992/0310/sys/src/9/port/segment.c
291a

	if(conf.cntrlp)
	print("ireclaim done %lud\n", TK2MS(MACHP(0)->ticks));
.
274a
	if(conf.cntrlp)
	print("ireclaim %lud\n", TK2MS(MACHP(0)->ticks));

.
## diffname port/segment.c 1992/0314
## diff -e /n/bootesdump/1992/0310/sys/src/9/port/segment.c /n/bootesdump/1992/0314/sys/src/9/port/segment.c
295,298d
287,293d
283,285c
			if(p->image != &swapimage) {
				lockpage(p);
				if(p->ref == 0)
					uncachepage(p);
				unlockpage(p);
			}
		}
.
280c
		for(p = palloc.head; p; p = p->next) {
.
275,277d
168a

.
98c
	if(i)
	if(i->s == s)
	if(s->ref == 1) {
.
## diffname port/segment.c 1992/0321
## diff -e /n/bootesdump/1992/0314/sys/src/9/port/segment.c /n/bootesdump/1992/0321/sys/src/9/port/segment.c
2c
#include	"../port/lib.h"
.
## diffname port/segment.c 1992/0404
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/segment.c /n/bootesdump/1992/0404/sys/src/9/port/segment.c
291a
	unlock(&palloc);
.
290d
283,288c
				uncachepage(p);
			unlockpage(p);
.
278,281c
	lock(&palloc);
	for(p = palloc.head; p; p = p->next) {
		if(p->image)
		if(p->ref == 0)
		if(p->image != &swapimage) {
			lockpage(p);
.
## diffname port/segment.c 1992/0430
## diff -e /n/bootesdump/1992/0404/sys/src/9/port/segment.c /n/bootesdump/1992/0430/sys/src/9/port/segment.c
164a
		if(share && s->ref == 1) {
			s->type = (s->type&~SG_TYPE)|SG_SHDATA;
			incref(s);
			qunlock(&s->lk);
			return s;
		}
.
162a
	case SG_BSS:			/* Just copy on write */
		qlock(&s->lk);
		if(share && s->ref == 1) {
			s->type = (s->type&~SG_TYPE)|SG_SHARED;
			incref(s);
			qunlock(&s->lk);
			return s;
		}
		n = newseg(s->type, s->base, s->size);
		goto copypte;

.
157d
143c
dupseg(Segment *s, int share)
.
## diffname port/segment.c 1992/0520
## diff -e /n/bootesdump/1992/0430/sys/src/9/port/segment.c /n/bootesdump/1992/0520/sys/src/9/port/segment.c
526a
	return 0;
.
198a
	return 0;		/* not reached */
.
85a
	return 0;	/* not reached */
.
## diffname port/segment.c 1992/0619
## diff -e /n/bootesdump/1992/0520/sys/src/9/port/segment.c /n/bootesdump/1992/0619/sys/src/9/port/segment.c
240,243c
			if(eqqid(c->qid, i->qid) &&
			   eqqid(c->mqid, i->mqid) &&
			   c->mchan == i->mchan &&
			   c->type == i->type) {
.
120,123c
		free(s);
.
61,86c
	s = smalloc(sizeof(Segment));
	s->ref = 1;
	s->type = type;
	s->base = base;
	s->top = base+(size*BY2PG);
	s->size = size;
	return s;
.
39,46c
	imagealloc.free = xalloc(conf.nimage*sizeof(Image));
.
25,30d
## diffname port/segment.c 1992/0621
## diff -e /n/bootesdump/1992/0619/sys/src/9/port/segment.c /n/bootesdump/1992/0621/sys/src/9/port/segment.c
363d
30d
## diffname port/segment.c 1992/0625
## diff -e /n/bootesdump/1992/0621/sys/src/9/port/segment.c /n/bootesdump/1992/0625/sys/src/9/port/segment.c
304c
		close(c);
.
279a
	Image *f, **l;
.
278d
272c
	qunlock(&imagealloc.ireclaim);
.
268c
			unlock(p);
.
262,265c
		if(p->image && p->ref == 0 && p->image != &swapimage) {
			lock(p);
.
257c
	/* Somebody is already cleaning the page cache */
	if(!canqlock(&imagealloc.ireclaim))
.
25,26d
22a
	QLock	ireclaim;
.
18c
struct
.
## diffname port/segment.c 1992/0711
## diff -e /n/bootesdump/1992/0625/sys/src/9/port/segment.c /n/bootesdump/1992/0711/sys/src/9/port/segment.c
399c
	Segment *s, *ns;
.
## diffname port/segment.c 1992/0721
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/segment.c /n/bootesdump/1992/0721/sys/src/9/port/segment.c
405c
	if((va&KZERO) == KZERO)				/* BUG: Only ok for now */
.
## diffname port/segment.c 1992/0822
## diff -e /n/bootesdump/1992/0721/sys/src/9/port/segment.c /n/bootesdump/1992/0822/sys/src/9/port/segment.c
262,263c
		if(p->image && p->ref == 0 && p->image != &swapimage && canlock(p)) {
.
## diffname port/segment.c 1992/0824
## diff -e /n/bootesdump/1992/0822/sys/src/9/port/segment.c /n/bootesdump/1992/0824/sys/src/9/port/segment.c
427c
			error(Esoverlap);
.
356a
	if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) {
		qunlock(&s->lk);
		return -1;
	}

.
352,353c
			error(Esoverlap);
.
349,350c
		if(newtop >= ns->base && newtop < ns->top) {
.
340,344d
324d
322a
	/* We may start with the bss overlapping the data */
.
162,163c
	n->flushme = s->flushme;
	qunlock(&s->lk);
	return n;	
.
160a
	for(i = 0; i < SEGMAPSIZE; i++)
		if(pte = s->map[i])
			n->map[i] = ptecpy(pte);
.
151,159c
		break;
.
135c
		break;
.
124c
		break;
.
112a
	SET(n);
.
111d
108a
	int i;
.
103a
	}
.
97c
	for(p = s->map; p < endpte; p++) {
.
65,67c
	if(i && i->s == s && s->ref == 1) {
.
## diffname port/segment.c 1992/0912
## diff -e /n/bootesdump/1992/0824/sys/src/9/port/segment.c /n/bootesdump/1992/0912/sys/src/9/port/segment.c
348c
		error(Enovmem);
.
## diffname port/segment.c 1992/1104
## diff -e /n/bootesdump/1992/0912/sys/src/9/port/segment.c /n/bootesdump/1992/1104/sys/src/9/port/segment.c
137a
		if(segno == TSEG)
			return data2txt(s);

.
112a
	s = seg[segno];

.
110c
	Segment *n, *s;
.
106c
dupseg(Segment **seg, int segno, int share)
.
## diffname port/segment.c 1992/1206
## diff -e /n/bootesdump/1992/1104/sys/src/9/port/segment.c /n/bootesdump/1992/1206/sys/src/9/port/segment.c
410,411c
		if(u->p->seg[sno] == 0 && sno != ESEG)
.
390,391d
386,387d
384a
			if(--pages == 0)
				return;
			j++;
.
374,383c
			break;
		if(s->map[i] == 0) {
			pages -= PTEPERTAB-j;
			j = 0;
			continue;
		}
		while(j < PTEPERTAB) {
			pg = s->map[i]->pages[j];
			if(pg) {
				putpage(pg);
				s->map[i]->pages[j] = 0;	
.
337a
		flushmmu();
.
## diffname port/segment.c 1993/0120
## diff -e /n/bootesdump/1992/1206/sys/src/9/port/segment.c /n/bootesdump/1993/0120/sys/src/9/port/segment.c
489,494d
8,9c
Page *lkpage(Segment*, ulong);
.
## diffname port/segment.c 1993/0210
## diff -e /n/bootesdump/1993/0120/sys/src/9/port/segment.c /n/bootesdump/1993/0210/sys/src/9/port/segment.c
444,445d
441,442c
	s->pseg = ps;
.
12a
#include "io.h"
.
## diffname port/segment.c 1993/0501
## diff -e /n/bootesdump/1993/0210/sys/src/9/port/segment.c /n/fornaxdump/1993/0501/sys/src/brazil/port/segment.c
485a
}

Page*
snewpage(ulong addr)
{
	return newpage(1, 0, addr);
.
472c
					for(i = 0; i < MAXMACH; i++)
						pg->cachectl[i] |= PG_TXTFLUSH;
.
456c
	s = seg(up, arg[0], 1);
.
444a
	/* Need some code build mapped devices here */

.
443c
	up->seg[sno] = s;
.
421c
		ns = up->seg[i];
.
411c
		if(up->seg[sno] == 0 && sno != ESEG)
.
343c
		ns = up->seg[i];
.
326c
		if(seg != BSEG || up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base) {
.
315c
	s = up->seg[seg];
.
8,9c
Page *snewpage(ulong addr);
.
## diffname port/segment.c 1993/0507
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0507/sys/src/brazil/port/segment.c
99a
					for(i = 0; i < MAXMACH; i++)
						(*pg)->cachectl[i] |= PG_DATINVALID;
				}
.
98c
				if(*pg){
.
89a
	int i;
.
## diffname port/segment.c 1993/0725
## diff -e /n/fornaxdump/1993/0507/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0725/sys/src/brazil/port/segment.c
492,497d
488c

.
485,486c
		while(len > 0 && j < PTEPERTAB) {
			pg = s->map[i]->pages[j];
			if(pg != 0) 
				memset(pg->cachectl, PG_TXTFLUSH, sizeof pg->cachectl);
			j++;
			len -= BY2PG;
		}
		j = 0;
.
471,483c
	for(i = soff/PTEMAPMEM; len > 0 && i < SEGMAPSIZE; i++) {
		if(s->map[i] == 0) {
			len -= PTEMAPMEM;
			continue;
.
469c
	len = arg[1]+BY2PG;
.
457c
	int i, j, len;
.
448,449d
441,442c
	attr &= ~SG_TYPE;		/* Turn off what we are not allowed */
	attr |= ps->attr;		/* Copy in defaults */
.
407c
	if((va&KZERO) == KZERO)			/* BUG: Only ok for now */
.
247a
		poperror();
.
245a
		/* Disaster after commit in exec */
		if(waserror()) {
			unlock(i);
			pexit(Enovmem, 1);
		}
.
101,103d
99c
				if(*pg)
.
90d
83,84c
	qunlock(&s->lk);
	free(s);
.
81c
	emap = &s->map[SEGMAPSIZE];
	for(pp = s->map; pp < emap; pp++)
		if(*pp)
			freepte(s, *pp);
.
76,79c
	qlock(&s->lk);
	if(i)
		putimage(i);
.
71,74c
	s->ref--;
	if(s->ref != 0) {
		unlock(s);
		return;
	}
.
69a
	else
		lock(s);
.
66c
		lock(s);
		if(i->s == s && s->ref == 1)
.
64c
	if(i != 0) {
.
8c
Page *lkpage(Segment*, ulong);
void lkpgfree(Page*);
.
## diffname port/segment.c 1993/0810
## diff -e /n/fornaxdump/1993/0725/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0810/sys/src/brazil/port/segment.c
102,106c
		if(*p == 0)
			continue;
		pte = *p;
		for(pg = pte->first; pg <= pte->last; pg++) {
			if(x = *pg)
				x->va += offset;
.
97,98c
	Page **pg, *x;
	Pte *pte, **p, **endpte;
.
## diffname port/segment.c 1993/0903
## diff -e /n/fornaxdump/1993/0810/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0903/sys/src/brazil/port/segment.c
478a
print("%s segflush 0x%lux %d\n", up->text, arg[0], arg[1]);

.
## diffname port/segment.c 1993/0904
## diff -e /n/fornaxdump/1993/0903/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0904/sys/src/brazil/port/segment.c
479,480d
## diffname port/segment.c 1993/0919
## diff -e /n/fornaxdump/1993/0904/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0919/sys/src/brazil/port/segment.c
494c
		chunk = pe-ps;
		len -= chunk;
		addr += chunk;

		qunlock(&s->lk);
	}
.
479,492c
		l = len;
		if(addr+l > s->top)
			l = s->top - addr;
		ua = addr-s->base;
		ps = ua&(PTEMAPMEM-1);
		pe = (ua+l)&(PTEMAPMEM-1);
		pe = (pe+BY2PG-1)&~(BY2PG-1);
		if(pe > PTEMAPMEM)
			pe = PTEMAPMEM;
	
		pteflush(s->map[ua/PTEMAPMEM], ps/BY2PG, pe/BY2PG);
.
475,477c
		s->flushme = 1;
.
473c
	while(len > 0) {
		s = seg(u->p, addr, 1);
		if(s == 0)
			error(Ebadarg);
.
469,471c
	addr = arg[0];
	len = arg[1];
.
465,467c
	ulong addr, ua, l;
	int chunk, ps, pe, len;
.
460a
void
pteflush(Pte *pte, int s, int e)
{
	int i;
	Page *p;

	if(pte == 0)
		return;

	for(i = s; i < e; i++) {
		p = pte->pages[i];
		if(p != 0)
			memset(p->cachectl, PG_TXTFLUSH, sizeof(p->cachectl));
	}
}

.
## diffname port/segment.c 1993/0930
## diff -e /n/fornaxdump/1993/0919/sys/src/brazil/port/segment.c /n/fornaxdump/1993/0930/sys/src/brazil/port/segment.c
488c
		s = seg(up, addr, 1);
.
## diffname port/segment.c 1993/1001
## diff -e /n/fornaxdump/1993/0930/sys/src/brazil/port/segment.c /n/fornaxdump/1993/1001/sys/src/brazil/port/segment.c
508a

		if(len > 0 && addr < s->top)
			goto more;
.
505a
		ps = addr-s->base;
		pte = s->map[ps/PTEMAPMEM];
		ps &= PTEMAPMEM-1;
		pe = PTEMAPMEM;
		if(pe-ps > l){
			pe = ps + l;
			pe = (pe+BY2PG-1)&~(BY2PG-1);
		}
		if(pe == ps) {
			qunlock(&s->lk);
			error(Ebadarg);
		}

		if(pte)
			pteflush(pte, ps/BY2PG, pe/BY2PG);

.
497,504d
493c
	more:
.
481c
	ulong addr, l;
	Pte *pte;
.
472c
		if(pagedout(p) == 0)
.
467,469d
## diffname port/segment.c 1993/1012
## diff -e /n/fornaxdump/1993/1001/sys/src/brazil/port/segment.c /n/fornaxdump/1993/1012/sys/src/brazil/port/segment.c
8,10c
Page*	lkpage(Segment*, ulong);
void	lkpgfree(Page*);
void	imagereclaim(void);
.
## diffname port/segment.c 1994/0514
## diff -e /n/fornaxdump/1993/1012/sys/src/brazil/port/segment.c /n/fornaxdump/1994/0514/sys/src/brazil/port/segment.c
458c
	return va;
.
456c
	p->seg[sno] = s;
.
441a
	va = va&~(BY2PG-1);
	if(isoverlap(p, va, len))
		error(Esoverlap);

.
432,439c

	/* Find a hole in the address space */
	if(va == 0) {
		va = p->seg[SSEG]->base - len;
		for(i = 0; i < 20; i++) {
			if(isoverlap(p, va, len) == 0)
				break;
			va -= len;
		}
.
430d
424c
		if(p->seg[sno] == 0 && sno != ESEG)
.
417c
	if(va != 0 && (va&KZERO) == KZERO)	/* BUG: Only ok for now */
.
414a
	Segment *s;
	Physseg *ps;
.
411,413d
407a
int
isoverlap(Proc *p, ulong va, int len)
{
	int i;
	Segment *ns;
	ulong newtop;

	newtop = va+len;
	for(i = 0; i < NSEG; i++) {
		ns = p->seg[i];
		if(ns == 0)
			continue;	
		if((newtop > ns->base && newtop <= ns->top) ||
		   (va >= ns->base && va < ns->top))
			return 1;
	}
	return 0;
}

.
## diffname port/segment.c 1994/0515
## diff -e /n/fornaxdump/1994/0514/sys/src/brazil/port/segment.c /n/fornaxdump/1994/0515/sys/src/brazil/port/segment.c
146c
	case SG_DATA:		/* Copy on write plus demand load info */
.
135c
	case SG_BSS:		/* Just copy on write */
.
123c
	case SG_TEXT:		/* New segment shares pte set */
.
## diffname port/segment.c 1994/0602
## diff -e /n/fornaxdump/1994/0515/sys/src/brazil/port/segment.c /n/fornaxdump/1994/0602/sys/src/brazil/port/segment.c
276,277c
		if(p->ref == 0 && p->image && canlock(p)) {
			if(p->ref == 0 && p->image != &swapimage)
.
## diffname port/segment.c 1994/0817
## diff -e /n/fornaxdump/1994/0602/sys/src/brazil/port/segment.c /n/fornaxdump/1994/0817/sys/src/brazil/port/segment.c
292c
	if(i->notext)
.
277c
			if(p->ref == 0)
.
## diffname port/segment.c 1995/0804
## diff -e /n/fornaxdump/1994/0817/sys/src/brazil/port/segment.c /n/fornaxdump/1995/0804/sys/src/brazil/port/segment.c
434d
## diffname port/segment.c 1996/0207
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/segment.c /n/fornaxdump/1996/0207/sys/src/brazil/port/segment.c
229c
		sched();
.
## diffname port/segment.c 1996/0303
## diff -e /n/fornaxdump/1996/0207/sys/src/brazil/port/segment.c /n/fornaxdump/1996/0303/sys/src/brazil/port/segment.c
543a
}

void
segclock(ulong pc)
{
	Segment *s;

	s = up->seg[TSEG];
	if(s == 0 || s->profile == 0)
		return;

	s->profile[0] += TK2MS(1);
	if(pc >= s->base && pc < s->top) {
		pc -= s->base;
		s->profile[pc>>LRESPROF] += TK2MS(1);
	}
.
90a
	if(s->profile != 0)
		free(s->profile);
.
## diffname port/segment.c 1996/0528
## diff -e /n/fornaxdump/1996/0303/sys/src/brazil/port/segment.c /n/fornaxdump/1996/0528/sys/src/brazil/port/segment.c
317d
314a

		/* defer freeing channel till we're out of spin lock's */
		if(imagealloc.nfreechan == imagealloc.szfreechan){
			imagealloc.szfreechan += NFREECHAN;
			cp = malloc(imagealloc.szfreechan*sizeof(Chan*));
			if(cp == nil)
				panic("putimage");
			memmove(cp, imagealloc.freechan, imagealloc.nfreechan*sizeof(Chan*));
			free(imagealloc.freechan);
			imagealloc.freechan = cp;
		}
		imagealloc.freechan[imagealloc.nfreechan++] = c;
.
291a

	/* Somebody is already cleaning the image chans */
	if(!canqlock(&imagealloc.fcreclaim))
		return;

	while(imagealloc.nfreechan > 0){
		lock(&imagealloc);
		imagealloc.nfreechan--;
		c = imagealloc.freechan[imagealloc.nfreechan];
		unlock(&imagealloc);
		close(c);
	}

	qunlock(&imagealloc.fcreclaim);
}

void
putimage(Image *i)
{
	Chan *c, **cp;
.
289c
imagechanreclaim(void)
.
287a
/*
 *  since close can block, this has to be called outside of
 *  spin locks.
 */
.
203a
	/* reclaim any free channels from reclaimed segments */
	if(imagealloc.nfreechan)
		imagechanreclaim();

.
35a
	imagealloc.freechan = malloc(NFREECHAN * sizeof(Chan*));
	imagealloc.szfreechan = NFREECHAN;
.
23c
	QLock	ireclaim;	/* mutex on reclaiming free images */

	Chan	**freechan;	/* free image channels */
	int	nfreechan;	/* number of free channels */
	int	szfreechan;	/* size of freechan array */
	QLock	fcreclaim;	/* mutex on reclaiming free channels */
.
15a
#define NFREECHAN	64
.
10a
void	imagechanreclaim(void);
.
## diffname port/segment.c 1997/0327
## diff -e /n/fornaxdump/1996/0528/sys/src/brazil/port/segment.c /n/emeliedump/1997/0327/sys/src/brazil/port/segment.c
319c
		cclose(c);
.
## diffname port/segment.c 1997/0516
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/segment.c /n/emeliedump/1997/0516/sys/src/brazil/port/segment.c
146a
	case SG_MAP:
.
## diffname port/segment.c 1998/0326
## diff -e /n/emeliedump/1997/0516/sys/src/brazil/port/segment.c /n/emeliedump/1998/0326/sys/src/brazil/port/segment.c
474a
	return 0;
}

int
addphysseg(Physseg* new)
{
	Physseg *ps;

	/*
	 * Check not already entered and there is room
	 * for a new entry and the terminating null entry.
	 */
	lock(&physseglock);
	for(ps = physseg; ps->name; ps++){
		if(strcmp(ps->name, new->name) == 0){
			unlock(&physseglock);
			return -1;
		}
	}
	if(ps-physseg >= nelem(physseg)-2){
		unlock(&physseglock);
		return -1;
	}

	*ps = *new;
	unlock(&physseglock);

.
306c
static void
.
281c
static void
.
20c
static struct
.
16a
static Lock physseglock;

.
8,11c
static void	imagereclaim(void);
static void	imagechanreclaim(void);
.
## diffname port/segment.c 1998/0512
## diff -e /n/emeliedump/1998/0326/sys/src/brazil/port/segment.c /n/emeliedump/1998/0512/sys/src/brazil/port/segment.c
470c
			continue;
.
449c
				s->map[i]->pages[j] = 0;
.
438c
		if(pages <= 0)
.
396c

.
341c

.
338c
		i->qid = (Qid){~0, ~0};
.
237c

.
221,222c
	 * Search the image cache for remains of the text from a previous
	 * or currently running incarnation
.
183c
	return n;
.
## diffname port/segment.c 1998/0724
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/segment.c /n/emeliedump/1998/0724/sys/src/brazil/port/segment.c
455a
	}
out:
	/* wait for others to get fix their tlb's and then free the pages */
	if((s->type&SG_TYPE) == SG_SHARED){
	}
	for(pg = list; pg != nil; pg = list){
		list = list->next;
		putpage(pg);
.
452c
				goto out;
.
450c
			pg->next = list;
			list = pg;
.
447,448c
			if(pg)
.
436a
	list = nil;
.
432a
	Page *list;
.
426a
/*
 *  called with s->lk locked
 */
.
## diffname port/segment.c 1998/0725
## diff -e /n/emeliedump/1998/0724/sys/src/brazil/port/segment.c /n/emeliedump/1998/0725/sys/src/brazil/port/segment.c
465a

	/* free the pages */
.
463,464c
	/* flush this seg in all other processes */
	i = s->type&SG_TYPE;
	switch(i){
	case SG_SHARED:
	case SG_SHDATA:
		procflushseg(s);
		break;
.
## diffname port/segment.c 1998/0823
## diff -e /n/emeliedump/1998/0725/sys/src/brazil/port/segment.c /n/emeliedump/1998/0823/sys/src/brazil/port/segment.c
454,455c
				pg->next = list;
				list = pg;
			}
.
452c
			if(pg){
.
## diffname port/segment.c 1998/0916
## diff -e /n/emeliedump/1998/0823/sys/src/brazil/port/segment.c /n/emeliedump/1998/0916/sys/src/brazil/port/segment.c
571c
	attr &= ~SG_TYPE;		/* Turn off what is not allowed */
.
559c
	if(isoverlap(p, va, len) != nil)
.
553a
			va = os->base;
			if(len > va)
				error(Enovmem);
.
551,552c
		for(;;) {
			os = isoverlap(p, va, len);
			if(os == nil)
.
548c
	/*
	 * Find a hole in the address space.
	 * Starting at the lowest possible stack address - len,
	 * check for an overlapping segment, and repeat at the
	 * base of that segment - len until either a hole is found
	 * or the address space is exhausted.
	 */
.
540c
		if(p->seg[sno] == nil && sno != ESEG)
.
529,530c
	int sno;
	Segment *s, *os;
.
496c
	return nil;
.
494c
			return ns;
.
480c
Segment*
.
442c
	for(i = soff/PTEMAPMEM; i < size; i++) {
.
440a
	size = s->mapsize;
.
433c
	int i, j, size;
.
419a
	mapsize = ROUND(newsize, PTEPERTAB)/PTEPERTAB;
	if(mapsize > s->mapsize){
		map = smalloc(mapsize*sizeof(Pte*));
		memmove(map, s->map, s->mapsize);
		if(s->map != s->ssegmap)
			free(s->map);
		s->map = map;
		s->mapsize = mapsize;
	}
.
416c
	if(newsize > (SEGMAPSIZE*PTEPERTAB)) {
.
377c
	int i, mapsize;
	Pte **map;
.
177c
	size = s->mapsize;
	for(i = 0; i < size; i++)
.
126c
	int i, size;
.
111c
	endpte = &s->map[s->mapsize];
.
99a
	if(s->map != s->ssegmap)
		free(s->map);
.
94c
	emap = &s->map[s->mapsize];
.
60a

	mapsize = ROUND(size, PTEPERTAB)/PTEPERTAB;
	if(mapsize > nelem(s->ssegmap)){
		s->map = smalloc(mapsize*sizeof(Pte*));
		s->mapsize = mapsize;
	}
	else{
		s->map = s->ssegmap;
		s->mapsize = nelem(s->ssegmap);
	}

.
50a
	int mapsize;
.
## diffname port/segment.c 1998/0919
## diff -e /n/emeliedump/1998/0916/sys/src/brazil/port/segment.c /n/emeliedump/1998/0919/sys/src/brazil/port/segment.c
439c
		memmove(map, s->map, s->mapsize*sizeof(Pte*));
.
64a
		mapsize *= 2;
		if(mapsize > (SEGMAPSIZE*PTEPERTAB))
			mapsize = (SEGMAPSIZE*PTEPERTAB);
.
## diffname port/segment.c 1998/1107
## diff -e /n/emeliedump/1998/0919/sys/src/brazil/port/segment.c /n/emeliedump/1998/1107/sys/src/brazil/port/segment.c
316a
	irstats.loops++;
	irstats.ticks += ticks;
	if(ticks > irstats.maxt)
		irstats.maxt = ticks;
	//print("T%llud+", ticks);
.
315a
	ticks = fastticks(nil) - ticks;
.
308a
	ticks = fastticks(nil);
.
303a
	irstats.calls++;
.
302a
	uvlong ticks;
.
298a
static struct {
	int	calls;			/* times imagereclaim was called */
	int	loops;			/* times the main loop was run */
	uvlong	ticks;			/* total time in the main loop */
	uvlong	maxt;			/* longest time in main loop */
} irstats;

.
## diffname port/segment.c 1999/0120
## diff -e /n/emeliedump/1998/1107/sys/src/brazil/port/segment.c /n/emeliedump/1999/0120/sys/src/brazil/port/segment.c
438a
	}

	if(swapfull()){
		qunlock(&s->lk);
		error(Enoswap);
.
186a
		poperror();
.
185a
		if(waserror()){
			qunlock(&s->lk);
			nexterror();
		}
.
172a
		poperror();
.
171a
		if(waserror()){
			qunlock(&s->lk);
			nexterror();
		}
.
160a
		poperror();
.
159a
		if(waserror()){
			qunlock(&s->lk);
			nexterror();
		}
.
55a
	if(swapfull())
		error(Enoswap);

.
## diffname port/segment.c 1999/1007
## diff -e /n/emeliedump/1999/0120/sys/src/brazil/port/segment.c /n/emeliedump/1999/1007/sys/src/brazil/port/segment.c
614a
	if(len == 0)
		error(Ebadarg);
.
## diffname port/segment.c 2000/0229
## diff -e /n/emeliedump/1999/1007/sys/src/brazil/port/segment.c /n/emeliedump/2000/0229/sys/src/9/port/segment.c
366a
	/*
	 * We don't have to recheck that nfreechan > 0 after we
	 * acquire the lock, because we're the only ones who decrement 
	 * it (the other lock contender increments it), and there's only
	 * one of us thanks to the qlock above.
	 */
.
## diffname port/segment.c 2000/0714
## diff -e /n/emeliedump/2000/0229/sys/src/9/port/segment.c /n/emeliedump/2000/0714/sys/src/9/port/segment.c
20c
static struct Imagealloc
.
## diffname port/segment.c 2000/1012
## diff -e /n/emeliedump/2000/0714/sys/src/9/port/segment.c /n/emeliedump/2000/1012/sys/src/9/port/segment.c
58d
## diffname port/segment.c 2001/0314
## diff -e /n/emeliedump/2000/1012/sys/src/9/port/segment.c /n/emeliedump/2001/0314/sys/src/9/port/segment.c
218a

sameseg:
	incref(s);
	poperror();
	qunlock(&s->lk);
	return s;
.
216a
	poperror();
.
203d
198,201d
194,196c
			goto sameseg;
.
191,192c
		if(share) {
			if(s->ref != 1)
				print("Fuckin A again cap'n!\n");
.
189a
		}
.
188c
		if(segno == TSEG){
			poperror();
			qunlock(&s->lk);
.
184d
179,182d
175,177c
			goto sameseg;
.
172,173c
		if(share) {
			if(s->ref != 1)
				print("Fuckin A cap'n!\n");
.
167d
161,165d
157,158c
		goto sameseg;
.
151a
	qlock(&s->lk);
	if(waserror()){
		qunlock(&s->lk);
		nexterror();
	}
.
## diffname port/segment.c 2001/0424
## diff -e /n/emeliedump/2001/0314/sys/src/9/port/segment.c /n/emeliedump/2001/0424/sys/src/9/port/segment.c
539,540d
534,537c
	if(s->ref > 1)
.
205a
	if(s->ref > 1)
		procflushseg(s);
.
191d
186,189c
		if(share)
.
175d
169,173c
		if(share)
.
161d
## diffname port/segment.c 2001/0503
## diff -e /n/emeliedump/2001/0424/sys/src/9/port/segment.c /n/emeliedump/2001/0503/sys/src/9/port/segment.c
13c

/*
 * Attachable segment types
 */
static Physseg physseg[10] = {
	{ SG_SHARED,	"shared",	0,	SEGMAXSIZE,	0, 	0 },
	{ SG_BSS,	"memory",	0,	SEGMAXSIZE,	0,	0 },
	{ 0,		0,		0,	0,		0,	0 },
};
.
11d
## diffname port/segment.c 2001/0507
## diff -e /n/emeliedump/2001/0503/sys/src/9/port/segment.c /n/emeliedump/2001/0507/sys/src/9/port/segment.c
607a

	/*
 	 *  first look for a global segment with the
	 *  same name
	 */
	if(_globalsegattach != nil){
		s = (*_globalsegattach)(p, name);
		if(s != nil){
			p->seg[sno] = s;
			return s->base;
		}
	}
.
588a
int
isphysseg(char *name)
{
	Physseg *ps;
	int rv = 0;

	lock(&physseglock);
	for(ps = physseg; ps->name; ps++){
		if(strcmp(ps->name, name) == 0){
			rv = 1;
			break;
		}
	}
	unlock(&physseglock);
	return rv;
}

Segment* (*_globalsegattach)(Proc*, char*);

.
## diffname port/segment.c 2001/0508
## diff -e /n/emeliedump/2001/0507/sys/src/9/port/segment.c /n/emeliedump/2001/0508/sys/src/9/port/segment.c
706c
	int chunk, len;
.
704c
	ulong addr, l, ps, pe;
.
665c
	len = top - va;
	if(isoverlap(p, va, top) != nil)
.
663a
	top = PGROUND(va + len);
.
654c
			os = isoverlap(p, va, va+len);
.
651a
		len = PGROUND(len);
.
640d
629c
	 *  first look for a global segment with the
.
611a
	ulong top;
.
550d
548d
544c
isoverlap(Proc *p, ulong va, int newtop)
.
## diffname port/segment.c 2001/0527
## diff -e /n/emeliedump/2001/0508/sys/src/9/port/segment.c /n/emeliedump/2001/0527/sys/src/9/port/segment.c
707c
	int chunk, ps, pe, len;
.
705c
	ulong addr, l;
.
665,666c
	if(isoverlap(p, va, len) != nil)
.
663d
653c
			os = isoverlap(p, va, len);
.
650d
627,638c
	len = PGROUND(len);
.
610d
587,605d
548a
	newtop = va+len;
.
547a
	ulong newtop;
.
544c
isoverlap(Proc *p, ulong va, int len)
.
390c
		mkqid(&i->qid, ~0, ~0, QTFILE);
.
## diffname port/segment.c 2002/0329
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/segment.c /n/emeliedump/2002/0329/sys/src/9/port/segment.c
127a
	unlock(s);	/* keep lock/unlocks balanced */
.
## diffname port/segment.c 2002/0330
## diff -e /n/emeliedump/2002/0329/sys/src/9/port/segment.c /n/emeliedump/2002/0330/sys/src/9/port/segment.c
608a

	/*
	 *  first look for a global segment with the
	 *  same name
	 */
	if(_globalsegattach != nil){
		s = (*_globalsegattach)(p, name);
		if(s != nil){
			p->seg[sno] = s;
			return s->base;
		}
	}
.
589a
int
isphysseg(char *name)
{
	Physseg *ps;
	int rv = 0;

	lock(&physseglock);
	for(ps = physseg; ps->name; ps++){
		if(strcmp(ps->name, name) == 0){
			rv = 1;
			break;
		}
	}
	unlock(&physseglock);
	return rv;
}

.
39a
Segment* (*_globalsegattach)(Proc*, char*);

.
## diffname port/segment.c 2002/0420
## diff -e /n/emeliedump/2002/0330/sys/src/9/port/segment.c /n/emeliedump/2002/0420/sys/src/9/port/segment.c
130d
114a
	unlock(s);
.
## diffname port/segment.c 2002/0924
## diff -e /n/emeliedump/2002/0420/sys/src/9/port/segment.c /n/emeliedump/2002/0924/sys/src/9/port/segment.c
525,526d
523a
				if(onswap(pg))
					putswap(pg);
				else{
					pg->next = list;
					list = pg;
				}
.
522a
			/*
			 * We want to zero s->map[i]->page[j] and putpage(pg),
			 * but we have to make sure other processors flush the entry
			 * entry from their TLBs before the page is freed.
			 * We construct a list of the pages to be freed, zero
			 * the entries, then (below) call procflushseg, and call
			 * putpage on the whole list.
			 *
			 * Swapped-out pages don't appear in TLBs, so it's okay
			 * to putswap those pages before procflushseg.
			 */
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].