123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- #define munmap __munmap
- #include "malloc.h"
- static int __malloc_trim(size_t pad, mstate av)
- {
- long top_size;
- long extra;
- long released;
- char* current_brk;
- char* new_brk;
- size_t pagesz;
- pagesz = av->pagesize;
- top_size = chunksize(av->top);
-
- extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
- if (extra > 0) {
-
- current_brk = (char*)(MORECORE(0));
- if (current_brk == (char*)(av->top) + top_size) {
-
- MORECORE(-extra);
- new_brk = (char*)(MORECORE(0));
- if (new_brk != (char*)MORECORE_FAILURE) {
- released = (long)(current_brk - new_brk);
- if (released != 0) {
-
- av->sbrked_mem -= released;
- set_head(av->top, (top_size - released) | PREV_INUSE);
- check_malloc_state();
- return 1;
- }
- }
- }
- }
- return 0;
- }
- int malloc_trim(size_t pad)
- {
- mstate av = get_malloc_state();
- __malloc_consolidate(av);
- return __malloc_trim(pad, av);
- }
- static void malloc_init_state(mstate av)
- {
- int i;
- mbinptr bin;
-
- for (i = 1; i < NBINS; ++i) {
- bin = bin_at(av,i);
- bin->fd = bin->bk = bin;
- }
- av->top_pad = DEFAULT_TOP_PAD;
- av->n_mmaps_max = DEFAULT_MMAP_MAX;
- av->mmap_threshold = DEFAULT_MMAP_THRESHOLD;
- av->trim_threshold = DEFAULT_TRIM_THRESHOLD;
- #if MORECORE_CONTIGUOUS
- set_contiguous(av);
- #else
- set_noncontiguous(av);
- #endif
- set_max_fast(av, DEFAULT_MXFAST);
- av->top = initial_top(av);
- av->pagesize = malloc_getpagesize;
- }
- void __malloc_consolidate(mstate av)
- {
- mfastbinptr* fb;
- mfastbinptr* maxfb;
- mchunkptr p;
- mchunkptr nextp;
- mchunkptr unsorted_bin;
- mchunkptr first_unsorted;
-
- mchunkptr nextchunk;
- size_t size;
- size_t nextsize;
- size_t prevsize;
- int nextinuse;
- mchunkptr bck;
- mchunkptr fwd;
-
- if (av->max_fast != 0) {
- clear_fastchunks(av);
- unsorted_bin = unsorted_chunks(av);
-
- maxfb = &(av->fastbins[fastbin_index(av->max_fast)]);
- fb = &(av->fastbins[0]);
- do {
- if ( (p = *fb) != 0) {
- *fb = 0;
- do {
- check_inuse_chunk(p);
- nextp = p->fd;
-
- size = p->size & ~PREV_INUSE;
- nextchunk = chunk_at_offset(p, size);
- nextsize = chunksize(nextchunk);
- if (!prev_inuse(p)) {
- prevsize = p->prev_size;
- size += prevsize;
- p = chunk_at_offset(p, -((long) prevsize));
- unlink(p, bck, fwd);
- }
- if (nextchunk != av->top) {
- nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
- set_head(nextchunk, nextsize);
- if (!nextinuse) {
- size += nextsize;
- unlink(nextchunk, bck, fwd);
- }
- first_unsorted = unsorted_bin->fd;
- unsorted_bin->fd = p;
- first_unsorted->bk = p;
- set_head(p, size | PREV_INUSE);
- p->bk = unsorted_bin;
- p->fd = first_unsorted;
- set_foot(p, size);
- }
- else {
- size += nextsize;
- set_head(p, size | PREV_INUSE);
- av->top = p;
- }
- } while ( (p = nextp) != 0);
- }
- } while (fb++ != maxfb);
- }
- else {
- malloc_init_state(av);
- check_malloc_state();
- }
- }
- void free(void* mem)
- {
- mstate av;
- mchunkptr p;
- size_t size;
- mfastbinptr* fb;
- mchunkptr nextchunk;
- size_t nextsize;
- int nextinuse;
- size_t prevsize;
- mchunkptr bck;
- mchunkptr fwd;
-
- if (mem == NULL)
- return;
- LOCK;
- av = get_malloc_state();
- p = mem2chunk(mem);
- size = chunksize(p);
- check_inuse_chunk(p);
-
- if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
- #if TRIM_FASTBINS
-
- && (chunk_at_offset(p, size) != av->top)
- #endif
- ) {
- set_fastchunks(av);
- fb = &(av->fastbins[fastbin_index(size)]);
- p->fd = *fb;
- *fb = p;
- }
-
- else if (!chunk_is_mmapped(p)) {
- set_anychunks(av);
- nextchunk = chunk_at_offset(p, size);
- nextsize = chunksize(nextchunk);
-
- if (!prev_inuse(p)) {
- prevsize = p->prev_size;
- size += prevsize;
- p = chunk_at_offset(p, -((long) prevsize));
- unlink(p, bck, fwd);
- }
- if (nextchunk != av->top) {
-
- nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
- set_head(nextchunk, nextsize);
-
- if (!nextinuse) {
- unlink(nextchunk, bck, fwd);
- size += nextsize;
- }
-
- bck = unsorted_chunks(av);
- fwd = bck->fd;
- p->bk = bck;
- p->fd = fwd;
- bck->fd = p;
- fwd->bk = p;
- set_head(p, size | PREV_INUSE);
- set_foot(p, size);
- check_free_chunk(p);
- }
-
- else {
- size += nextsize;
- set_head(p, size | PREV_INUSE);
- av->top = p;
- check_chunk(p);
- }
-
- if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
- if (have_fastchunks(av))
- __malloc_consolidate(av);
- if ((unsigned long)(chunksize(av->top)) >=
- (unsigned long)(av->trim_threshold))
- __malloc_trim(av->top_pad, av);
- }
- }
-
- else {
- int ret;
- size_t offset = p->prev_size;
- av->n_mmaps--;
- av->mmapped_mem -= (size + offset);
- ret = munmap((char*)p - offset, size + offset);
-
- assert(ret == 0);
- }
- UNLOCK;
- }
|