lemoncake

rbtree based memory allocator
git clone git://git.2f30.org/lemoncake.git
Log | Files | Refs | README | LICENSE

commit 93a0b753f23a4823c90cc6bab76478b638c21ae0
parent 7915e540408259f295841cc47a2c545dc492e590
Author: sin <sin@2f30.org>
Date:   Mon Aug  5 11:22:53 +0100

When we realloc() split the unused space into a separate node

When we shrink the allocated region and there is enough space left
split it out and insert it into the free tree.  We need to make sure
the new address continues to be aligned properly so we do not split
unless there is enough space to align the free space.

Diffstat:
lemoncake.c | 30++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/lemoncake.c b/lemoncake.c @@ -186,7 +186,7 @@ realloc(void *oldp, size_t siz) { struct node n, *res; struct node *oldan, *newan; - struct node *fn; + struct node *fn, *newfn; if (lemon_init()) return NULL; @@ -201,9 +201,31 @@ realloc(void *oldp, size_t siz) n.buf = oldp; res = RB_FIND(alloc_tree, &at, &n); if (res) { - /* If we were asked to shrink the allocated space - * just re-use it */ - if (res->siz >= siz) { + if (res->siz == siz) { + unlock(&rblock); + st.nr_realloc++; + return res->buf; + } + if (res->siz > siz) { + size_t diff = res->siz - siz; + if (diff < ALIGN + siz) { + unlock(&rblock); + st.nr_realloc++; + st.nr_shrink_realloc++; + return res->buf; + } + newfn = alloc_object(sizeof(*newfn)); + if (!newfn) { + unlock(&rblock); + return NULL; + } + res->siz = siz; + newfn->buf = res->buf + siz; + newfn->siz = diff; + newfn->siz -= (uintptr_t)align_pointer(ALIGN, newfn->buf); + newfn->siz += (uintptr_t)newfn->buf; + newfn->buf = align_pointer(ALIGN, newfn->buf); + RB_INSERT(free_tree, &ft, newfn); unlock(&rblock); st.nr_realloc++; st.nr_shrink_realloc++;