| 2723 | } |
| 2724 | |
| 2725 | int malloc_state::sys_trim(size_t pad) |
| 2726 | { |
| 2727 | size_t released = 0; |
| 2728 | mparams.ensure_initialization(); |
| 2729 | if (pad < MAX_REQUEST && is_initialized()) |
| 2730 | { |
| 2731 | pad += top_foot_size(); // ensure enough room for segment overhead |
| 2732 | |
| 2733 | if (_topsize > pad) |
| 2734 | { |
| 2735 | // Shrink top space in _granularity - size units, keeping at least one |
| 2736 | size_t unit = mparams._granularity; |
| 2737 | size_t extra = ((_topsize - pad + (unit - 1)) / unit - |
| 2738 | 1) * unit; |
| 2739 | msegmentptr sp = segment_holding((char*)_top); |
| 2740 | |
| 2741 | if (!sp->is_extern_segment()) |
| 2742 | { |
| 2743 | if (sp->is_mmapped_segment()) |
| 2744 | { |
| 2745 | if (SPP_HAVE_MMAP && |
| 2746 | sp->_size >= extra && |
| 2747 | !has_segment_link(sp)) |
| 2748 | { |
| 2749 | // can't shrink if pinned |
| 2750 | size_t newsize = sp->_size - extra; |
| 2751 | (void)newsize; // placate people compiling -Wunused-variable |
| 2752 | // Prefer mremap, fall back to munmap |
| 2753 | if ((SPP_CALL_MREMAP(sp->_base, sp->_size, newsize, 0) != mfail) || |
| 2754 | (SPP_CALL_MUNMAP(sp->_base + newsize, extra) == 0)) |
| 2755 | released = extra; |
| 2756 | } |
| 2757 | } |
| 2758 | } |
| 2759 | |
| 2760 | if (released != 0) |
| 2761 | { |
| 2762 | sp->_size -= released; |
| 2763 | _footprint -= released; |
| 2764 | init_top(_top, _topsize - released); |
| 2765 | check_top_chunk(_top); |
| 2766 | } |
| 2767 | } |
| 2768 | |
| 2769 | // Unmap any unused mmapped segments |
| 2770 | if (SPP_HAVE_MMAP) |
| 2771 | released += release_unused_segments(); |
| 2772 | |
| 2773 | // On failure, disable autotrim to avoid repeated failed future calls |
| 2774 | if (released == 0 && _topsize > _trim_check) |
| 2775 | _trim_check = spp_max_size_t; |
| 2776 | } |
| 2777 | |
| 2778 | return (released != 0) ? 1 : 0; |
| 2779 | } |
| 2780 | |
| 2781 | /* Consolidate and bin a chunk. Differs from exported versions |
| 2782 | of free mainly in that the chunk need not be marked as inuse. |
no test coverage detected