• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 #include <stdint.h>
3 #include <errno.h>
4 #include "libc.h"
5 #include "pthread_impl.h"
6 #include "oldmalloc/malloc_impl.h"
7 
lock(volatile int * lk)8 static inline void lock(volatile int *lk)
9 {
10 	if (libc.threads_minus_1)
11 		while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
12 }
13 
unlock(volatile int * lk)14 static inline void unlock(volatile int *lk)
15 {
16 	if (lk[0]) {
17 		a_store(lk, 0);
18 		if (lk[1]) __wake(lk, 1, 1);
19 	}
20 }
21 
__memalign(size_t align,size_t len)22 void *__memalign(size_t align, size_t len)
23 {
24 	unsigned char *mem, *new;
25 
26 	if ((align & -align) != align) {
27 		errno = EINVAL;
28 		return 0;
29 	}
30 
31 	if (len > SIZE_MAX - align || __malloc_replaced) {
32 		errno = ENOMEM;
33 		return 0;
34 	}
35 
36 	if (align <= SIZE_ALIGN)
37 		return malloc(len);
38 
39 	if (!(mem = malloc(len + align-1)))
40 		return 0;
41 
42 	new = (void *)((uintptr_t)mem + align-1 & -align);
43 	if (new == mem) return mem;
44 
45 	struct chunk *c = MEM_TO_CHUNK(mem);
46 	struct chunk *n = MEM_TO_CHUNK(new);
47 
48 	if (g_enable_check) {
49 		int status = delete_node(mem);
50 		if (status != 0) {
51 			get_free_trace(mem);
52 			a_crash();
53 		}
54 	}
55 
56 	if (IS_MMAPPED(c)) {
57 		/* Apply difference between aligned and original
58 		 * address to the "extra" field of mmapped chunk. */
59 		n->psize = c->psize + (new-mem);
60 		n->csize = c->csize - (new-mem);
61 		if (g_enable_check) {
62 			insert_node(CHUNK_TO_MEM(n), CHUNK_SIZE(n));
63 		}
64 		return new;
65 	}
66 
67 	struct chunk *t = NEXT_CHUNK(c);
68 
69 	/* Split the allocated chunk into two chunks. The aligned part
70 	 * that will be used has the size in its footer reduced by the
71 	 * difference between the aligned and original addresses, and
72 	 * the resulting size copied to its header. A new header and
73 	 * footer are written for the split-off part to be freed. */
74 	lock(g_mem_lock);
75 	n->psize = c->csize = C_INUSE | (new-mem);
76 	n->csize = t->psize -= new-mem;
77 	calculate_checksum(c, n);
78 	calculate_checksum(NULL, t);
79 	unlock(g_mem_lock);
80 	if (g_enable_check) {
81 		insert_node(CHUNK_TO_MEM(n), CHUNK_SIZE(n));
82 	}
83 
84 	__bin_chunk(c);
85 	return new;
86 }
87 
88 weak_alias(__memalign, memalign);
89