diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-04-12 18:08:06 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-04-12 18:08:06 +0200 |
commit | a43321946e0f661f51290988c7e7567262d403bd (patch) | |
tree | 437c6f43a515a2611cc7ea02497ba849ddaed976 /sys/src | |
parent | 98a7eae9c0cdb31a48c79b34c5f263916a8c1390 (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.c | 46 |
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; } |