diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-02-07 03:01:59 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-02-07 03:01:59 +0100 |
commit | e8760ba6360d3ccd75d8ccf8319ff40954b6659c (patch) | |
tree | ecae73439e642106c7a6f3be09e6a5f1eb349953 | |
parent | b8cf3cb879a19c001796329ebe266104d13e63be (diff) |
kernel: make pagereclaim() a bit less stupid
put recently used pages at the head of ther image hash
chains, and reclaim pages from the tail first.
-rw-r--r-- | sys/src/9/port/page.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/sys/src/9/port/page.c b/sys/src/9/port/page.c index c33b1ec6b..dcd701267 100644 --- a/sys/src/9/port/page.c +++ b/sys/src/9/port/page.c @@ -86,7 +86,7 @@ freepages(Page *head, Page *tail, int n) int pagereclaim(Image *i, int min) { - Page **h, **l, *p; + Page **h, **l, **x, *p; Page *fh, *ft; int n; @@ -100,17 +100,18 @@ pagereclaim(Image *i, int min) n = 0; fh = ft = nil; for(h = i->pghash; h < &i->pghash[PGHSIZE]; h++){ - if((p = *h) == nil) - continue; - for(l = h; p != nil; p = p->next){ + l = h; + x = nil; + for(p = *l; p != nil; p = p->next){ if(p->ref == 0) - break; + x = l; l = &p->next; } - if(p == nil) + if(x == nil) continue; - *l = p->next; + p = *x; + *x = p->next; p->next = nil; p->image = nil; p->daddr = ~0; @@ -315,15 +316,20 @@ uncachepage(Page *p) Page* lookpage(Image *i, uintptr daddr) { - Page *p; + Page *p, **h, **l; lock(i); - for(p = PGHASH(i, daddr); p != nil; p = p->next) { - if(p->daddr == daddr) { + l = h = &PGHASH(i, daddr); + for(p = *l; p != nil; p = p->next){ + if(p->daddr == daddr){ + *l = p->next; + p->next = *h; + *h = p; incref(p); unlock(i); return p; } + l = &p->next; } unlock(i); |