plan 9 kernel history: overview | file list | diff list

1992/0619/port/page.c (diff list | history)

1992/0618/sys/src/9/port/page.c:8,151992/0619/sys/src/9/port/page.c:8,13 (short | long | prev | next)
1991/0705    
#define PGHFUN(x, y)	(((ulong)x^(ulong)y)%PGHSIZE) 
#define	pghash(s)	palloc.hash[PGHFUN(s->image, p->daddr)] 
1990/0227    
 
1991/0705    
struct Palloc palloc; 
                 
struct Ptealloc 
1990/0227    
{ 
	Lock; 
1992/0618/sys/src/9/port/page.c:17,2381992/0619/sys/src/9/port/page.c:15,49
1991/0705    
	int	pages; 
}ptealloclk; 
1990/0227    
 
1992/0315    
ulong	hiaddr; 
1991/0705    
static Lock pglock; 
1992/0619    
static	Lock pglock; 
struct	Palloc palloc; 
1990/0227    
 
1991/0705    
/* Multiplex a hardware lock for per page manipulations */ 
void 
lockpage(Page *p) 
{	 
	int s; 
1990/0227    
                 
1991/0705    
	for(;;) { 
		if(p->lock == 0) { 
			s = splhi(); 
			lock(&pglock); 
			if(p->lock == 0) { 
				p->lock = 1; 
				unlock(&pglock); 
				splx(s); 
				return; 
			} 
			unlock(&pglock); 
			splx(s); 
		} 
		sched(); 
	} 
} 
1990/0227    
                 
1991/0705    
void 
unlockpage(Page *p) 
{ 
	p->lock = 0; 
} 
1991/0425    
                 
1992/0313    
typedef struct Region	Region; 
struct Region 
{ 
	ulong	start; 
	ulong	end; 
}; 
                 
enum 
{ 
	Nregion=	10, 
}; 
Region region[Nregion]; 
                 
                 
void 
addsplit(Region *r, ulong start, ulong end) 
{ 
1992/0618    
	int len; 
	Region *rr, *eregion; 
1992/0313    
                 
1992/0618    
	len = end - start; 
	eregion = ®ion[Nregion]; 
                 
1992/0313    
	/* first look for an unused one */ 
1992/0618    
	for(rr = region; rr < eregion; rr++){ 
1992/0313    
		if(rr == r) 
			continue; 
		if(rr->end - rr->start == 0){ 
			rr->start = start; 
			rr->end = end; 
			return; 
		} 
	} 
                 
	/* then look for a smaller one */ 
1992/0618    
	for(rr = region; rr < eregion; rr++){ 
1992/0313    
		if(rr == r) 
			continue; 
		if(rr->end - rr->start < len){ 
			rr->start = start; 
			rr->end = end; 
			return; 
		} 
	} 
} 
1992/0315    
                 
/* 
 *  Called to allocate permanent data structures, before calling pageinit(). 
 *  We assume all of text+data+bss is in the first memory bank. 
 * 
1992/0317    
 *  alignment is in number of bytes.  It pertains both to the start and 
1992/0315    
 *  end of the allocated memory. 
 * 
 *  If crevasse is specified, no allocation can span an address that is 
 *  a multiple of crevasse. 
 */ 
1990/0227    
void* 
1992/0313    
iallocspan(ulong n, int align, ulong crevasse) 
1990/0227    
{ 
1992/0618    
	int m; 
1990/0227    
	ulong p; 
1992/0313    
	Region *r; 
	int ledge; 
1990/0227    
                 
1990/1212    
	if(palloc.active && n!=0) 
1990/0227    
		print("ialloc bad\n"); 
1991/0606    
                 
1991/0802    
	if(palloc.addr0 == 0){ 
1992/0618    
		r = ®ion[Nregion-2]; 
		r->start = (((ulong)end)&~KZERO) + conf.base0; 
		r->end = conf.base0 + (conf.npage0<<PGSHIFT); 
		r++; 
		r->start = conf.base1; 
		r->end = conf.base1 + (conf.npage1<<PGSHIFT); 
1992/0313    
                 
		palloc.addr0 = region[Nregion-2].start; 
		palloc.addr1 = region[Nregion-1].start; 
1991/0802    
	} 
1991/0801    
                 
1991/0802    
	/* 
1992/0313    
	 *  alignment also applies to length 
1991/0802    
	 */ 
1992/0313    
	if(align){ 
		m = n % align; 
		if(m) 
			n += align - m; 
	} 
1991/0606    
                 
1992/0313    
	p = 0; 
	for(r = region; r < ®ion[Nregion]; r++){ 
1992/0315    
		/* align region */ 
1992/0313    
		p = r->start; 
		if(align){ 
			m = p % align; 
			if(m) 
				p += align - m; 
		} 
1991/0705    
                 
1992/0313    
		/* check for crossing a crevasse */ 
		if(crevasse){ 
			ledge = p / crevasse; 
			if(ledge != ((p+n-1) / crevasse)) 
				p = ((p+n-1) / crevasse) * crevasse; 
		} 
                 
		/* see if it fits */ 
		if(p + n > r->end) 
			continue; 
                 
		/* split the region */ 
		if(p != r->start) 
			addsplit(r, r->start, p); 
		r->start = p + n; 
		break; 
	} 
	if(r == ®ion[Nregion]) 
		panic("out of memory"); 
                 
1991/0802    
	/* 
1992/0313    
	 *  remember high water marks 
1991/0802    
	 */ 
1992/0313    
	if(palloc.addr0 < r->start && r->start <= conf.base0+(conf.npage0<<PGSHIFT)) 
		palloc.addr0 = r->start; 
	else if(palloc.addr1 < r->start && r->start <= conf.base1+(conf.npage1<<PGSHIFT)) 
		palloc.addr1 = r->start; 
1991/0802    
                 
	/* 
1992/0313    
	 *  zero it 
1991/0802    
	 */ 
1992/0313    
	memset((void*)(p|KZERO), 0, n); 
1990/0227    
	return (void*)(p|KZERO); 
1992/0313    
} 
                 
/* 
 *  allocate with possible page alignment 
 */ 
void* 
ialloc(ulong n, int align) 
{ 
	return iallocspan(n, align ? BY2PG : 0, 0); 
1990/0227    
} 
                 
void 
pageinit(void) 
{ 
1991/0802    
	ulong np, addr, lim; 
1992/0303    
	ulong i, vmem, pmem, hw, hr; 
1990/0227    
	Page *p; 
1992/0619    
	ulong np, hw, hr, vmem, pmem; 
1990/0227    
 
1991/0802    
	/* 
	 *  calculate an upper bound to the number of pages structures 
	 *  we'll need (np). 
	 */ 
	np = (conf.npage0<<PGSHIFT) - (palloc.addr0 - conf.base0); 
	np += (conf.npage1<<PGSHIFT) - (palloc.addr1 - conf.base1); 
	np = np>>PGSHIFT; 
1992/0619    
	np = palloc.np0+palloc.np1; 
	palloc.head = xalloc(np*sizeof(Page)); 
	if(palloc.head == 0) 
		panic("pageinit"); 
1990/0227    
 
	/* 
1991/0802    
	 *  allocate Page structs (no more ialloc's allowed after this). 
	 *  np is useless after this ialloc since we've just eaten up 
	 *  some pages for the Page structures. 
1990/0227    
	 */ 
1991/0802    
	palloc.head = ialloc(np*sizeof(Page), 0); 
	palloc.active = 1; 
1990/0227    
                 
1991/0802    
	/* 
 	 *  for each page in each bank, point a page structure to 
	 *  the page and chain it into the free list 
	 */ 
	p = palloc.head; 
	addr = palloc.addr0 = PGROUND(palloc.addr0); 
	lim = conf.base0 + (conf.npage0<<PGSHIFT); 
	for(; addr < lim; addr += BY2PG){ 
1990/0227    
		p->next = p+1; 
1992/0619    
	while(palloc.np0 > 0) { 
1990/0227    
		p->prev = p-1; 
1991/0802    
		p->pa = addr; 
1992/0619    
		p->next = p+1; 
		p->pa = palloc.p0; 
		palloc.p0 += BY2PG; 
		palloc.np0--; 
1991/0802    
		p++; 
1990/0227    
	} 
1991/0802    
	addr = palloc.addr1 = PGROUND(palloc.addr1); 
	lim = conf.base1 + (conf.npage1<<PGSHIFT); 
	for(; addr < lim; addr += BY2PG){ 
		p->next = p+1; 
1992/0619    
	while(palloc.np1 > 0) { 
1991/0802    
		p->prev = p-1; 
		p->pa = addr; 
1992/0619    
		p->next = p+1; 
		p->pa = palloc.p1; 
		palloc.p1 += BY2PG; 
		palloc.np1--; 
1991/0802    
		p++; 
	} 
	palloc.tail = p - 1; 
1992/0618/sys/src/9/port/page.c:239,2561992/0619/sys/src/9/port/page.c:50,69
1990/0227    
	palloc.head->prev = 0; 
	palloc.tail->next = 0; 
1991/0802    
 
	palloc.user = palloc.freecount = p - palloc.head; 
1992/0619    
	palloc.user = p - palloc.head; 
	palloc.freecount = palloc.user; 
1991/0802    
	pmem = palloc.user*BY2PG/1024; 
	vmem = pmem + ((conf.nswap)*BY2PG)/1024; 
1992/0619    
	vmem = pmem + (conf.nswap*BY2PG)/1024; 
1992/0303    
 
	/* Pageing numbers */ 
	swapalloc.highwater = (palloc.freecount*5)/100; 
	swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4); 
	hw = (swapalloc.highwater*BY2PG)/1024; 
	hr = (swapalloc.headroom*BY2PG)/1024; 
1992/0619    
 
	hw = swapalloc.highwater*BY2PG; 
	hr = swapalloc.headroom*BY2PG; 
1992/0303    
	 
	print("%lud free pages, %dK bytes, swap %dK bytes, highwater %dK, headroom %dK\n",  
				palloc.user, pmem, vmem, hw, hr); 
1992/0619    
	print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",  
	palloc.user, pmem, vmem, hw/1024, hr/1024); 
1990/0227    
} 
 
Page* 
1992/0618/sys/src/9/port/page.c:260,2721992/0619/sys/src/9/port/page.c:73,83
1990/0617    
	KMap *k; 
1991/0705    
	int i; 
1990/0227    
 
	if(palloc.active == 0) 
		print("newpage inactive\n"); 
1991/0705    
                 
1990/0227    
	lock(&palloc); 
1991/0705    
 
	/* The kp test is a poor guard against the pager deadlocking */ 
1992/0303    
	while((palloc.freecount < swapalloc.highwater && u->p->kp == 0)||palloc.freecount == 0) { 
1992/0619    
	while((palloc.freecount < swapalloc.highwater && u->p->kp == 0) || 
	       palloc.freecount == 0) { 
1991/0705    
		palloc.wanted++; 
1991/0806    
		unlock(&palloc); 
1991/0705    
		if(s && *s) { 
1992/0618/sys/src/9/port/page.c:604,6071992/0619/sys/src/9/port/page.c:415,447
1991/0705    
	p->next = ptealloclk.free; 
	ptealloclk.free = p; 
	unlock(&ptealloclk); 
1992/0619    
} 
 
/* Multiplex a hardware lock for per page manipulations */ 
void 
lockpage(Page *p) 
{	 
	int s; 
 
	for(;;) { 
		if(p->lock == 0) { 
			s = splhi(); 
			lock(&pglock); 
			if(p->lock == 0) { 
				p->lock = 1; 
				unlock(&pglock); 
				splx(s); 
				return; 
			} 
			unlock(&pglock); 
			splx(s); 
		} 
		sched(); 
	} 
} 
 
void 
unlockpage(Page *p) 
{ 
	p->lock = 0; 
1990/0227    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)