summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-04-12 18:08:06 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-04-12 18:08:06 +0200
commita43321946e0f661f51290988c7e7567262d403bd (patch)
tree437c6f43a515a2611cc7ea02497ba849ddaed976 /sys/src
parent98a7eae9c0cdb31a48c79b34c5f263916a8c1390 (diff)
segment: speed up fixedseg() doing single pass over freelist
walking the freelist for every page is too slow. as we are freeing a range, we can do a single pass unlinking all pages in our range and at the end, check if all pages where freed, if not put the pages that we did free back and retry, otherwise we'r done.
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/9/port/devsegment.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/sys/src/9/port/devsegment.c b/sys/src/9/port/devsegment.c
index 41967e829..7d1dc4b7e 100644
--- a/sys/src/9/port/devsegment.c
+++ b/sys/src/9/port/devsegment.c
@@ -580,8 +580,8 @@ fixedseg(uintptr va, ulong len)
{
KMap *k;
Segment *s;
- Page **f, *p;
- ulong n, i, j;
+ Page **f, *p, *l, *h;
+ ulong n, i;
int color;
s = newseg(SG_FIXED, va, len);
@@ -591,32 +591,44 @@ fixedseg(uintptr va, ulong len)
}
lock(&palloc);
i = 0;
- p = palloc.pages;
+ l = palloc.pages;
color = getpgcolor(va);
- for(n = palloc.user; n >= len; n--, p++){
- if(p->ref != 0 || i != 0 && (p[-1].pa+BY2PG) != p->pa || i == 0 && p->color != color){
+ for(n = palloc.user; n >= len; n--, l++){
+ if(l->ref != 0 || i != 0 && (l[-1].pa+BY2PG) != l->pa || i == 0 && l->color != color){
Retry:
i = 0;
continue;
}
if(++i < len)
continue;
- for(j = 0; j < i; j++, p--){
- for(f = &palloc.head; *f != nil; f = &((*f)->next)){
- if(*f == p){
- *f = p->next;
- goto Freed;
- }
+
+ i = 0;
+ h = nil;
+ f = &palloc.head;
+ while((p = *f) != nil){
+ if(p > &l[-len] && p <= l){
+ *f = p->next;
+ p->next = h;
+ h = p;
+ if(++i < len)
+ continue;
+ break;
+ }
+ f = &p->next;
+ }
+ palloc.freecount -= i;
+
+ if(i != len){
+ while((p = h) != nil){
+ h = h->next;
+ pagechainhead(p);
}
- while(j-- > 0)
- pagechainhead(++p);
goto Retry;
- Freed:
- palloc.freecount--;
}
unlock(&palloc);
- while(i-- > 0){
+ p = &l[-len];
+ do {
p++;
p->ref = 1;
p->va = va;
@@ -629,7 +641,7 @@ fixedseg(uintptr va, ulong len)
segpage(s, p);
va += BY2PG;
- }
+ } while(p != l);
poperror();
return s;
}