• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 
3 #ifndef USE_JEMALLOC
4 #include <stdint.h>
5 #include <errno.h>
6 #include "malloc_impl.h"
7 #include "malloc_config.h"
8 #else
9 extern void* je_memalign(size_t align, size_t len);
10 #endif
11 
__memalign(size_t align,size_t len)12 void *__memalign(size_t align, size_t len)
13 {
14 #ifdef USE_JEMALLOC
15 	return je_memalign(align, len);
16 #else
17 	unsigned char *mem, *new;
18 
19 	if ((align & -align) != align) {
20 		errno = EINVAL;
21 		return 0;
22 	}
23 
24 	if (len > SIZE_MAX - align || __malloc_replaced) {
25 		errno = ENOMEM;
26 		return 0;
27 	}
28 
29 	if (align <= SIZE_ALIGN)
30 		return malloc(len);
31 
32 	if (!(mem = malloc(len + align-1)))
33 		return 0;
34 
35 	new = (void *)((uintptr_t)mem + align-1 & -align);
36 
37 	if (new == mem) return mem;
38 	struct chunk *c = MEM_TO_CHUNK(mem);
39 	struct chunk *n = MEM_TO_CHUNK(new);
40 
41 #ifdef MUSL_ITERATE_AND_STATS_API
42 	__pop_chunk(c);
43 	__push_chunk(n);
44 #endif
45 
46 	if (IS_MMAPPED(c)) {
47 		/* Apply difference between aligned and original
48 		 * address to the "extra" field of mmapped chunk.
49 		 */
50 		n->psize = c->psize + (new-mem);
51 		n->csize = c->csize - (new-mem);
52 #ifdef MALLOC_RED_ZONE
53 		n->usize = len;
54 		n->state = M_STATE_MMAP | M_STATE_USED;
55 		chunk_checksum_set(n);
56 #endif
57 		return new;
58 	}
59 
60 	struct chunk *t = NEXT_CHUNK(c);
61 
62 	/* Split the allocated chunk into two chunks. The aligned part
63 	 * that will be used has the size in its footer reduced by the
64 	 * difference between the aligned and original addresses, and
65 	 * the resulting size copied to its header. A new header and
66 	 * footer are written for the split-off part to be freed. */
67 	n->psize = c->csize = C_INUSE | (new-mem);
68 	n->csize = t->psize -= new-mem;
69 
70 #ifdef MALLOC_RED_ZONE
71 	/* Update extra overhead */
72 	c->usize = OVERHEAD;
73 	c->state = M_STATE_BRK;
74 	chunk_checksum_set(c);
75 	n->usize = len;
76 	n->state = M_STATE_BRK | M_STATE_USED;
77 	chunk_checksum_set(n);
78 #endif
79 
80 	__bin_chunk(c);
81 	return new;
82 #endif
83 }
84 
85 weak_alias(__memalign, memalign);
86