diff options
| author | peter <peter@pmikkelsen.com> | 2026-10-07 17:59:50 +0000 |
|---|---|---|
| committer | peter <peter@pmikkelsen.com> | 2026-10-07 17:59:50 +0000 |
| commit | 87a324b2e0c41ba294c43016cc38953dd1023688 (patch) | |
| tree | 027f657b5cac3127ba10e8db648a367d7b93ca6b /src | |
| parent | e123d8528e6ffb31d18c23af89b5dd6d74b22990 (diff) | |
For testing, move memory around sometimes [c9e361fa97].
FossilOrigin-Name: b78e635bff051ffacfbaab830b770c30aca3e775a2613d09b503ec784c2d49ab
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/memory.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/lib/memory.c b/src/lib/memory.c index 006c409..b61f844 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -438,14 +438,60 @@ compact(struct aplwc *aplwc) } } +static void +shuffle(struct aplwc *aplwc) +{ + struct chunk *c, *prev, *prev_prev; + size_t move; + + compact(aplwc); + + prev_prev = prev = NULL; + for(c = (struct chunk *)aplwc->data; c; prev_prev = prev, prev = c, c = next(c)) + assert((next(c) == NULL) || (c->tag != CHUNK_TAG_FREE)); + + if(prev == NULL) /* No chunks */ + return; + + if(prev->tag != CHUNK_TAG_FREE){ /* No free space at the end */ + if(grow(aplwc, HEADER_SIZE*8)) + shuffle(aplwc); + return; + } + + if(prev_prev == NULL) /* Only free space */ + return; + + assert(prev); + assert(prev->tag == CHUNK_TAG_FREE); + move = prev->size; + prev_prev->last = 1; + memmove(aplwc->data+move, aplwc->data, aplwc->size-move); + + aplwc->data += move; + aplwc->size -= move; + fixrefs(aplwc, aplwc->data-move); + + aplwc->data -= move; + aplwc->size += move; + + c = (struct chunk *)aplwc->data; + c->stack = NULL; + c->tag = CHUNK_TAG_FREE; + c->size = move; + c->last = 0; +} + static void * alloc(struct aplwc *aplwc, size_t size, enum chunk_tag tag) { struct chunk *free, *new; size_t pad; - int attempt; + + FAILCASE((void)0, shuffle(aplwc)); + pad = size % ALIGNMENT; if(pad) size += ALIGNMENT - pad; |