X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Falloc%2Falloc.c;h=c70b7fa7817a40da51f15cddedb7ddfb6db6aa18;hp=f7a05e2d9f273d64f98aa36d977b80121094f057;hb=1d7e593d2221690abd8010d4d572984ef2be4d21;hpb=4239dd56d06be573c5cbf8fdf1ab0995cbd4bc66 diff --git a/ccan/alloc/alloc.c b/ccan/alloc/alloc.c index f7a05e2d..c70b7fa7 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) {