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 */
39 /* If need less alignment than we give anyway, just relay to malloc */
41 if (alignment <= MALLOC_ALIGNMENT) return malloc(bytes);
43 /* Otherwise, ensure that it is at least a minimum chunk size */
45 if (alignment < MINSIZE) alignment = MINSIZE;
47 /* Make sure alignment is power of 2 (in case MINSIZE is not). */
48 if ((alignment & (alignment - 1)) != 0) {
49 size_t a = MALLOC_ALIGNMENT * 2;
50 while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
55 checked_request2size(bytes, nb);
57 /* Strategy: find a spot within that chunk that meets the alignment
58 * request, and then possibly free the leading and trailing space. */
61 /* Call malloc with worst case padding to hit alignment. */
63 m = (char*)(malloc(nb + alignment + MINSIZE));
67 return 0; /* propagate failure */
72 if ((((unsigned long)(m)) % alignment) != 0) { /* misaligned */
75 Find an aligned spot inside chunk. Since we need to give back
76 leading space in a chunk of at least MINSIZE, if the first
77 calculation places us at a spot with less than MINSIZE leader,
78 we can move to the next aligned spot -- we've allocated enough
79 total room so that this is always possible.
82 _brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) &
83 -((signed long) alignment)));
84 if ((unsigned long)(_brk - (char*)(p)) < MINSIZE)
87 newp = (mchunkptr)_brk;
88 leadsize = _brk - (char*)(p);
89 newsize = chunksize(p) - leadsize;
91 /* For mmapped chunks, just adjust offset */
92 if (chunk_is_mmapped(p)) {
93 newp->prev_size = p->prev_size + leadsize;
94 set_head(newp, newsize|IS_MMAPPED);
96 return chunk2mem(newp);
99 /* Otherwise, give back leader, use the rest */
100 set_head(newp, newsize | PREV_INUSE);
101 set_inuse_bit_at_offset(newp, newsize);
102 set_head_size(p, leadsize);
106 assert (newsize >= nb &&
107 (((unsigned long)(chunk2mem(p))) % alignment) == 0);
110 /* Also give back spare room at the end */
111 if (!chunk_is_mmapped(p)) {
113 if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
114 remainder_size = size - nb;
115 remainder = chunk_at_offset(p, nb);
116 set_head(remainder, remainder_size | PREV_INUSE);
117 set_head_size(p, nb);
118 free(chunk2mem(remainder));
122 check_inuse_chunk(p);