X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=alloc%2Falloc.c;fp=alloc%2Falloc.c;h=3ec6952c82c8b6d20187ea722d56a907d518548f;hp=f3638340949fedc9187c68e8567af73489cbf318;hb=294f8d35427a7f5a0afe872fee7d4a47494d6add;hpb=e5ca6bcffbac9983e03a584729219ba4b6fe860f;ds=sidebyside diff --git a/alloc/alloc.c b/alloc/alloc.c index f3638340..3ec6952c 100644 --- a/alloc/alloc.c +++ b/alloc/alloc.c @@ -48,7 +48,8 @@ static unsigned long metadata_length(void *pool, unsigned long poolsize) void *alloc_get(void *pool, unsigned long poolsize, unsigned long size, unsigned long align) { - unsigned long i, free, want, metalen; + long i; + unsigned long free, want, metalen; if (poolsize < MIN_SIZE) return NULL; @@ -61,20 +62,22 @@ void *alloc_get(void *pool, unsigned long poolsize, metalen = metadata_length(pool, poolsize); free = 0; - for (i = 0; i < (poolsize - metalen) / getpagesize(); i++) { + /* We allocate from far end, to increase ability to expand metadata. */ + for (i = (poolsize - metalen) / getpagesize() - 1; i >= 0; i--) { switch (get_page_state(pool, i)) { case FREE: if (++free >= want) { - unsigned int j; + unsigned long j; char *ret = (char *)pool + metalen - + (i - want + 1) * getpagesize(); + + i * getpagesize(); + /* They might ask for multi-page alignment. */ if ((unsigned long)ret % align) continue; - for (j = i; j > i - want + 1; j--) + for (j = i+1; j < i + want; j++) set_page_state(pool, j, TAKEN); - set_page_state(pool, i - want + 1, TAKEN_START); + set_page_state(pool, i, TAKEN_START); return ret; } break;