From 641ff7e9cb265146b27ce6f71faa4d2ae39d0309 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 17 Aug 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-08-17 --- port/page.c | 84 ++++++++++++++++++++++++++++++++++++++------------ port/portdat.h | 4 ++- port/portfns.h | 1 - 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/port/page.c b/port/page.c index aa28157b754d6272fb317a2f828e22dddfea6859..46cbc4d4f84b55d9e73467900067d152026c8609 100644 --- a/port/page.c +++ b/port/page.c @@ -13,19 +13,24 @@ struct Palloc palloc; void pageinit(void) { + int color; Page *p; - ulong np, vmem, pmem; + ulong np, vm, pm; np = palloc.np0+palloc.np1; palloc.head = xalloc(np*sizeof(Page)); if(palloc.head == 0) panic("pageinit"); + color = 0; p = palloc.head; while(palloc.np0 > 0) { p->prev = p-1; p->next = p+1; p->pa = palloc.p0; + p->color = color; + palloc.freecol[color]++; + color = (color+1)%NCOLOR; palloc.p0 += BY2PG; palloc.np0--; p++; @@ -34,6 +39,9 @@ pageinit(void) p->prev = p-1; p->next = p+1; p->pa = palloc.p1; + p->color = color; + palloc.freecol[color]++; + color = (color+1)%NCOLOR; palloc.p1 += BY2PG; palloc.np1--; p++; @@ -43,15 +51,14 @@ pageinit(void) palloc.tail->next = 0; palloc.user = p - palloc.head; - palloc.freecount = palloc.user; - pmem = palloc.user*BY2PG/1024; - vmem = pmem + (conf.nswap*BY2PG)/1024; + pm = palloc.user*BY2PG/1024; + vm = pm + (conf.nswap*BY2PG)/1024; /* Pageing numbers */ - swapalloc.highwater = (palloc.freecount*5)/100; + swapalloc.highwater = (palloc.user*5)/100; swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4); - print("%lud free pages\n%dK bytes\n%dK swap\n", palloc.user, pmem, vmem); + print("%lud free pages\n%dK bytes\n%dK swap\n", palloc.user, pm, vm); } Page* @@ -59,14 +66,19 @@ newpage(int clear, Segment **s, ulong va) { Page *p; KMap *k; - int i, hw, dontalloc, fc; + int i, hw, dontalloc, color; retry: lock(&palloc); + color = getcolor(va); hw = swapalloc.highwater; - fc = palloc.freecount; - while((fc < hw && up->kp == 0) || fc == 0) { + for(;;) { + if(palloc.freecol[color] > hw) + break; + if(up->kp && palloc.freecol[color] > 0) + break; + palloc.wanted++; unlock(&palloc); dontalloc = 0; @@ -75,7 +87,7 @@ retry: *s = 0; dontalloc = 1; } - qlock(&palloc.pwait); /* Hold memory requesters here */ + qlock(&palloc.pwait); /* Hold memory requesters here */ while(waserror()) /* Ignore interrupts */ ; @@ -100,13 +112,26 @@ retry: palloc.wanted--; } - p = palloc.head; - if(palloc.head = p->next) /* = Assign */ - palloc.head->prev = 0; + 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; else - palloc.tail = 0; + palloc.head = p->next; + + if(p->next) + p->next->prev = p->prev; + else + palloc.tail = p->prev; + palloc.freecount--; + palloc.freecol[color]--; unlock(&palloc); lock(p); @@ -158,7 +183,6 @@ putpage(Page *p) return; } - vcacheinval(p, p->va); lock(&palloc); if(p->image && p->image != &swapimage) { if(palloc.tail) { @@ -186,6 +210,10 @@ putpage(Page *p) } palloc.freecount++; /* Release people waiting for memory */ + palloc.freecol[p->color]++; + if(palloc.r.p != 0) + wakeup(&palloc.r); + unlock(&palloc); unlock(p); } @@ -194,6 +222,7 @@ void duppage(Page *p) /* Always call with p locked */ { Page *np; + int color; /* No dup for swap pages */ if(p->image == &swapimage) { @@ -209,11 +238,27 @@ duppage(Page *p) /* Always call with p locked */ return; } - np = palloc.head; /* Allocate a new page from freelist */ - if(palloc.head = np->next) /* = Assign */ - palloc.head->prev = 0; + 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; + else + palloc.head = np->next; + + if(np->next) + np->next->prev = np->prev; else - palloc.tail = 0; + palloc.tail = np->prev; if(palloc.tail) { /* Link back onto tail to give us lru */ np->prev = palloc.tail; @@ -349,6 +394,7 @@ lookpage(Image *i, ulong daddr) else palloc.tail = f->prev; palloc.freecount--; + palloc.freecol[f->color]--; } unlock(&palloc); diff --git a/port/portdat.h b/port/portdat.h index 42ea48a8fd5c31c5b9110772f33fd6d54ae1330b..5871449de05d4a1dd9fd859df8ddc957a0f1675e 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -306,6 +306,7 @@ struct Page ulong daddr; /* Disc address on swap */ ushort ref; /* Reference count */ char modref; /* Simulated modify/reference bits */ + char color; /* Cache coloring */ char cachectl[MAXMACH]; /* Cache flushing control for putmmu */ Image *image; /* Associated text or swap image */ Page *next; /* Lru free list */ @@ -454,7 +455,8 @@ struct Palloc ulong np0, np1; /* number of pages in bank 0/1 */ Page *head; /* most recently used */ Page *tail; /* least recently used */ - ulong freecount; /* how many pages on free list now */ + ulong freecount; + ulong freecol[NCOLOR]; /* how many pages on free list now */ ulong user; /* how many user pages */ Page *hash[PGHSIZE]; Lock hashlock; diff --git a/port/portfns.h b/port/portfns.h index ee7e4de57502fcf442807c10ed2dacc4c18f82ca..0f07d8d301e286eb815adf3e0a06c1dc6dcc41d7 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -81,7 +81,6 @@ void freechan(Chan*); void freepte(Segment*, Pte*); void freesegs(int); void freesession(Session*); -void getcolor(ulong, ulong*, ulong*, ulong*); int getfields(char*, char**, int, char); void gotolabel(Label*); int haswaitq(void*);