## diffname port/page.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/page.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ureg.h"
struct
{
Lock;
ulong addr;
int active;
Page *page; /* base of Page structures, indexed by phys addr */
ulong minppn; /* index of first usable page */
Page *head; /* most recently used */
Page *tail; /* least recently used */
}palloc;
struct
{
Lock;
Orig *arena;
Orig *free;
}origalloc;
typedef union PTEA PTEA;
union PTEA{
PTE;
struct{
ulong n; /* for growpte */
Orig *o; /* for growpte */
PTEA *next; /* for newmod */
};
};
struct
{
Lock;
PTEA *arena;
PTEA *free;
PTEA *end;
}ptealloc;
struct{
Lock;
PTEA *free;
}modalloc;
/*
* Called to allocate permanent data structures, before calling pageinit().
*/
void*
ialloc(ulong n, int align)
{
ulong p;
if(palloc.active)
print("ialloc bad\n");
if(palloc.addr == 0)
palloc.addr = ((ulong)&end)&~KZERO;
if(align){
palloc.addr += BY2PG-1;
palloc.addr &= ~(BY2PG-1);
}
memset((void*)(palloc.addr|KZERO), 0, n);
p = palloc.addr;
palloc.addr += n;
if(align){
palloc.addr += BY2PG-1;
palloc.addr &= ~(BY2PG-1);
}
return (void*)(p|KZERO);
}
void
audit(char *s)
{
int nf, nb;
Page *p;
static int here;
do;while(here);
here=1;
p = palloc.head;
nf=nb=0;
while(p){
print("%lux %lux %d\n", p->pa, p->va, p->ref);
if(p->o) print("\t%d %lux %c\n", p->o->nproc, p->o->qid, devchar[p->o->type]);
delay(100);
nf++;
p = p->next;
}
p = palloc.tail;
while(p){
nb++;
p = p->prev;
}
print("%s: nf: %d nb: %d\n", s, nf, nb);
delay(1000);
here=0;
}
void
pageinit(void)
{
ulong pa, nb, ppn;
ulong i;
Page *p;
PTEA *pte;
Orig *o;
ptealloc.arena = ialloc(conf.npte*sizeof(PTEA), 0);
ptealloc.free = ptealloc.arena;
ptealloc.end = ptealloc.arena+conf.npte;
modalloc.free = ialloc(conf.nmod*sizeof(PTEA), 0);
pte = modalloc.free;
for(i=0; i<conf.nmod-1; i++,pte++)
pte->next = pte+1;
pte->next = 0;
origalloc.free = ialloc(conf.norig*sizeof(Orig), 0);
origalloc.arena = origalloc.free;
o = origalloc.free;
for(i=0; i<conf.norig-1; i++,o++)
o->next = o+1;
o->next = 0;
palloc.active = 1;
nb = (conf.npage<<PGSHIFT) - palloc.addr;
nb -= ((nb+(BY2PG-1))>>PGSHIFT)*sizeof(Page); /* safe overestimate */
nb &= ~(BY2PG-1);
pa = (conf.npage<<PGSHIFT) - nb; /* physical addr of first free page */
ppn = pa >> PGSHIFT; /* physical page number of first free page */
palloc.page = (Page *)((palloc.addr - ppn*sizeof(Page))|KZERO);
/*
* Now palloc.page[ppn] describes first free page
*/
palloc.minppn = ppn;
palloc.addr = ppn<<PGSHIFT;
palloc.head = &palloc.page[ppn];
palloc.tail = &palloc.page[conf.npage-1];
memset(palloc.head, 0, (conf.npage-ppn)*sizeof(Page));
print("%lud free pages\n", conf.npage-ppn);
for(p=palloc.head; p<=palloc.tail; p++,ppn++){
p->next = p+1;
p->prev = p-1;
p->pa = ppn<<PGSHIFT;
}
palloc.head->prev = 0;
palloc.tail->next = 0;
}
Page*
newpage(int noclear, Orig *o, ulong va)
{
Page *p;
Orig *o1;
if(palloc.active == 0)
print("newpage inactive\n");
loop:
lock(&palloc);
for(p=palloc.tail; p; p=p->prev){
if(p->ref == 0)
goto out;
#ifdef asdf
if(p->ref == 1){ /* a pageout daemon should do this */
o1 = p->o;
if(o1 && o1->nproc==0 && canlock(o1)){
if(o1->nproc){
unlock(o1);
continue;
}
print("free %d pages va %lux %lux %c\n", o1->npage, o->va, o1->qid, devchar[o1->type]);
freepage(o1);
/* neworig will free the orig and pte's later */
unlock(o1);
if(p->ref == 0)
goto out;
print("newpage ref != 0");
}
}
#endif
}
audit("newpage");
print("no physical memory\n");
unlock(&palloc);
if(u == 0)
panic("newpage");
u->p->state = Wakeme;
alarm(1000, wakeme, u->p);
sched();
goto loop;
out:
if(p->o){
print("page in use %lux %lux %lux\n", p->va, p->o, origalloc.arena);
print("%c %lux %lux, %d %d %d\n", devchar[p->o->type], p->o->va, p->o->qid, p->o->flag, p->o->nproc, p->o->npte);
panic("shit");
}
p->ref = 1;
usepage(p, 0);
unlock(&palloc);
if(!noclear)
memset((void*)(p->pa|KZERO), 0, BY2PG);
p->o = o;
p->va = va;
return p;
}
/*
* Move page to head of list
*/
void
usepage(Page *p, int dolock)
{
if(dolock)
lock(&palloc);
/*
* Unlink
*/
if(p->prev)
p->prev->next = p->next;
else
palloc.head = p->next;
if(p->next)
p->next->prev = p->prev;
else
palloc.tail = p->prev;
/*
* Link
*/
p->next = palloc.head;
p->prev = 0;
if(p->next)
p->next->prev = p;
else
palloc.tail = p;
palloc.head = p;
if(dolock)
unlock(&palloc);
}
Orig*
lookorig(ulong va, ulong npte, int flag, Chan *c)
{
Orig *o;
ulong i;
for(o=origalloc.arena,i=0; i<conf.norig; i++,o++)
if(o->npage && o->qid==c->qid && o->va==va){
lock(o);
if(o->npage && o->qid==c->qid)
if(o->va==va && o->npte==npte && o->flag==flag)
if(o->type==c->type && o->dev==c->dev){
if(o->chan == 0){
o->chan = c;
incref(c);
}
o->nproc++;
unlock(o);
return o;
}
unlock(o);
}
return 0;
}
Orig*
neworig(ulong va, ulong npte, int flag, Chan *c)
{
Orig *o;
int i, freed;
lock(&origalloc);
loop:
if(o = origalloc.free){ /* assign = */
origalloc.free = o->next;
o->va = va;
o->pte = 0;
o->flag = flag;
o->nproc = 1;
o->npage = 0;
o->chan = c;
if(c){
o->type = c->type;
o->dev = c->dev;
o->qid = c->qid;
incref(c);
}else{
o->type = -1;
o->dev = -1;
o->qid = -1;
}
growpte(o, npte);
unlock(&origalloc);
return o;
}
/*
* This is feeble. Orig's should perhaps be held in
* an LRU list. This algorithm is too aggressive.
*/
freed = 0;
for(o=origalloc.arena,i=0; i<conf.norig; i++,o++){
if(o->nproc==0 && canlock(o)){
if(o->nproc){
unlock(o);
continue;
}
freepage(o);
freepte(o);
unlock(o);
o->next = origalloc.free;
origalloc.free = o;
freed++;
}
}
if(freed)
goto loop;
print("no origs freed\n");
unlock(&origalloc);
if(u == 0)
panic("neworig");
u->p->state = Wakeme;
alarm(1000, wakeme, u->p);
sched();
lock(&origalloc);
goto loop;
}
PTE*
newmod(void)
{
PTEA *pte;
loop:
lock(&modalloc);
if(pte = modalloc.free){ /* assign = */
modalloc.free = pte->next;
unlock(&modalloc);
memset(pte, 0, sizeof(PTE));
return pte;
}
unlock(&modalloc);
print("no mods\n");
if(u == 0)
panic("newmod");
u->p->state = Wakeme;
alarm(1000, wakeme, u->p);
sched();
goto loop;
}
/*
* Duplicate mod structure for this segment (old) in new process p.
* old->o must be locked.
*/
void
forkmod(Seg *old, Seg *new, Proc *p)
{
Orig *o;
PTE *pte, *ppte, *opte, *npte;
ulong va;
o = old->o;
ppte = 0;
pte = old->mod;
while(pte){
if(pte->page==0) panic("forkmod zero page");
if(pte->proc != u->p) panic("forkmod wrong page");
npte = newmod();
npte->proc = p;
npte->page = pte->page;
pte->page->ref++;
o->npage++;
/*
* Link into mod list for this va
*/
npte->nextmod = pte->nextmod;
pte->nextmod = npte;
/*
* Link into mod list for new segment
*/
if(ppte == 0)
new->mod = npte;
else
ppte->nextva = npte;
npte->nextva = 0;
ppte = npte;
pte = pte->nextva;
}
}
void
freesegs(int save)
{
int i, j;
Seg *s;
Orig *o;
PTE *pte, *opte;
PTEA *old;
Page *pg;
Chan *c;
s = u->p->seg;
for(i=0; i<NSEG; i++,s++){
if(i == save)
continue;
o = s->o;
if(o == 0)
continue;
lock(o);
if(pte = s->mod){ /* assign = */
while(pte){
opte = &o->pte[(pte->page->va-o->va)>>PGSHIFT];
while(opte->nextmod != pte){
if(opte->page && opte->page->va != pte->page->va)
panic("pte %lux %lux\n", opte->page->va, pte->page->va);
opte = opte->nextmod;
if(opte == 0)
panic("freeseg opte==0");
}
opte->nextmod = pte->nextmod;
pg = pte->page;
if(pg->ref == 1){
pte->page = 0;
pg->o = 0;
}
pg->ref--;
o->npage--;
old = (PTEA*)pte;
pte = pte->nextva;
lock(&modalloc);
old->next = modalloc.free;
modalloc.free = old;
unlock(&modalloc);
}
}
o->nproc--;
if(o->nproc == 0){
if(c = o->chan){ /* assign = */
o->chan = 0;
close(c);
}
if(!(o->flag&OCACHED) || o->npage==0){
freepage(o);
freepte(o);
unlock(o);
lock(&origalloc);
o->next = origalloc.free;
origalloc.free = o;
unlock(&origalloc);
}else
unlock(o);
}else{
/*
* BUG: there is a leak here. if the origin pte is being used only
* by the exiting process, the associated page will linger. the fix
* is to remember either the length of the mod list at each va or
* the number of processes sharing the origin pte, and to promote one
* of the mods to the origin pte when no process is left using the
* origin pte.
*/
unlock(o);
}
}
}
/*
* Adjust segment to desired size. This implementation is rudimentary.
*/
int
segaddr(Seg *s, ulong min, ulong max)
{
Orig *o;
if(max < min)
return 0;
if(min != s->minva) /* can't grow down yet (stacks: fault.c) */
return 0;
max = (max+(BY2PG-1)) & ~(BY2PG-1);
o = s->o;
if(max == s->maxva)
return 1;
if(max > s->maxva){
/*
* Grow
*/
/* BUG: check spill onto other segments */
if(o->va+BY2PG*o->npte < max)
growpte(o, (max-o->va)>>PGSHIFT);
s->maxva = max;
return 1;
}
/*
* Shrink
*/
print("segaddr shrink");
for(;;);
}
/*
* o is locked
*/
void
freepage(Orig *o)
{
PTE *pte;
Page *pg;
int i;
pte = o->pte;
for(i=0; i<o->npte; i++,pte++)
if(pg = pte->page){ /* assign = */
if(pg->ref == 1){
pte->page = 0;
pg->o = 0;
}
pg->ref--;
}
o->npage = 0;
}
/*
* Compacting allocator
*/
void
freepte(Orig *o) /* o is locked */
{
PTEA *p;
p = (PTEA*)(o->pte - 1);
p->o = 0;
}
void
growpte(Orig *o, ulong n)
{
PTEA *p;
ulong nfree;
lock(&ptealloc);
lock(o);
if(o->pte){
if(o->npte == n)
panic("growpte pointless");
p = (PTEA*)(o->pte - 1);
if(o->npte > n){
nfree = o->npte - n;
p->n -= nfree;
o->npte -= nfree;
p += p->n;
p->o = 0;
p->n = nfree;
}else{
n++;
if(p+p->n == ptealloc.free){
compactpte(o, n - p->n);
p = (PTEA*)(o->pte - 1);
ptealloc.free += n - p->n;
}else{
compactpte(o, n);
p = ptealloc.free;
ptealloc.free += n;
memcpy(p+1, o->pte, o->npte*sizeof(PTE));
p->o = o;
((PTEA*)(o->pte-1))->o = 0;
o->pte = p+1;
}
memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
p->n = n;
o->npte = n-1;
}
unlock(o);
unlock(&ptealloc);
return;
}
n++;
compactpte(o, n);
p = ptealloc.free;
ptealloc.free += n;
memset(p, 0, n*sizeof(PTE));
p->n = n;
p->o = o;
o->pte = p+1;
o->npte = n-1;
unlock(o);
unlock(&ptealloc);
}
void
compactpte(Orig *o, ulong n)
{
PTEA *p1, *p2;
Orig *p2o;
if(ptealloc.end-ptealloc.free >= n)
return;
p1 = ptealloc.arena; /* dest */
p2 = ptealloc.arena; /* source */
while(p2 < ptealloc.free){
p2o = p2->o;
if(p2o == 0){
Free:
p2 += p2->n;
continue;
}
if(p1 != p2){
if(p2o != o)
lock(p2o);
if(p2->o != p2o){ /* freepte()d very recently */
if(p2->o)
panic("compactpte p2->o %lux\n", p2->o);
unlock(p2o);
goto Free;
}
memcpy(p1, p2, p2->n*sizeof(PTE));
p2o->pte = p1+1;
if(p2o != o)
unlock(p2o);
}
p2 += p1->n;
p1 += p1->n;
}
ptealloc.free = p1;
if(ptealloc.end-ptealloc.free >= n)
return;
unlock(o);
unlock(&ptealloc);
panic("compactpte %d %lux %d", n, o->va, o->npte);
}
.
## diffname port/page.c 1990/0303
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/page.c /n/bootesdump/1990/0303/sys/src/9/mips/page.c
298a
o->mqid = -1;
o->mchan = 0;
.
297d
293a
o->mchan = c->mchan;
o->mqid = c->mqid;
.
292d
260c
if(o->mchan==c->mchan && o->mqid==c->mqid && o->type==c->type){
.
190d
101c
here=0;
.
88,90c
print("%lux %lux %d\n", p->pa, p->va, p->ref);
if(p->o){
print("\t%d %lux %c\n", p->o->nproc, p->o->qid, devchar[p->o->type]);
delay(100); /* let it drain; there's a lot here */
}
.
81,84c
do;while(here);
here=1;
.
79a
static int here;
.
## diffname port/page.c 1990/0312
## diff -e /n/bootesdump/1990/0303/sys/src/9/mips/page.c /n/bootesdump/1990/0312/sys/src/9/mips/page.c
437a
o->nmod--;
.
378a
o->nmod++;
.
352a
DEBUG();
panic("mods");
.
289a
o->nmod = 0;
.
## diffname port/page.c 1990/0409
## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/page.c /n/bootesdump/1990/0409/sys/src/9/mips/page.c
191a
pprint("no physical memory\n");
.
## diffname port/page.c 1990/0617
## diff -e /n/bootesdump/1990/0409/sys/src/9/mips/page.c /n/bootesdump/1990/0617/sys/src/9/mips/page.c
209,210c
if(!noclear){
k = kmap(p);
memset((void*)VA(k), 0, BY2PG);
kunmap(k);
}
.
163a
KMap *k;
.
13c
Page *page; /* base of Page structures, indexed by phys page number */
.
## diffname port/page.c 1990/0720
## diff -e /n/bootesdump/1990/0617/sys/src/9/mips/page.c /n/bootesdump/1990/0720/sys/src/9/mips/page.c
495a
if(max > 20*1024*1024) pprint("segaddr %lux\n", max);
.
## diffname port/page.c 1990/0728
## diff -e /n/bootesdump/1990/0720/sys/src/9/mips/page.c /n/bootesdump/1990/0728/sys/src/9/mips/page.c
604a
Return:
.
592,594c
goto Return;
.
566a
print("growpte shrink");
goto Return;
.
563,564c
if(o->npte == n){
if(u && u->p) print("%s: ", u->p->text);
print("growpte pointless\n");
goto Return;
}
.
## diffname port/page.c 1990/0801
## diff -e /n/bootesdump/1990/0728/sys/src/9/mips/page.c /n/bootesdump/1990/0801/sys/src/9/mips/page.c
533a
unusepage(pg, 1);
.
496c
if(max > 20*1024*1024) {pprint("segaddr %lux\n", max);print("segaddr %lux\n", max);}
.
253a
/*
* Move page to tail of list
*/
void
unusepage(Page *p, int dolock)
{
return;
if(dolock)
lock(&palloc);
/*
* Unlink
*/
if(p->prev)
p->prev->next = p->next;
else
palloc.head = p->next;
if(p->next)
p->next->prev = p->prev;
else
palloc.tail = p->prev;
/*
* Link
*/
p->prev = palloc.tail;
p->next = 0;
if(p->prev)
p->prev->next = p;
else
palloc.head = p;
palloc.tail = p;
if(dolock)
unlock(&palloc);
}
.
## diffname port/page.c 1990/0802
## diff -e /n/bootesdump/1990/0801/sys/src/9/mips/page.c /n/bootesdump/1990/0802/sys/src/9/mips/page.c
687c
if(u && u->p)
print("%s: %s: ", u->p->text, u->p->pgrp->user);
print("compactpte fails addr %lux\n", o->va+n*BY2PG);
return 0;
.
684c
return 1;
.
655c
return 1;
.
648c
int
.
645a
return;
Trouble:
unlock(&ptealloc);
if(u && u->p)
error(0, Enovmem);
panic("growpte fails %d %lux %d\n", n, o->va, o->npte);
.
644d
635c
if(!compactpte(o, n))
goto Trouble;
.
620c
if(!compactpte(o, n))
goto Trouble;
.
616c
if(!compactpte(o, n - p->n))
goto Trouble;
.
596d
543a
unlock(o);
poperror();
.
541a
lock(o);
if(waserror()){
unlock(o);
nexterror();
}
.
530d
342a
if(u && u->p)
poperror();
unlock(o);
.
341a
lock(o);
if(u && u->p && waserror()){
unlock(o);
unlock(&origalloc);
nexterror();
}
.
260d
6a
#include "errno.h"
.
## diffname port/page.c 1990/0814
## diff -e /n/bootesdump/1990/0802/sys/src/9/mips/page.c /n/bootesdump/1990/0814/sys/src/9/mips/page.c
665a
unlock(o);
.
661a
unlock(o);
.
647a
memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
p->n = n;
o->npte = n-1;
.
628,646c
if(!compactpte(o, n))
goto Trouble;
p = ptealloc.free;
ptealloc.free += n;
memcpy(p+1, o->pte, o->npte*sizeof(PTE));
p->o = o;
((PTEA*)(o->pte-1))->o = 0;
o->pte = p+1;
.
618,626c
n++;
if(p+p->n == ptealloc.free){
if(!compactpte(o, n - p->n))
goto Trouble;
p = (PTEA*)(o->pte - 1);
ptealloc.free += n - p->n;
.
616d
612,614c
if(o->npte >= n)
.
610a
lock(o);
.
603a
/*
* o is locked. this will always do a grow; if n<=o->npte someone
* else got here first and we can just return.
*/
.
557,558d
550,554d
351d
344d
342d
## diffname port/page.c 1990/1013
## diff -e /n/bootesdump/1990/0814/sys/src/9/mips/page.c /n/bootesdump/1990/1013/sys/src/9/mips/page.c
426c
npte = newmod(o);
.
400c
panic("mods %lux %d %d", o->va, o->npte, o->nmod);
.
385c
newmod(Orig *o)
.
## diffname port/page.c 1990/1018
## diff -e /n/bootesdump/1990/1013/sys/src/9/mips/page.c /n/bootesdump/1990/1018/sys/src/9/mips/page.c
465a
s->o = 0; /* seg() won't match it (e.g. in procread()) */
.
## diffname port/page.c 1990/1101
## diff -e /n/bootesdump/1990/1018/sys/src/9/mips/page.c /n/bootesdump/1990/1101/sys/src/9/mips/page.c
374a
if(freebroken())
goto lockloop;
print("no origs freed\n");
.
373d
318a
lockloop:
.
197a
print("no physical memory\n");
pprint("no physical memory\n");
.
195a
if(freebroken())
goto loop;
.
193,194d
## diffname port/page.c 1990/1115
## diff -e /n/bootesdump/1990/1101/sys/src/9/mips/page.c /n/bootesdump/1990/1115/sys/src/9/mips/page.c
562c
pexit("Suicide", 0);
.
## diffname port/page.c 1990/11211
## diff -e /n/bootesdump/1990/1115/sys/src/9/mips/page.c /n/bootesdump/1990/11211/sys/src/9/mips/page.c
656c
error(Enovmem);
.
493d
432d
404,405d
341,342c
o->qid = (Qid){~0, ~0};
o->mqid = (Qid){~0, ~0};
.
332d
301c
if(o->mchan==c->mchan && o->type==c->type && eqqid(o->mqid, c->mqid)){
.
299c
if(o->npage && eqqid(o->qid, c->qid))
.
297c
if(o->npage && o->qid.path==c->qid.path && o->va==va){
.
## diffname port/page.c 1990/1126
## diff -e /n/bootesdump/1990/11211/sys/src/9/mips/page.c /n/bootesdump/1990/1126/sys/src/9/mips/page.c
339c
o->type = ~0;
.
## diffname port/page.c 1990/1211
## diff -e /n/bootesdump/1990/1211/sys/src/9/mips/page.c /n/bootesdump/1990/1211/sys/src/9/port/page.c
154c
if(ppn < conf.npage0)
p->pa = conf.base0+(ppn<<PGSHIFT);
else
p->pa = conf.base1+((ppn-conf.npage0)<<PGSHIFT);
.
72a
if(palloc.addr >= conf.maxialloc)
panic("keep bill joy away");
.
## diffname port/page.c 1990/1212
## diff -e /n/bootesdump/1990/1211/sys/src/9/port/page.c /n/bootesdump/1990/1212/sys/src/9/port/page.c
579c
unusepage(pg, dolock);
.
569c
freepage(Orig *o, int dolock)
.
509c
freepage(o, 1);
.
370c
freepage(o, 1);
.
188c
freepage(o1, 0);
.
58c
if(palloc.active && n!=0)
.
## diffname port/page.c 1990/1214
## diff -e /n/bootesdump/1990/1212/sys/src/9/port/page.c /n/bootesdump/1990/1214/sys/src/9/port/page.c
344c
o->type = 0xFFFF;
.
## diffname port/page.c 1990/1226
## diff -e /n/bootesdump/1990/1214/sys/src/9/port/page.c /n/bootesdump/1990/1226/sys/src/9/port/page.c
701c
print("compactpte fails addr %lux %lux %d\n", o->va+n*BY2PG, o->va, n);
.
## diffname port/page.c 1991/0110
## diff -e /n/bootesdump/1990/1226/sys/src/9/port/page.c /n/bootesdump/1991/0110/sys/src/9/port/page.c
211c
print("page in use %lux %lux %lux %lux\n", p, p->va, p->o, origalloc.arena);
.
88c
nf = nb = 0;
.
## diffname port/page.c 1991/0115
## diff -e /n/bootesdump/1991/0110/sys/src/9/port/page.c /n/bootesdump/1991/0115/sys/src/9/port/page.c
466a
/*
* flushvirt() is a no-op on machines without virtual write-back caches.
* On such machines it is necessary to make sure the caches are flushed
* before the pages are remapped.
*/
flushvirt();
.
## diffname port/page.c 1991/0318
## diff -e /n/bootesdump/1991/0115/sys/src/9/port/page.c /n/bootesdump/1991/0318/sys/src/9/port/page.c
692c
memmove(p1, p2, p2->n*sizeof(PTE));
.
633c
memmove(p+1, o->pte, o->npte*sizeof(PTE));
.
## diffname port/page.c 1991/0425
## diff -e /n/bootesdump/1991/0318/sys/src/9/port/page.c /n/bootesdump/1991/0425/sys/src/9/port/page.c
49a
extern long end;
.
## diffname port/page.c 1991/0606
## diff -e /n/bootesdump/1991/0425/sys/src/9/port/page.c /n/bootesdump/1991/0606/sys/src/9/port/page.c
709a
return 0;
}
long
ibrk(ulong addr, int seg)
{
Seg *s;
s = &u->p->seg[seg];
if(seg == LSEG && s->o == 0)
mklockseg(s);
/* Allows us to determine the base of the segment */
if(addr == 0)
return s->minva;
if(addr < s->endseg){
pprint("addr below segment\n");
pexit("Suicide", 0);
error(Esegaddr);
}
if(addr > PGROUND(s->endseg))
if(segaddr(s, s->minva, addr) == 0){
pprint("bad segaddr in brk\n");
pexit("Suicide", 0);
error(Esegaddr);
}
s->endseg = addr;
.
552c
max = PGROUND(max);
.
71,74c
if(align)
palloc.addr = PGROUND(palloc.addr);
.
64,67c
if(align)
palloc.addr = PGROUND(palloc.addr);
.
## diffname port/page.c 1991/0607
## diff -e /n/bootesdump/1991/0606/sys/src/9/port/page.c /n/bootesdump/1991/0607/sys/src/9/port/page.c
590a
}
.
585c
(*o->freepg)(pg, dolock);
.
582c
for(i=0; i<o->npte; i++,pte++) {
.
431,432d
336a
o->freepg = unusepage;
.
## diffname port/page.c 1991/0705
## diff -e /n/bootesdump/1991/0607/sys/src/9/port/page.c /n/bootesdump/1991/0705/sys/src/9/port/page.c
730,738c
lock(&ptealloclk);
p->next = ptealloclk.free;
ptealloclk.free = p;
unlock(&ptealloclk);
.
720,727c
switch(s->type&SG_TYPE) {
case SG_PHYSICAL:
for(pg = p->pages; pg < ptop; pg++)
if(*pg)
(*s->pgfree)(*pg);
break;
default:
for(pg = p->pages; pg < ptop; pg++)
if(*pg)
putpage(*pg);
.
716,718c
ptop = &p->pages[PTEPERTAB];
.
714c
Page **pg, **ptop;
.
711,712c
void
freepte(Segment *s, Pte *p)
.
700,708c
new = ptealloclk.free;
ptealloclk.free = new->next;
unlock(&ptealloclk);
memset(new->pages, 0, sizeof(new->pages));
return new;
.
672,698c
lock(&ptealloclk);
while(ptealloclk.free == 0) {
unlock(&ptealloclk);
k = kmap(newpage(1, 0, 0));
new = (Pte*)VA(k);
n = (BY2PG/sizeof(Pte))-1;
for(i = 0; i < n; i++)
new[i].next = &new[i+1];
lock(&ptealloclk);
ptealloclk.pages++;
new[i].next = ptealloclk.free;
ptealloclk.free = new;
.
669,670c
Pte *new;
int i, n;
KMap *k;
.
666,667c
Pte*
ptealloc(void)
.
658,663c
return new;
.
638,656d
616,636c
end = &old->pages[PTEPERTAB];
for(src = old->pages, dst = new->pages; src < end; src++, dst++)
if(*src) {
if(onswap(*src))
dupswap(*src);
else {
lockpage(*src);
(*src)->ref++;
unlockpage(*src);
}
*dst = *src;
.
606,614c
new = ptealloc();
.
601,604c
Page **src, **dst, **end;
Pte *new;
.
594,599c
Pte*
ptecpy(Pte *old)
.
591c
unlock(&palloc.hashlock);
return 0;
.
588c
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);
unlockpage(f);
return f;
.
580,586c
lock(&palloc.hashlock);
for(f = palloc.hash[PGHFUN(i, daddr)]; f; f = f->hash) {
if(f->image == i && f->daddr == daddr) {
unlock(&palloc.hashlock);
lockpage(f);
if(f->image != i || f->daddr != daddr) {
unlockpage(f);
return 0;
.
576,578c
Page *f;
.
570,574c
Page *
lookpage(Image *i, ulong daddr)
.
545,567c
incref(i);
lock(&palloc.hashlock);
p->image = i;
l = &pghash(p);
p->hash = *l;
*l = p;
unlock(&palloc.hashlock);
.
543c
Page **l;
.
537,541c
void
cachepage(Page *p, Image *i)
.
507,533c
unlock(&palloc.hashlock);
putimage(p->image);
p->image = 0;
.
505a
l = &f->hash;
.
466,504c
if(p->image) {
lock(&palloc.hashlock);
l = &pghash(p);
for(f = *l; f; f = f->hash) {
if(f == p) {
*l = p->hash;
break;
.
458,464c
Page **l, *f;
.
456c
uncachepage(Page *p) /* Alway called with a locked page */
.
428,452c
ks = kmap(f);
kd = kmap(t);
memmove((void*)VA(kd), (void*)VA(ks), BY2PG);
kunmap(ks);
kunmap(kd);
.
424,426c
KMap *ks, *kd;
.
422c
copypage(Page *f, Page *t)
.
417,420d
407,414c
uncachepage(np);
np->va = p->va;
np->daddr = p->daddr;
copypage(p, np);
cachepage(np, p->image);
unlockpage(np);
uncachepage(p);
.
399,405c
lockpage(np); /* Cache the new version */
if(np->ref != 0) { /* Stolen by new page */
uncachepage(p);
unlockpage(np);
return;
.
394,397c
unlock(&palloc);
.
379,392c
else {
palloc.head = palloc.tail = np;
np->prev = np->next = 0;
}
.
360,377c
np = palloc.head; /* Allocate a new page from freelist */
if(palloc.head = np->next) /* = Assign */
palloc.head->prev = 0;
else
palloc.tail = 0;
if(palloc.tail) { /* Link back onto tail to give us lru */
np->prev = palloc.tail;
palloc.tail->next = np;
np->next = 0;
palloc.tail = np;
.
326,358c
lock(&palloc);
if(palloc.freecount < HIGHWATER || /* No freelist cache when memory is very low */
p->image == &swapimage) { /* No dup for swap pages */
unlock(&palloc);
uncachepage(p);
return;
.
323,324c
Page *np;
.
320,321c
void
duppage(Page *p) /* Always call with p locked */
.
317c
else {
if(palloc.head) {
p->next = palloc.head;
palloc.head->prev = p;
p->prev = 0;
palloc.head = p;
}
else {
palloc.head = palloc.tail = p;
p->prev = p->next = 0;
}
}
palloc.freecount++; /* Release people waiting for memory */
unlock(&palloc);
}
unlockpage(p);
if(palloc.wanted)
wakeup(&palloc.r);
.
315c
else {
palloc.head = palloc.tail = p;
p->prev = p->next = 0;
}
.
301,313c
lockpage(p);
if(--p->ref == 0) {
lock(&palloc);
if(p->image) {
if(palloc.tail) {
p->prev = palloc.tail;
palloc.tail->next = p;
p->next = 0;
palloc.tail = p;
.
295,299c
if(onswap(p)) {
putswap(p);
return;
}
.
268,293c
int count;
.
266c
putpage(Page *p)
.
262,264d
235,259c
return palloc.freecount >= HIGHWATER;
.
229,233c
int
ispages(void *p)
.
223,224d
203,218c
uncachepage(p);
p->ref++;
p->va = va;
p->modref = 0;
for(i = 0; i < MAXMACH; i++)
p->cachectl[i] = PG_NOFLUSH;
unlockpage(p);
if(clear){
.
199,201c
lockpage(p);
if(p->ref != 0)
.
197a
p = palloc.head;
if(palloc.head = p->next) /* = Assign */
palloc.head->prev = 0;
else
palloc.tail = 0;
palloc.freecount--;
.
196c
qlock(&palloc.pwait); /* Hold memory requesters here */
kickpager();
tsleep(&palloc.r, ispages, 0, 1000);
qunlock(&palloc.pwait);
lock(&palloc);
palloc.wanted--;
.
176,194c
/* The kp test is a poor guard against the pager deadlocking */
while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) {
palloc.wanted++;
unlock(&palloc);
if(s && *s) {
qunlock(&((*s)->lk));
*s = 0;
.
174c
.
170a
int i;
.
169d
166c
newpage(int clear, Segment **s, ulong va)
.
159a
palloc.freecount++;
.
152c
pmem = ((conf.npage-ppn)*BY2PG)/1024;
vmem = pmem + ((conf.nswap)*BY2PG)/1024;
palloc.user = conf.npage-ppn;
print("%lud free pages, %dK bytes, swap %dK bytes\n", palloc.user, pmem, vmem);
.
140,141c
pa = (conf.npage<<PGSHIFT) - nb; /* physical addr of first free page */
ppn = pa >> PGSHIFT; /* physical page number of first free page */
.
117,134d
114,115d
112c
ulong i, vmem, pmem;
.
79,108d
74a
.
50c
void
unlockpage(Page *p)
{
p->lock = 0;
}
.
45,48c
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();
}
}
.
37,43c
/* Multiplex a hardware lock for per page manipulations */
void
lockpage(Page *p)
{
int s;
.
27,35c
extern long end;
static Lock pglock;
.
23,25c
Pte *free;
int pages;
}ptealloclk;
.
20c
struct Palloc palloc;
struct Ptealloc
.
9,18c
#define PGHFUN(x, y) (((ulong)x^(ulong)y)%PGHSIZE)
#define pghash(s) palloc.hash[PGHFUN(s->image, p->daddr)]
.
## diffname port/page.c 1991/0718
## diff -e /n/bootesdump/1991/0705/sys/src/9/port/page.c /n/bootesdump/1991/0718/sys/src/9/port/page.c
299c
uncachepage(Page *p) /* Always called with a locked page */
.
## diffname port/page.c 1991/0801
## diff -e /n/bootesdump/1991/0718/sys/src/9/port/page.c /n/bootesdump/1991/0801/sys/src/9/port/page.c
67a
if(palloc.addr+n > conf.base0 + conf.npage0*BY2PG)
palloc.addr = conf.base1;
.
## diffname port/page.c 1991/0802
## diff -e /n/bootesdump/1991/0801/sys/src/9/port/page.c /n/bootesdump/1991/0802/sys/src/9/port/page.c
123a
palloc.user = palloc.freecount = p - palloc.head;
pmem = palloc.user*BY2PG/1024;
vmem = pmem + ((conf.nswap)*BY2PG)/1024;
print("%lud free pages, %dK bytes, swap %dK bytes\n", palloc.user, pmem, vmem);
.
121a
addr = palloc.addr1 = PGROUND(palloc.addr1);
lim = conf.base1 + (conf.npage1<<PGSHIFT);
for(; addr < lim; addr += BY2PG){
p->next = p+1;
p->prev = p-1;
p->pa = addr;
p++;
}
palloc.tail = p - 1;
.
116,120c
p->pa = addr;
p++;
.
104,113c
/*
* 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){
.
101,102c
palloc.head = ialloc(np*sizeof(Page), 0);
palloc.active = 1;
.
99c
* 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.
.
92,97d
90c
/*
* 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;
.
86c
ulong np, addr, lim;
.
79a
/*
* zero it
*/
memset((void*)(p|KZERO), 0, n);
/*
* don't put anything else into a page aligned ialloc
*/
*ap = align ? PGROUND(p+n) : (p+n);
.
77,78c
if(p >= conf.maxialloc)
panic("keep bill joy away 2");
.
71,75c
/*
* try first bank
*/
p = align ? PGROUND(palloc.addr0) : palloc.addr0;
if(p+n > conf.base0 + (conf.npage0<<PGSHIFT)){
/*
* no room in first bank, try second bank
*/
if(conf.npage1 <= 0)
panic("keep bill joy away 1");
p = align ? PGROUND(palloc.addr1) : palloc.addr1;
ap = &palloc.addr1;
} else
ap = &palloc.addr0;
.
68,69c
if(palloc.addr0 == 0){
palloc.addr0 = ((ulong)&end)&~KZERO;
palloc.addr1 = conf.base1;
}
.
63,66d
59a
ulong *ap;
.
54c
* Called to allocate permanent data structures, before calling pageinit().
* We assume all of text+data+bss is in the first memory bank.
.
## diffname port/page.c 1991/0806
## diff -e /n/bootesdump/1991/0802/sys/src/9/port/page.c /n/bootesdump/1991/0806/sys/src/9/port/page.c
179a
poperror();
.
177a
if(waserror()) {
qunlock(&palloc.pwait);
lock(&palloc);
palloc.wanted--;
unlock(&palloc);
nexterror();
}
.
171c
unlock(&palloc);
.
## diffname port/page.c 1991/0807
## diff -e /n/bootesdump/1991/0806/sys/src/9/port/page.c /n/bootesdump/1991/0807/sys/src/9/port/page.c
67c
/* addr0 and addr1 are physical addresses */
palloc.addr0 = (((ulong)&end)&~KZERO) + conf.base0;
.
## diffname port/page.c 1991/0906
## diff -e /n/bootesdump/1991/0807/sys/src/9/port/page.c /n/bootesdump/1991/0906/sys/src/9/port/page.c
179,185c
while(waserror()) /* Ignore interrupts */
;
.
## diffname port/page.c 1991/1003
## diff -e /n/bootesdump/1991/0906/sys/src/9/port/page.c /n/bootesdump/1991/1003/sys/src/9/port/page.c
276a
simpleputpage(Page *pg) /* Always call with palloc locked */
{
pg->ref = 0;
palloc.freecount++;
if(palloc.head) {
pg->next = palloc.head;
palloc.head->prev = pg;
pg->prev = 0;
palloc.head = pg;
}
else {
palloc.head = palloc.tail = pg;
pg->prev = pg->next = 0;
}
}
void
.
## diffname port/page.c 1991/1115
## diff -e /n/bootesdump/1991/1003/sys/src/9/port/page.c /n/bootesdump/1991/1115/sys/src/9/port/page.c
225a
USED(p);
.
## diffname port/page.c 1991/1122
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/page.c /n/bootesdump/1991/1122/sys/src/9/port/page.c
497c
for(pg = p->first; pg <= p->last; pg++)
.
491a
ptop = &p->pages[PTEPERTAB];
.
488,489d
479a
new->first = &new->pages[PTEPERTAB];
new->last = new->pages;
.
464c
k = kmap(newpage(0, 0, 0));
.
446a
new->last = dst;
.
436,438c
dst = &new->pages[old->first-old->pages];
new->first = dst;
for(src = old->first; src <= old->last; src++, dst++)
.
## diffname port/page.c 1992/0111
## diff -e /n/bootesdump/1991/1122/sys/src/9/port/page.c /n/bootesdump/1992/0111/sys/src/9/port/page.c
7c
#include "../port/error.h"
.
## diffname port/page.c 1992/0120
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/page.c /n/bootesdump/1992/0120/sys/src/9/port/page.c
6d
## diffname port/page.c 1992/0131
## diff -e /n/bootesdump/1992/0120/sys/src/9/port/page.c /n/bootesdump/1992/0131/sys/src/9/port/page.c
500a
*pg = 0;
}
.
499c
if(*pg) {
.
495a
*pg = 0;
}
.
494c
if(*pg) {
.
481a
.
479d
464c
k = kmap(newpage(1, 0, 0));
.
## diffname port/page.c 1992/0204
## diff -e /n/bootesdump/1992/0131/sys/src/9/port/page.c /n/bootesdump/1992/0204/sys/src/9/port/page.c
264a
p->prev = 0;
.
263c
p->next = 0;
.
258d
252a
p->next = 0;
.
251c
p->prev = 0;
.
246d
## diffname port/page.c 1992/0303
## diff -e /n/bootesdump/1992/0204/sys/src/9/port/page.c /n/bootesdump/1992/0303/sys/src/9/port/page.c
300,301c
/* No freelist cache when memory is very low, No dup for swap pages */
if(palloc.freecount < swapalloc.highwater ||
p->image == &swapimage) {
.
271,272c
if(wake && palloc.wanted)
.
266a
wake = 1;
.
263a
palloc.head = p;
.
261c
palloc.tail = p;
.
258d
251a
palloc.tail = p;
.
249c
palloc.head = p;
.
246d
242c
if(p->image && p->image != &swapimage) {
.
238a
wake = 0;
.
232c
int wake;
.
226c
return palloc.freecount >= swapalloc.highwater;
.
169c
while((palloc.freecount < swapalloc.highwater && u->p->kp == 0)||palloc.freecount == 0) {
.
153c
/* 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;
print("%lud free pages, %dK bytes, swap %dK bytes, highwater %dK, headroom %dK\n",
palloc.user, pmem, vmem, hw, hr);
.
106c
ulong i, vmem, pmem, hw, hr;
.
## diffname port/page.c 1992/0304
## diff -e /n/bootesdump/1992/0303/sys/src/9/port/page.c /n/bootesdump/1992/0304/sys/src/9/port/page.c
281,282d
276d
247d
240,241d
## diffname port/page.c 1992/0313
## diff -e /n/bootesdump/1992/0304/sys/src/9/port/page.c /n/bootesdump/1992/0313/sys/src/9/port/page.c
99a
}
/*
* allocate with possible page alignment
*/
void*
ialloc(ulong n, int align)
{
return iallocspan(n, align ? BY2PG : 0, 0);
.
97c
memset((void*)(p|KZERO), 0, n);
.
95c
* zero it
.
92c
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;
.
90c
* remember high water marks
.
88a
/* 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");
.
86,87c
p = 0;
for(r = region; r < ®ion[Nregion]; r++){
/* allign region */
p = r->start;
if(align){
m = p % align;
if(m)
p += align - m;
}
.
74,84c
if(align){
m = n % align;
if(m)
n += align - m;
}
.
72c
* alignment also applies to length
.
66,68c
region[Nregion-2].start = (((ulong)&end)&~KZERO) + conf.base0;
region[Nregion-2].end = conf.base0 + (conf.npage0<<PGSHIFT);
region[Nregion-1].start = conf.base1;
region[Nregion-1].end = conf.base1 + (conf.npage1<<PGSHIFT);
palloc.addr0 = region[Nregion-2].start;
palloc.addr1 = region[Nregion-1].start;
.
60c
Region *r;
int m;
int ledge;
.
57c
iallocspan(ulong n, int align, ulong crevasse)
.
55a
void
addsplit(Region *r, ulong start, ulong end)
{
Region *rr;
int len = end - start;
/* first look for an unused one */
for(rr = region; rr < ®ion[Nregion]; rr++){
if(rr == r)
continue;
if(rr->end - rr->start == 0){
rr->start = start;
rr->end = end;
return;
}
}
/* then look for a smaller one */
for(rr = region; rr < ®ion[Nregion]; rr++){
if(rr == r)
continue;
if(rr->end - rr->start < len){
rr->start = start;
rr->end = end;
return;
}
}
}
.
54a
*
* alignment is in number of bytes
*
* WARNING: You can't cross a crevasse!
.
51a
typedef struct Region Region;
struct Region
{
ulong start;
ulong end;
};
enum
{
Nregion= 10,
};
Region region[Nregion];
.
## diffname port/page.c 1992/0315
## diff -e /n/bootesdump/1992/0313/sys/src/9/port/page.c /n/bootesdump/1992/0315/sys/src/9/port/page.c
134c
/* align region */
.
101a
/*
* Called to allocate permanent data structures, before calling pageinit().
* We assume all of text+data+bss is in the first memory bank.
*
* alignment is in number of bytes. It pretains both to the start and
* end of the allocated memory.
*
* If crevasse is specified, no allocation can span an address that is
* a multiple of crevasse.
*/
.
66,73d
20c
extern long end;
ulong hiaddr;
.
## diffname port/page.c 1992/0317
## diff -e /n/bootesdump/1992/0315/sys/src/9/port/page.c /n/bootesdump/1992/0317/sys/src/9/port/page.c
197a
print("addr0 %lux addr1 %lux\n", palloc.addr0, palloc.addr1);
.
100c
* alignment is in number of bytes. It pertains both to the start and
.
## diffname port/page.c 1992/0318
## diff -e /n/bootesdump/1992/0317/sys/src/9/port/page.c /n/bootesdump/1992/0318/sys/src/9/port/page.c
198d
## diffname port/page.c 1992/0319
## diff -e /n/bootesdump/1992/0318/sys/src/9/port/page.c /n/bootesdump/1992/0319/sys/src/9/port/page.c
118c
region[Nregion-2].start = (((ulong)end)&~KZERO) + conf.base0;
.
20d
## diffname port/page.c 1992/0321
## diff -e /n/bootesdump/1992/0319/sys/src/9/port/page.c /n/bootesdump/1992/0321/sys/src/9/port/page.c
2c
#include "../port/lib.h"
.
## diffname port/page.c 1992/0618
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/page.c /n/bootesdump/1992/0618/sys/src/9/port/page.c
177d
117,120c
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);
.
110d
107a
int m;
.
84c
for(rr = region; rr < eregion; rr++){
.
73c
for(rr = region; rr < eregion; rr++){
.
71a
len = end - start;
eregion = ®ion[Nregion];
.
69,70c
int len;
Region *rr, *eregion;
.
## diffname port/page.c 1992/0619
## diff -e /n/bootesdump/1992/0618/sys/src/9/port/page.c /n/bootesdump/1992/0619/sys/src/9/port/page.c
606a
}
/* 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;
.
269c
while((palloc.freecount < swapalloc.highwater && u->p->kp == 0) ||
palloc.freecount == 0) {
.
263,265d
252,253c
print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",
palloc.user, pmem, vmem, hw/1024, hr/1024);
.
249,250c
hw = swapalloc.highwater*BY2PG;
hr = swapalloc.headroom*BY2PG;
.
244c
vmem = pmem + (conf.nswap*BY2PG)/1024;
.
242c
palloc.user = p - palloc.head;
palloc.freecount = palloc.user;
.
235c
p->next = p+1;
p->pa = palloc.p1;
palloc.p1 += BY2PG;
palloc.np1--;
.
230,233c
while(palloc.np1 > 0) {
.
227c
p->next = p+1;
p->pa = palloc.p0;
palloc.p0 += BY2PG;
palloc.np0--;
.
222,225c
while(palloc.np0 > 0) {
.
209,220d
201,207c
np = palloc.np0+palloc.np1;
palloc.head = xalloc(np*sizeof(Page));
if(palloc.head == 0)
panic("pageinit");
.
199a
ulong np, hw, hr, vmem, pmem;
.
197,198d
25,194d
23d
20,21c
static Lock pglock;
struct Palloc palloc;
.
11,12d
## diffname port/page.c 1992/0620
## diff -e /n/bootesdump/1992/0619/sys/src/9/port/page.c /n/bootesdump/1992/0620/sys/src/9/port/page.c
413,417c
free(p);
.
388d
367,385c
new = smalloc(sizeof(Pte));
.
364,365d
11,17d
## diffname port/page.c 1992/0621
## diff -e /n/bootesdump/1992/0620/sys/src/9/port/page.c /n/bootesdump/1992/0621/sys/src/9/port/page.c
24c
print("page: %lux %d %lux %d\n", palloc.p0, palloc.np0, palloc.p1, palloc.np1);
.
## diffname port/page.c 1992/0622
## diff -e /n/bootesdump/1992/0621/sys/src/9/port/page.c /n/bootesdump/1992/0622/sys/src/9/port/page.c
24c
.
## diffname port/page.c 1992/0625
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/page.c /n/bootesdump/1992/0625/sys/src/9/port/page.c
386,414d
344c
unlock(*src);
.
342c
lock(*src);
.
332a
Page **src, **dst, **end;
.
331d
320c
unlock(f);
.
301c
unlock(f);
.
299c
lock(f);
.
272a
unlock(&palloc.hashlock);
putimage(p->image);
p->image = 0;
.
269,271c
l = &f->hash;
.
259,267c
if(p->image == 0)
return;
lock(&palloc.hashlock);
l = &pghash(p);
for(f = *l; f; f = f->hash) {
if(f == p) {
*l = p->hash;
break;
.
238c
unlock(np);
.
229c
unlock(np);
.
226c
lock(np); /* Cache the new version */
.
189a
pg->next = palloc.head;
palloc.head->prev = pg;
pg->prev = 0;
palloc.head = pg;
.
188a
return;
.
180,186c
if(palloc.head == 0) {
.
172c
unlock(p);
.
141c
lock(p);
.
115c
unlock(p);
.
104c
lock(p);
.
## diffname port/page.c 1992/0628
## diff -e /n/bootesdump/1992/0625/sys/src/9/port/page.c /n/bootesdump/1992/0628/sys/src/9/port/page.c
199,200c
if(palloc.freecount < swapalloc.highwater) {
.
195a
if(p->image == &swapimage)
return;
.
## diffname port/page.c 1992/0629
## diff -e /n/bootesdump/1992/0628/sys/src/9/port/page.c /n/bootesdump/1992/0629/sys/src/9/port/page.c
287a
unlock(&palloc.hashlock);
}
void
cachedel(Image *i, ulong daddr)
{
Page *f, **l;
lock(&palloc.hashlock);
l = &palloc.hash[PGHFUN(i, daddr)];
for(f = *l; f; f = f->hash) {
if(f->image == i && f->daddr == daddr) {
*l = f->hash;
break;
}
l = &f->hash;
}
.
200,201c
/* No freelist cache when memory is very low */
.
197a
}
.
196c
/* No dup for swap pages */
if(p->image == &swapimage) {
uncachepage(p);
.
## diffname port/page.c 1992/0711
## diff -e /n/bootesdump/1992/0629/sys/src/9/port/page.c /n/bootesdump/1992/0711/sys/src/9/port/page.c
353c
Page **src, **dst;
.
## diffname port/page.c 1992/0805
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/page.c /n/bootesdump/1992/0805/sys/src/9/port/page.c
90a
/*
* If called from fault and we lost the segment from underneath
* don't waste time allocating and freeing a page. Fault will call
* newpage again when it has reaquired the segment locks
*/
if(dontalloc)
return 0;
.
78a
dontalloc = 1;
.
75a
dontalloc = 0;
.
71,73c
hw = swapalloc.highwater;
while((palloc.freecount < hw && u->p->kp == 0) || palloc.freecount == 0) {
.
67c
int hw, i, dontalloc;
.
## diffname port/page.c 1992/0905
## diff -e /n/bootesdump/1992/0805/sys/src/9/port/page.c /n/bootesdump/1992/0905/sys/src/9/port/page.c
240c
if(np->ref != 0) { /* Stolen by lookpage */
.
187a
if(pg->ref != 1)
panic("simpleputpage");
.
115,118c
if(p->ref != 0) { /* lookpage has priority on steal */
unlock(p);
goto retry;
}
.
68a
retry:
.
## diffname port/page.c 1992/0910
## diff -e /n/bootesdump/1992/0905/sys/src/9/port/page.c /n/bootesdump/1992/0910/sys/src/9/port/page.c
97c
* newpage again when it has reacquired the segment locks
.
## diffname port/page.c 1992/0911
## diff -e /n/bootesdump/1992/0910/sys/src/9/port/page.c /n/bootesdump/1992/0911/sys/src/9/port/page.c
58,59c
/* print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",
palloc.user, pmem, vmem, hw/1024, hr/1024);/**/
.
## diffname port/page.c 1992/0913
## diff -e /n/bootesdump/1992/0911/sys/src/9/port/page.c /n/bootesdump/1992/0913/sys/src/9/port/page.c
58c
print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",
.
## diffname port/page.c 1992/1209
## diff -e /n/bootesdump/1992/0913/sys/src/9/port/page.c /n/bootesdump/1992/1209/sys/src/9/port/page.c
329c
for(f = pghash(daddr); f; f = f->hash) {
.
312c
l = &pghash(daddr);
.
300c
l = &pghash(p->daddr);
.
296a
/* If this ever happens it should be fixed by calling
* uncachepage instead of panic. I think there is a race
* with pio in which this can happen. Calling uncachepage is
* correct - I just wanted to see if we got here.
*/
if(p->image)
panic("cachepage");
.
279c
l = &pghash(p->daddr);
.
271c
uncachepage(Page *p) /* Always called with a locked page */
.
229c
if(palloc.tail) { /* Link back onto tail to give us lru */
.
223,224c
np = palloc.head; /* Allocate a new page from freelist */
if(palloc.head = np->next) /* = Assign */
.
180c
palloc.freecount++; /* Release people waiting for memory */
.
116c
if(p->ref != 0) { /* lookpage has priority on steal */
.
8,9c
#define pghash(daddr) palloc.hash[(daddr>>PGSHIFT)&(PGHSIZE-1)]
.
## diffname port/page.c 1993/0116
## diff -e /n/bootesdump/1992/1209/sys/src/9/port/page.c /n/bootesdump/1993/0116/sys/src/9/port/page.c
250a
mmunewpage(np);
.
124a
mmunewpage(p);
.
## diffname port/page.c 1993/0210
## diff -e /n/bootesdump/1993/0116/sys/src/9/port/page.c /n/bootesdump/1993/0210/sys/src/9/port/page.c
419a
break;
}
for(pg = p->pages; pg < ptop; pg++) {
pt = *pg;
if(pt == 0)
continue;
lock(pt);
ref = --pt->ref;
unlock(pt);
if(ref == 0)
free(pt);
}
.
415,417c
if(fn) {
for(pg = p->pages; pg < ptop; pg++) {
if(*pg == 0)
continue;
(*fn)(*pg);
.
413a
fn = s->pseg->pgfree;
.
410c
int ref;
Page *pt, **pg, **ptop;
void (*fn)(Page*);
.
## diffname port/page.c 1993/0501
## diff -e /n/bootesdump/1993/0210/sys/src/9/port/page.c /n/fornaxdump/1993/0501/sys/src/brazil/port/page.c
412a
Page *pt, **pg, **ptop;
.
411d
252c
for(i = 0; i < MAXMACH; i++)
np->cachectl[i] |= PG_DATINVALID;
.
207a
int i;
.
123,125c
memset(p->cachectl, PG_DATINVALID, sizeof(p->cachectl));
.
72c
while((palloc.freecount < hw && up->kp == 0) || palloc.freecount == 0) {
.
66c
int hw, dontalloc;
.
54,58c
print("%lud free pages\n%dK bytes\n%dK swap\n", palloc.user, pmem, vmem);
.
17c
ulong np, vmem, pmem;
.
## diffname port/page.c 1993/0810
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/page.c /n/fornaxdump/1993/0810/sys/src/brazil/port/page.c
192,195c
palloc.freecount++; /* Release people waiting for memory */
unlock(&palloc);
unlock(p);
.
177,190c
else {
if(palloc.head) {
p->next = palloc.head;
palloc.head->prev = p;
}
else {
palloc.tail = p;
p->next = 0;
}
palloc.head = p;
p->prev = 0;
.
173,175c
palloc.tail = p;
p->next = 0;
.
162,169d
147,159c
if(--p->ref > 0) {
unlock(p);
return;
}
vcacheinval(p);
lock(&palloc);
if(p->image && p->image != &swapimage) {
if(palloc.tail) {
p->prev = palloc.tail;
palloc.tail->next = p;
.
122c
if(clear) {
.
90,92c
* If called from fault and we lost the segment from
* underneath don't waste time allocating and freeing
* a page. Fault will call newpage again when it has
* reacquired the segment locks
.
79c
while(waserror()) /* Ignore interrupts */
.
77c
qlock(&palloc.pwait); /* Hold memory requesters here */
.
68c
fc = palloc.freecount;
while((fc < hw && up->kp == 0) || fc == 0) {
.
62c
int hw, dontalloc, fc;
.
## diffname port/page.c 1993/0811
## diff -e /n/fornaxdump/1993/0810/sys/src/brazil/port/page.c /n/fornaxdump/1993/0811/sys/src/brazil/port/page.c
234,235d
189d
152a
.
121c
for(i = 0; i < MAXMACH; i++)
p->cachectl[i] = PG_NOFLUSH;
.
62c
int i, hw, dontalloc, fc;
.
## diffname port/page.c 1993/0815
## diff -e /n/fornaxdump/1993/0811/sys/src/brazil/port/page.c /n/fornaxdump/1993/0815/sys/src/brazil/port/page.c
155c
vcacheinval(p, p->va);
.
## diffname port/page.c 1993/0816
## diff -e /n/fornaxdump/1993/0815/sys/src/brazil/port/page.c /n/fornaxdump/1993/0816/sys/src/brazil/port/page.c
230a
if(np->log == 0) {
np->log = smalloc(8192);
np->lptr = 0;
}
.
116a
if(p->log == 0) {
p->log = smalloc(8192);
p->lptr = 0;
}
.
## diffname port/page.c 1993/0817
## diff -e /n/fornaxdump/1993/0816/sys/src/brazil/port/page.c /n/fornaxdump/1993/0817/sys/src/brazil/port/page.c
351a
palloc.freecol[f->color]--;
.
217a
if(np->next)
np->next->prev = np->prev;
else
palloc.tail = np->prev;
.
216c
palloc.head = np->next;
.
212,214c
color = getcolor(p->va);
for(np = palloc.head; np; np = np->next)
if(np->color == color)
break;
/* No page of the correct color */
if(np == 0) {
unlock(&palloc);
uncachepage(p);
return;
}
if(np->prev)
np->prev->next = np->next;
.
196a
int color;
.
188a
palloc.freecol[p->color]++;
if(palloc.r.p != 0)
wakeup(&palloc.r);
.
161d
109a
palloc.freecol[color]--;
.
108a
if(p->next)
p->next->prev = p->prev;
else
palloc.tail = p->prev;
.
107c
palloc.head = p->next;
.
103,105c
for(p = palloc.head; p; p = p->next)
if(p->color == color)
break;
if(p == 0)
panic("newpage");
if(p->prev)
p->prev->next = p->next;
.
78c
qlock(&palloc.pwait); /* Hold memory requesters here */
.
68,69c
for(;;) {
if(palloc.freecol[color] > hw)
break;
if(up->kp && palloc.freecol[color] > 0)
break;
.
66a
color = getcolor(va);
.
62c
int i, hw, dontalloc, color;
.
54c
print("%lud free pages\n%dK bytes\n%dK swap\n", palloc.user, pm, vm);
.
51c
swapalloc.highwater = (palloc.user*5)/100;
.
46,48c
pm = palloc.user*BY2PG/1024;
vm = pm + (conf.nswap*BY2PG)/1024;
.
36a
p->color = color;
palloc.freecol[color]++;
color = (color+1)%NCOLOR;
.
28a
p->color = color;
palloc.freecol[color]++;
color = (color+1)%NCOLOR;
.
23a
color = 0;
.
17c
ulong np, vm, pm;
.
15a
int color;
.
## diffname port/page.c 1993/0818
## diff -e /n/fornaxdump/1993/0817/sys/src/brazil/port/page.c /n/fornaxdump/1993/0818/sys/src/brazil/port/page.c
282,285d
263c
/* Link back onto tail to give us lru in the free list */
if(palloc.tail) {
.
143,147d
## diffname port/page.c 1993/0819
## diff -e /n/fornaxdump/1993/0818/sys/src/brazil/port/page.c /n/fornaxdump/1993/0819/sys/src/brazil/port/page.c
365a
return 0;
.
## diffname port/page.c 1993/0825
## diff -e /n/fornaxdump/1993/0819/sys/src/brazil/port/page.c /n/fornaxdump/1993/0825/sys/src/brazil/port/page.c
398a
print("#");
.
366d
## diffname port/page.c 1993/0827
## diff -e /n/fornaxdump/1993/0825/sys/src/brazil/port/page.c /n/fornaxdump/1993/0827/sys/src/brazil/port/page.c
398d
## diffname port/page.c 1993/0906
## diff -e /n/fornaxdump/1993/0827/sys/src/brazil/port/page.c /n/fornaxdump/1993/0906/sys/src/brazil/port/page.c
236c
color = getpgcolor(p->va);
.
74c
color = getpgcolor(va);
.
## diffname port/page.c 1993/0910
## diff -e /n/fornaxdump/1993/0906/sys/src/brazil/port/page.c /n/fornaxdump/1993/0910/sys/src/brazil/port/page.c
388c
.
230c
if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) {
.
209,210c
r = &palloc.r[p->color];
if(r->p != 0)
wakeup(r);
.
207d
169a
Rendez *r;
.
163,164c
int color;
color = (int)p;
return palloc.freecol[color] >= swapalloc.highwater/NCOLOR;
.
133d
100c
qunlock(&palloc.pwait[color]);
.
96c
tsleep(&palloc.r[color], ispages, (void*)color, 1000);
.
90c
qlock(&palloc.pwait[color]); /* Hold memory requesters here */
.
## diffname port/page.c 1993/0918
## diff -e /n/fornaxdump/1993/0910/sys/src/brazil/port/page.c /n/fornaxdump/1993/0918/sys/src/brazil/port/page.c
61c
print("%lud free pages\n", palloc.user);
print("%dK bytes\n", pm);
print("%dK swap\n", vm);
.
## diffname port/page.c 1993/1008
## diff -e /n/fornaxdump/1993/0918/sys/src/brazil/port/page.c /n/fornaxdump/1993/1008/sys/src/brazil/port/page.c
79c
if(palloc.freecol[color] > hw/NCOLOR)
.
## diffname port/page.c 1993/1015
## diff -e /n/fornaxdump/1993/1008/sys/src/brazil/port/page.c /n/fornaxdump/1993/1015/sys/src/brazil/port/page.c
324a
p->daddr = 0;
.
220a
Page*
auxpage()
{
Page *p;
lock(&palloc);
p = palloc.head;
if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) {
unlock(&palloc);
return 0;
}
p->next->prev = 0;
palloc.head = p->next;
palloc.freecol[p->color]--;
unlock(&palloc);
lock(p);
if(p->ref != 0) { /* Stolen by lookpage */
unlock(p);
return 0;
}
p->ref++;
uncachepage(p);
unlock(p);
return p;
}
.
## diffname port/page.c 1993/1120
## diff -e /n/fornaxdump/1993/1015/sys/src/brazil/port/page.c /n/fornaxdump/1993/1120/sys/src/brazil/port/page.c
422c
palloc.freecount--;
.
262c
if(palloc.freecount < swapalloc.highwater) {
.
234c
palloc.freecount--;
.
228c
if(palloc.freecount < swapalloc.highwater) {
.
212,215c
palloc.freecount++;
if(palloc.r.p != 0)
wakeup(&palloc.r);
.
173,174d
164,167c
USED(p);
return palloc.freecount >= swapalloc.highwater;
.
140a
print("stolen\n");
lock(&palloc);
palloc.freecount++;
.
135c
palloc.freecount--;
.
121,122c
if(p == 0) {
p = palloc.head;
memset(p->cachectl, PG_DATFLUSH, sizeof(p->cachectl));
p->color = color;
}
.
116a
/* First try for out colour */
.
114d
102c
qunlock(&palloc.pwait);
.
98c
tsleep(&palloc.r, ispages, 0, 1000);
.
92c
qlock(&palloc.pwait); /* Hold memory requesters here */
.
84d
81c
if(up->kp && palloc.freecount > 0)
.
79c
if(palloc.freecount > hw)
.
75a
lock(&palloc);
retry:
.
73,74d
43c
palloc.freecount++;
.
32c
palloc.freecount++;
.
## diffname port/page.c 1993/1211
## diff -e /n/fornaxdump/1993/1120/sys/src/brazil/port/page.c /n/fornaxdump/1993/1211/sys/src/brazil/port/page.c
120a
print("! ");
.
## diffname port/page.c 1993/1212
## diff -e /n/fornaxdump/1993/1211/sys/src/brazil/port/page.c /n/fornaxdump/1993/1212/sys/src/brazil/port/page.c
123c
memset(p->cachectl, PG_NEWCOL, sizeof(p->cachectl));
.
115c
/* First try for our colour */
.
## diffname port/page.c 1993/1219
## diff -e /n/fornaxdump/1993/1212/sys/src/brazil/port/page.c /n/fornaxdump/1993/1219/sys/src/brazil/port/page.c
137d
## diffname port/page.c 1994/0508
## diff -e /n/fornaxdump/1993/1219/sys/src/brazil/port/page.c /n/fornaxdump/1994/0508/sys/src/brazil/port/page.c
121d
## diffname port/page.c 1994/0817
## diff -e /n/fornaxdump/1994/0508/sys/src/brazil/port/page.c /n/fornaxdump/1994/0817/sys/src/brazil/port/page.c
336c
if(p->image == 0 || p->image->notext)
.
257d
253,255c
/* No dup for swap/cache pages */
if(p->image->notext)
.
## diffname port/page.c 1994/0819
## diff -e /n/fornaxdump/1994/0817/sys/src/brazil/port/page.c /n/fornaxdump/1994/0819/sys/src/brazil/port/page.c
334c
if(p->image == 0)
.
## diffname port/page.c 1994/1213
## diff -e /n/fornaxdump/1994/0819/sys/src/brazil/port/page.c /n/fornaxdump/1994/1213/sys/src/brazil/port/page.c
153c
p->cachectl[i] = ct;
.
123a
ct = PG_NEWCOL;
.
122d
119a
ct = PG_NOFLUSH;
.
70a
uchar ct;
.
## diffname port/page.c 1995/0804
## diff -e /n/fornaxdump/1994/1213/sys/src/brazil/port/page.c /n/fornaxdump/1995/0804/sys/src/brazil/port/page.c
170d
168c
ispages(void*)
.
## diffname port/page.c 1998/0512
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/page.c /n/emeliedump/1998/0512/sys/src/brazil/port/page.c
490c
if(pt == 0)
.
454c
return new;
.
425c
return f;
.
410c
if(f->prev)
.
308c
.
278c
if(np->prev)
.
274c
uncachepage(p);
.
262c
uncachepage(p);
.
128c
if(p->prev)
.
106,107c
* underneath don't waste time allocating and freeing
* a page. Fault will call newpage again when it has
.
## diffname port/page.c 1998/0513
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/page.c /n/emeliedump/1998/0513/sys/src/brazil/port/page.c
428a
.
424a
.
423d
419d
414d
407,408d
404a
unlock(&palloc);
.
401a
lock(&palloc);
.
302,308c
/* Cache the new version */
.
299a
lock(np);
.
282d
258c
/*
* 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;
}
.
255c
if(p->ref == 0 || p->image == nil || p->image->notext)
.
253a
retries = 0;
retry:
if(retries++ > 10000)
panic("duppage");
.
252a
int retries;
.
244a
unlock(&palloc);
.
238,241c
if(p->ref != 0)
panic("auxpage");
.
235d
218a
unlock(&palloc);
.
217d
213a
.
212d
187d
183a
unlock(&palloc);
.
180a
lock(&palloc);
.
156a
unlock(&palloc);
.
142,148c
if(p->ref != 0)
panic("newpage");
.
139d
137d
132d
76d
## diffname port/page.c 1998/0605
## diff -e /n/emeliedump/1998/0513/sys/src/brazil/port/page.c /n/emeliedump/1998/0605/sys/src/brazil/port/page.c
414,424c
if(++f->ref == 1)
pageunchain(f);
.
298,309d
289,296c
pageunchain(np);
pagechaintail(np);
.
250c
panic("duppage %d", retries);
.
248a
.
225,227c
pageunchain(p);
.
181,205c
if(p->image && p->image != &swapimage)
pagechaintail(p);
else
pagechainhead(p);
.
127,135c
pageunchain(p);
.
74d
65a
static void
pageunchain(Page *p)
{
if(canlock(&palloc))
panic("pageunchain");
if(p->prev)
p->prev->next = p->next;
else
palloc.head = p->next;
if(p->next)
p->next->prev = p->prev;
else
palloc.tail = p->prev;
p->prev = p->next = nil;
palloc.freecount--;
}
void
pagechaintail(Page *p)
{
if(canlock(&palloc))
panic("pagechaintail");
if(palloc.tail) {
p->prev = palloc.tail;
palloc.tail->next = p;
}
else {
palloc.head = p;
p->prev = 0;
}
palloc.tail = p;
p->next = 0;
palloc.freecount++;
}
void
pagechainhead(Page *p)
{
if(canlock(&palloc))
panic("pagechainhead");
if(palloc.head) {
p->next = palloc.head;
palloc.head->prev = p;
}
else {
palloc.tail = p;
p->next = 0;
}
palloc.head = p;
p->prev = 0;
palloc.freecount++;
}
.
10d
## diffname port/page.c 1998/0825
## diff -e /n/emeliedump/1998/0605/sys/src/brazil/port/page.c /n/emeliedump/1998/0825/sys/src/brazil/port/page.c
61,62c
print("%ludK bytes\n", pm);
print("%ludK swap\n", vm);
.
## diffname port/page.c 1999/0108
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/port/page.c /n/emeliedump/1999/0108/sys/src/brazil/port/page.c
392a
putimage(f->image);
f->image = 0;
f->daddr = 0;
.
276a
/* No dup for swap/cache pages but we still have to uncache */
if(p->image->notext){
uncachepage(p);
return;
}
.
273,274c
/* don't dup pages with no image */
if(p->ref == 0 || p->image == nil)
.
## diffname port/page.c 1999/0109
## diff -e /n/emeliedump/1999/0108/sys/src/brazil/port/page.c /n/emeliedump/1999/0109/sys/src/brazil/port/page.c
398,401c
lock(f);
if(f->image == i && f->daddr == daddr){
*l = f->hash;
putimage(f->image);
f->image = 0;
f->daddr = 0;
}
unlock(f);
.
277,282d
274c
if(p->ref == 0 || p->image == nil || p->image->notext)
.
217a
if(p->ref == 0)
panic("putpage");
.
## diffname port/page.c 2001/0110
## diff -e /n/emeliedump/1999/0109/sys/src/brazil/port/page.c /n/emeliedump/2001/0110/sys/src/9/port/page.c
232a
uncachepage(p);
.
## diffname port/page.c 2001/0218
## diff -e /n/emeliedump/2001/0110/sys/src/9/port/page.c /n/emeliedump/2001/0218/sys/src/9/port/page.c
233d
## diffname port/page.c 2001/0821
## diff -e /n/emeliedump/2001/0218/sys/src/9/port/page.c /n/emeliedump/2001/0821/sys/src/9/port/page.c
60,61c
print("%lud free pages, ", palloc.user);
print("%ludK bytes, ", pm);
.
## diffname port/page.c 2003/0405
## diff -e /n/emeliedump/2001/0821/sys/src/9/port/page.c /n/emeliedump/2003/0405/sys/src/9/port/page.c
69c
panic("pageunchain (palloc %p)", &palloc);
.
## diffname port/page.c 2003/0417
## diff -e /n/emeliedump/2003/0405/sys/src/9/port/page.c /n/emeliedump/2003/0417/sys/src/9/port/page.c
20a
print("pageinit: allocated %p to %p\n", palloc.head, (uchar*)palloc.head+np*sizeof(Page));
.
## diffname port/page.c 2003/0418
## diff -e /n/emeliedump/2003/0417/sys/src/9/port/page.c /n/emeliedump/2003/0418/sys/src/9/port/page.c
180d
## diffname port/page.c 2003/0506
## diff -e /n/emeliedump/2003/0418/sys/src/9/port/page.c /n/emeliedump/2003/0506/sys/src/9/port/page.c
21d
## diffname port/page.c 2003/0507
## diff -e /n/emeliedump/2003/0506/sys/src/9/port/page.c /n/emeliedump/2003/0507/sys/src/9/port/page.c
178a
.
|