diff options
author | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2002-01-09 05:13:33 +0000 |
---|---|---|
committer | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2002-01-09 05:13:33 +0000 |
commit | 7ba7448cc9133403c60b2c1afddce04fc23c2266 (patch) | |
tree | 7fc1cae02f63c9ec270536eb84522d457714c2e1 /misc | |
parent | 95b7451c13ef08f66964f13eb24dc227feb5c9db (diff) | |
download | libapr-util-7ba7448cc9133403c60b2c1afddce04fc23c2266.tar.gz |
Collapse a block upon free into it's previous and/or next block
when the blocks are adjacent.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr-util/trunk@58514 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'misc')
-rw-r--r-- | misc/apr_rmm.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/misc/apr_rmm.c b/misc/apr_rmm.c index cb1cf65f..18ef4c35 100644 --- a/misc/apr_rmm.c +++ b/misc/apr_rmm.c @@ -193,13 +193,32 @@ static void move_block(apr_rmm_t *rmm, apr_rmm_off_t this, int free) /* and open it up */ if (blk->prev) { struct rmm_block_t *prev = (rmm_block_t*)((char*)rmm->base + blk->prev); - blk->next = prev->next; - prev->next = this; + if (free && (blk->prev + prev->size == this)) { + /* Collapse us into our predecessor */ + prev->size += blk->size; + this = blk->prev; + blk = prev; + } + else { + blk->next = prev->next; + prev->next = this; + } } if (blk->next) { struct rmm_block_t *next = (rmm_block_t*)((char*)rmm->base + blk->next); - next->prev = this; + if (free && (this + blk->size == blk->next)) { + /* Collapse us into our successor */ + blk->size += next->size; + blk->next = next->next; + if (blk->next) { + next = (rmm_block_t*)((char*)rmm->base + blk->next); + next->prev = this; + } + } + else { + next->prev = this; + } } } |