X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Falloc%2Falloc.c;h=5c851d824469b334c2425d83ef2ce36d9a317cbb;hp=f7a05e2d9f273d64f98aa36d977b80121094f057;hb=16b7eb13fbcb1a04a71622e6310020baccc3c39c;hpb=650c775ff00cccd03fc84e7789a03c51d9839004 diff --git a/ccan/alloc/alloc.c b/ccan/alloc/alloc.c index f7a05e2d..5c851d82 100644 --- a/ccan/alloc/alloc.c +++ b/ccan/alloc/alloc.c @@ -822,6 +822,53 @@ void alloc_free(void *pool, unsigned long poolsize, void *free) } } +unsigned long alloc_size(void *pool, unsigned long poolsize, void *p) +{ + unsigned long len, pagenum; + struct metaheader *mh; + + assert(poolsize >= MIN_SIZE); + + mh = first_mheader(pool, poolsize); + assert((char *)p >= (char *)(mh + 1)); + assert((char *)pool + poolsize > (char *)p); + + pagenum = pool_offset(pool, p) / getpagesize(); + + if (get_page_state(pool, pagenum) == SPECIAL) { + unsigned long off = (unsigned long)p % getpagesize(); + uint8_t *metadata = get_page_metadata(pool, pagenum); + enum sub_metadata_type type = get_bit_pair(metadata, 0); + + assert(off < SUBPAGE_METAOFF); + + switch (type) { + case BITMAP: + assert(off % BITMAP_GRANULARITY == 0); + off /= BITMAP_GRANULARITY; + + /* Offset by one because first bit used for header. */ + off++; + len = BITMAP_GRANULARITY; + while (++off < SUBPAGE_METAOFF / BITMAP_GRANULARITY + && get_bit_pair(metadata, off) == TAKEN) + len += BITMAP_GRANULARITY; + break; + case UNIFORM: + len = decode_usize(metadata); + break; + default: + assert(0); + } + } else { + len = getpagesize(); + while (get_page_state(pool, ++pagenum) == TAKEN) + len += getpagesize(); + } + + return len; +} + static bool is_metadata_page(void *pool, unsigned long poolsize, unsigned long page) { @@ -1014,7 +1061,7 @@ void alloc_visualize(FILE *out, void *pool, unsigned long poolsize) if (meta[j / 8] & (1 << (j % 8))) total++; - printf(" %u: %u/%u (%u%% density)\n", + printf(" %u: %u/%zu (%zu%% density)\n", uc->size[j], total, SUBPAGE_METAOFF / uc->size[i], (total * 100) / (SUBPAGE_METAOFF / uc->size[i])); }