|
|
|
1992/0618/sys/src/9/port/page.c:8,15 –
1992/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,238 –
1992/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,256 –
1992/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,272 –
1992/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,607 –
1992/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
| |
}
|