MCPcopy Create free account
hub / github.com/CppCXY/EmmyLuaCodeStyle / mi_segment_alloc

Function mi_segment_alloc

3rd/mimalloc-2.0.9/src/segment.c:847–945  ·  view source on GitHub ↗

Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .

Source from the content-addressed store, hash-verified

845
846// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .
847static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld, mi_page_t** huge_page)
848{
849 mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL));
850
851 // calculate needed sizes first
852 size_t info_slices;
853 size_t pre_size;
854 size_t segment_slices = mi_segment_calculate_slices(required, &pre_size, &info_slices);
855
856 // Commit eagerly only if not the first N lazy segments (to reduce impact of many threads that allocate just a little)
857 const bool eager_delay = (// !_mi_os_has_overcommit() && // never delay on overcommit systems
858 _mi_current_thread_count() > 1 && // do not delay for the first N threads
859 tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay));
860 const bool eager = !eager_delay && mi_option_is_enabled(mi_option_eager_commit);
861 bool commit = eager || (required > 0);
862 bool is_zero = false;
863
864 mi_commit_mask_t commit_mask;
865 mi_commit_mask_t decommit_mask;
866 mi_commit_mask_create_empty(&commit_mask);
867 mi_commit_mask_create_empty(&decommit_mask);
868
869 // Allocate the segment from the OS
870 mi_segment_t* segment = mi_segment_os_alloc(required, page_alignment, eager_delay, req_arena_id,
871 &segment_slices, &pre_size, &info_slices, &commit_mask, &decommit_mask,
872 &is_zero, &commit, tld, os_tld);
873 if (segment == NULL) return NULL;
874
875 // zero the segment info? -- not always needed as it may be zero initialized from the OS
876 mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); // tsan
877 if (!is_zero) {
878 ptrdiff_t ofs = offsetof(mi_segment_t, next);
879 size_t prefix = offsetof(mi_segment_t, slices) - ofs;
880 memset((uint8_t*)segment+ofs, 0, prefix + sizeof(mi_slice_t)*(segment_slices+1)); // one more
881 }
882
883 segment->commit_mask = commit_mask; // on lazy commit, the initial part is always committed
884 segment->allow_decommit = (mi_option_is_enabled(mi_option_allow_decommit) && !segment->mem_is_pinned && !segment->mem_is_large);
885 if (segment->allow_decommit) {
886 segment->decommit_expire = 0; // don't decommit just committed memory // _mi_clock_now() + mi_option_get(mi_option_decommit_delay);
887 segment->decommit_mask = decommit_mask;
888 mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->decommit_mask));
889 #if MI_DEBUG>2
890 const size_t commit_needed = _mi_divide_up(info_slices*MI_SEGMENT_SLICE_SIZE, MI_COMMIT_SIZE);
891 mi_commit_mask_t commit_needed_mask;
892 mi_commit_mask_create(0, commit_needed, &commit_needed_mask);
893 mi_assert_internal(!mi_commit_mask_any_set(&segment->decommit_mask, &commit_needed_mask));
894 #endif
895 }
896
897 // initialize segment info
898 const size_t slice_entries = (segment_slices > MI_SLICES_PER_SEGMENT ? MI_SLICES_PER_SEGMENT : segment_slices);
899 segment->segment_slices = segment_slices;
900 segment->segment_info_slices = info_slices;
901 segment->thread_id = _mi_thread_id();
902 segment->cookie = _mi_ptr_cookie(segment);
903 segment->slice_entries = slice_entries;
904 segment->kind = (required == 0 ? MI_SEGMENT_NORMAL : MI_SEGMENT_HUGE);

Callers 2

Calls 15

_mi_current_thread_countFunction · 0.85
mi_option_getFunction · 0.85
mi_option_is_enabledFunction · 0.85
mi_segment_os_allocFunction · 0.85
mi_commit_mask_all_setFunction · 0.85
_mi_divide_upFunction · 0.85
mi_commit_mask_createFunction · 0.85
mi_commit_mask_any_setFunction · 0.85
_mi_thread_idFunction · 0.85
_mi_ptr_cookieFunction · 0.85

Tested by

no test coverage detected