diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-05-21 09:04:16 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-21 09:04:16 +0200 |
| commit | 4b69bd61e41f1a49bb0b00ac00a7e499ab7974a7 (patch) | |
| tree | f2a7d43ea77e01d6010c2256b79801769680acec /lib/libc/wasi/libc-top-half/musl/src/malloc/mallocng/aligned_alloc.c | |
| parent | 0267abfe9b14b07dcf98f06218416f4b8aaeda48 (diff) | |
| parent | b63c92f0b9ce7b3876c5f51e12a6ae249dfa4bac (diff) | |
| download | zig-4b69bd61e41f1a49bb0b00ac00a7e499ab7974a7.tar.gz zig-4b69bd61e41f1a49bb0b00ac00a7e499ab7974a7.zip | |
Merge pull request #8837 from ziglang/cc-wasm32-wasi
cc,wasi: ship WASI libc and autobuild it when needed
Diffstat (limited to 'lib/libc/wasi/libc-top-half/musl/src/malloc/mallocng/aligned_alloc.c')
| -rw-r--r-- | lib/libc/wasi/libc-top-half/musl/src/malloc/mallocng/aligned_alloc.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/libc/wasi/libc-top-half/musl/src/malloc/mallocng/aligned_alloc.c b/lib/libc/wasi/libc-top-half/musl/src/malloc/mallocng/aligned_alloc.c new file mode 100644 index 0000000000..3411689600 --- /dev/null +++ b/lib/libc/wasi/libc-top-half/musl/src/malloc/mallocng/aligned_alloc.c @@ -0,0 +1,57 @@ +#include <stdlib.h> +#include <errno.h> +#include "meta.h" + +void *aligned_alloc(size_t align, size_t len) +{ + if ((align & -align) != align) { + errno = EINVAL; + return 0; + } + + if (len > SIZE_MAX - align || align >= (1ULL<<31)*UNIT) { + errno = ENOMEM; + return 0; + } + + if (DISABLE_ALIGNED_ALLOC) { + errno = ENOMEM; + return 0; + } + + if (align <= UNIT) align = UNIT; + + unsigned char *p = malloc(len + align - UNIT); + struct meta *g = get_meta(p); + int idx = get_slot_index(p); + size_t stride = get_stride(g); + unsigned char *start = g->mem->storage + stride*idx; + unsigned char *end = g->mem->storage + stride*(idx+1) - IB; + size_t adj = -(uintptr_t)p & (align-1); + + if (!adj) { + set_size(p, end, len); + return p; + } + p += adj; + uint32_t offset = (size_t)(p-g->mem->storage)/UNIT; + if (offset <= 0xffff) { + *(uint16_t *)(p-2) = offset; + p[-4] = 0; + } else { + // use a 32-bit offset if 16-bit doesn't fit. for this, + // 16-bit field must be zero, [-4] byte nonzero. + *(uint16_t *)(p-2) = 0; + *(uint32_t *)(p-8) = offset; + p[-4] = 1; + } + p[-3] = idx; + set_size(p, end, len); + // store offset to aligned enframing. this facilitates cycling + // offset and also iteration of heap for debugging/measurement. + // for extreme overalignment it won't fit but these are classless + // allocations anyway. + *(uint16_t *)(start - 2) = (size_t)(p-start)/UNIT; + start[-3] = 7<<5; + return p; +} |
