| 849 | ----------------------------------------------------------- */ |
| 850 | |
| 851 | void* _mi_os_alloc_aligned_offset(size_t size, size_t alignment, size_t offset, bool commit, bool* large, mi_stats_t* tld_stats) { |
| 852 | mi_assert(offset <= MI_SEGMENT_SIZE); |
| 853 | mi_assert(offset <= size); |
| 854 | mi_assert((alignment % _mi_os_page_size()) == 0); |
| 855 | if (offset > MI_SEGMENT_SIZE) return NULL; |
| 856 | if (offset == 0) { |
| 857 | // regular aligned allocation |
| 858 | return _mi_os_alloc_aligned(size, alignment, commit, large, tld_stats); |
| 859 | } |
| 860 | else { |
| 861 | // overallocate to align at an offset |
| 862 | const size_t extra = _mi_align_up(offset, alignment) - offset; |
| 863 | const size_t oversize = size + extra; |
| 864 | void* start = _mi_os_alloc_aligned(oversize, alignment, commit, large, tld_stats); |
| 865 | if (start == NULL) return NULL; |
| 866 | void* p = (uint8_t*)start + extra; |
| 867 | mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment)); |
| 868 | // decommit the overallocation at the start |
| 869 | if (commit && extra > _mi_os_page_size()) { |
| 870 | _mi_os_decommit(start, extra, tld_stats); |
| 871 | } |
| 872 | return p; |
| 873 | } |
| 874 | } |
| 875 | |
| 876 | void _mi_os_free_aligned(void* p, size_t size, size_t alignment, size_t align_offset, bool was_committed, mi_stats_t* tld_stats) { |
| 877 | mi_assert(align_offset <= MI_SEGMENT_SIZE); |
no test coverage detected