aligned_alloc.c\oldmalloc\malloc\src - musl - musl - an implementation of the standard library for Linux-based systems

index : musl
musl - an implementation of the standard library for Linux-based systems
summary refs log tree commit diff
path: root/src/malloc/oldmalloc/aligned_alloc.c
blob: 4adca3b4f6b7704b3cb034c4a087eaf4e08c2749 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include "malloc_impl.h"
void *aligned_alloc(size_t align, size_t len)
{
	unsigned char *mem, *new;
	if ((align & -align) != align) {
		errno = EINVAL;
		return 0;
	}
	if (len > SIZE_MAX - align ||
	 (__malloc_replaced && !__aligned_alloc_replaced)) {
		errno = ENOMEM;
		return 0;
	}
	if (align <= SIZE_ALIGN)
		return malloc(len);
	if (!(mem = malloc(len + align-1)))
		return 0;
	new = (void *)((uintptr_t)mem + align-1 & -align);
	if (new == mem) return mem;
	struct chunk *c = MEM_TO_CHUNK(mem);
	struct chunk *n = MEM_TO_CHUNK(new);
	if (IS_MMAPPED(c)) {
		/* Apply difference between aligned and original
		 * address to the "extra" field of mmapped chunk. */
		n->psize = c->psize + (new-mem);
		n->csize = c->csize - (new-mem);
		return new;
	}
	struct chunk *t = NEXT_CHUNK(c);
	/* Split the allocated chunk into two chunks. The aligned part
	 * that will be used has the size in its footer reduced by the
	 * difference between the aligned and original addresses, and
	 * the resulting size copied to its header. A new header and
	 * footer are written for the split-off part to be freed. */
	n->psize = c->csize = C_INUSE | (new-mem);
	n->csize = t->psize -= new-mem;
	__bin_chunk(c);
	return new;
}
generated by cgit v1.2.1 (git 2.18.0) at 2025年09月10日 04:13:50 +0000

AltStyle によって変換されたページ (->オリジナル) /