From a43321946e0f661f51290988c7e7567262d403bd Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 12 Apr 2015 18:08:06 +0200 Subject: 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. --- sys/src/9/port/devsegment.c | 46 ++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'sys/src/9/port/devsegment.c') 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; } -- cgit v1.2.3