123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- #include <features.h>
- #include <stddef.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include "malloc.h"
- void* memalign(size_t alignment, size_t bytes)
- {
- size_t nb;
- char* m;
- mchunkptr p;
- char* _brk;
- mchunkptr newp;
- size_t newsize;
- size_t leadsize;
- mchunkptr remainder;
- unsigned long remainder_size;
- size_t size;
- void *retval;
-
- if (alignment <= MALLOC_ALIGNMENT) return malloc(bytes);
-
- if (alignment < MINSIZE) alignment = MINSIZE;
-
- if ((alignment & (alignment - 1)) != 0) {
- size_t a = MALLOC_ALIGNMENT * 2;
- while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
- alignment = a;
- }
- checked_request2size(bytes, nb);
- __MALLOC_LOCK;
-
-
- m = (char*)(malloc(nb + alignment + MINSIZE));
- if (m == 0) {
- retval = 0;
- goto DONE;
- }
- p = mem2chunk(m);
- if ((((unsigned long)(m)) % alignment) != 0) {
-
- _brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) &
- -((signed long) alignment)));
- if ((unsigned long)(_brk - (char*)(p)) < MINSIZE)
- _brk += alignment;
- newp = (mchunkptr)_brk;
- leadsize = _brk - (char*)(p);
- newsize = chunksize(p) - leadsize;
-
- if (chunk_is_mmapped(p)) {
- newp->prev_size = p->prev_size + leadsize;
- set_head(newp, newsize|IS_MMAPPED);
- retval = chunk2mem(newp);
- goto DONE;
- }
-
- set_head(newp, newsize | PREV_INUSE);
- set_inuse_bit_at_offset(newp, newsize);
- set_head_size(p, leadsize);
- free(chunk2mem(p));
- p = newp;
- assert (newsize >= nb &&
- (((unsigned long)(chunk2mem(p))) % alignment) == 0);
- }
-
- if (!chunk_is_mmapped(p)) {
- size = chunksize(p);
- if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
- remainder_size = size - nb;
- remainder = chunk_at_offset(p, nb);
- set_head(remainder, remainder_size | PREV_INUSE);
- set_head_size(p, nb);
- free(chunk2mem(remainder));
- }
- }
- check_inuse_chunk(p);
- retval = chunk2mem(p);
- DONE:
- __MALLOC_UNLOCK;
- return retval;
- }
- weak_alias(memalign, aligned_alloc)
- libc_hidden_def(memalign)
- weak_alias(memalign, __libc_memalign)
|