]> git.proxmox.com Git - wasi-libc.git/blob - libc-top-half/musl/src/malloc/oldmalloc/aligned_alloc.c
Update to musl 1.2.1. (#222)
[wasi-libc.git] / libc-top-half / musl / src / malloc / oldmalloc / aligned_alloc.c
1 #include <stdlib.h>
2 #include <stdint.h>
3 #include <errno.h>
4 #include "malloc_impl.h"
5
6 void *aligned_alloc(size_t align, size_t len)
7 {
8 unsigned char *mem, *new;
9
10 if ((align & -align) != align) {
11 errno = EINVAL;
12 return 0;
13 }
14
15 if (len > SIZE_MAX - align ||
16 (__malloc_replaced && !__aligned_alloc_replaced)) {
17 errno = ENOMEM;
18 return 0;
19 }
20
21 if (align <= SIZE_ALIGN)
22 return malloc(len);
23
24 if (!(mem = malloc(len + align-1)))
25 return 0;
26
27 new = (void *)((uintptr_t)mem + align-1 & -align);
28 if (new == mem) return mem;
29
30 struct chunk *c = MEM_TO_CHUNK(mem);
31 struct chunk *n = MEM_TO_CHUNK(new);
32
33 if (IS_MMAPPED(c)) {
34 /* Apply difference between aligned and original
35 * address to the "extra" field of mmapped chunk. */
36 n->psize = c->psize + (new-mem);
37 n->csize = c->csize - (new-mem);
38 return new;
39 }
40
41 struct chunk *t = NEXT_CHUNK(c);
42
43 /* Split the allocated chunk into two chunks. The aligned part
44 * that will be used has the size in its footer reduced by the
45 * difference between the aligned and original addresses, and
46 * the resulting size copied to its header. A new header and
47 * footer are written for the split-off part to be freed. */
48 n->psize = c->csize = C_INUSE | (new-mem);
49 n->csize = t->psize -= new-mem;
50
51 __bin_chunk(c);
52 return new;
53 }