2 This is a version (aka dlmalloc) of malloc/free/realloc written by
3 Doug Lea and released to the public domain. Use, modify, and
4 redistribute this code without permission or acknowledgement in any
5 way you wish. Send questions, comments, complaints, performance
6 data, etc to dl@cs.oswego.edu
8 VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee)
10 Note: There may be an updated version of this malloc obtainable at
11 ftp://gee.cs.oswego.edu/pub/misc/malloc.c
12 Check before installing!
14 Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
25 /* ------------------------------ memalign ------------------------------ */
26 void* memalign(size_t alignment
, size_t bytes
)
28 size_t nb
; /* padded request size */
29 char* m
; /* memory returned by malloc call */
30 mchunkptr p
; /* corresponding chunk */
31 char* _brk
; /* alignment point within p */
32 mchunkptr newp
; /* chunk to return */
33 size_t newsize
; /* its size */
34 size_t leadsize
; /* leading space before alignment point */
35 mchunkptr remainder
; /* spare room at end to split off */
36 unsigned long remainder_size
; /* its size */
40 /* If need less alignment than we give anyway, just relay to malloc */
42 if (alignment
<= MALLOC_ALIGNMENT
) return malloc(bytes
);
44 /* Otherwise, ensure that it is at least a minimum chunk size */
46 if (alignment
< MINSIZE
) alignment
= MINSIZE
;
48 /* Make sure alignment is power of 2 (in case MINSIZE is not). */
49 if ((alignment
& (alignment
- 1)) != 0) {
50 size_t a
= MALLOC_ALIGNMENT
* 2;
51 while ((unsigned long)a
< (unsigned long)alignment
) a
<<= 1;
55 checked_request2size(bytes
, nb
);
58 /* Strategy: find a spot within that chunk that meets the alignment
59 * request, and then possibly free the leading and trailing space. */
62 /* Call malloc with worst case padding to hit alignment. */
64 m
= (char*)(malloc(nb
+ alignment
+ MINSIZE
));
67 retval
= 0; /* propagate failure */
73 if ((((unsigned long)(m
)) % alignment
) != 0) { /* misaligned */
76 Find an aligned spot inside chunk. Since we need to give back
77 leading space in a chunk of at least MINSIZE, if the first
78 calculation places us at a spot with less than MINSIZE leader,
79 we can move to the next aligned spot -- we've allocated enough
80 total room so that this is always possible.
83 _brk
= (char*)mem2chunk((unsigned long)(((unsigned long)(m
+ alignment
- 1)) &
84 -((signed long) alignment
)));
85 if ((unsigned long)(_brk
- (char*)(p
)) < MINSIZE
)
88 newp
= (mchunkptr
)_brk
;
89 leadsize
= _brk
- (char*)(p
);
90 newsize
= chunksize(p
) - leadsize
;
92 /* For mmapped chunks, just adjust offset */
93 if (chunk_is_mmapped(p
)) {
94 newp
->prev_size
= p
->prev_size
+ leadsize
;
95 set_head(newp
, newsize
|IS_MMAPPED
);
96 retval
= chunk2mem(newp
);
100 /* Otherwise, give back leader, use the rest */
101 set_head(newp
, newsize
| PREV_INUSE
);
102 set_inuse_bit_at_offset(newp
, newsize
);
103 set_head_size(p
, leadsize
);
107 assert (newsize
>= nb
&&
108 (((unsigned long)(chunk2mem(p
))) % alignment
) == 0);
111 /* Also give back spare room at the end */
112 if (!chunk_is_mmapped(p
)) {
114 if ((unsigned long)(size
) > (unsigned long)(nb
+ MINSIZE
)) {
115 remainder_size
= size
- nb
;
116 remainder
= chunk_at_offset(p
, nb
);
117 set_head(remainder
, remainder_size
| PREV_INUSE
);
118 set_head_size(p
, nb
);
119 free(chunk2mem(remainder
));
123 check_inuse_chunk(p
);
124 retval
= chunk2mem(p
);
130 weak_alias(memalign
, aligned_alloc
)
131 libc_hidden_def(memalign
)
132 /* glibc compatibilty */
133 weak_alias(memalign
, __libc_memalign
)