| 170 | -----------------------------------------------------------------------------*/ |
| 171 | |
| 172 | static bool mi_region_try_alloc_os(size_t blocks, bool commit, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld) |
| 173 | { |
| 174 | // not out of regions yet? |
| 175 | if (mi_atomic_load_relaxed(®ions_count) >= MI_REGION_MAX - 1) return false; |
| 176 | |
| 177 | // try to allocate a fresh region from the OS |
| 178 | bool region_commit = (commit && mi_option_is_enabled(mi_option_eager_region_commit)); |
| 179 | bool region_large = (commit && allow_large); |
| 180 | bool is_zero = false; |
| 181 | bool is_pinned = false; |
| 182 | size_t arena_memid = 0; |
| 183 | void* const start = _mi_arena_alloc_aligned(MI_REGION_SIZE, MI_SEGMENT_ALIGN, 0, ®ion_commit, ®ion_large, &is_pinned, &is_zero, _mi_arena_id_none(), & arena_memid, tld); |
| 184 | if (start == NULL) return false; |
| 185 | mi_assert_internal(!(region_large && !allow_large)); |
| 186 | mi_assert_internal(!region_large || region_commit); |
| 187 | |
| 188 | // claim a fresh slot |
| 189 | const size_t idx = mi_atomic_increment_acq_rel(®ions_count); |
| 190 | if (idx >= MI_REGION_MAX) { |
| 191 | mi_atomic_decrement_acq_rel(®ions_count); |
| 192 | _mi_arena_free(start, MI_REGION_SIZE, MI_SEGMENT_ALIGN, 0, arena_memid, region_commit, tld->stats); |
| 193 | _mi_warning_message("maximum regions used: %zu GiB (perhaps recompile with a larger setting for MI_HEAP_REGION_MAX_SIZE)", _mi_divide_up(MI_HEAP_REGION_MAX_SIZE, MI_GiB)); |
| 194 | return false; |
| 195 | } |
| 196 | |
| 197 | // allocated, initialize and claim the initial blocks |
| 198 | mem_region_t* r = ®ions[idx]; |
| 199 | r->arena_memid = arena_memid; |
| 200 | mi_atomic_store_release(&r->in_use, (size_t)0); |
| 201 | mi_atomic_store_release(&r->dirty, (is_zero ? 0 : MI_BITMAP_FIELD_FULL)); |
| 202 | mi_atomic_store_release(&r->commit, (region_commit ? MI_BITMAP_FIELD_FULL : 0)); |
| 203 | mi_atomic_store_release(&r->reset, (size_t)0); |
| 204 | *bit_idx = 0; |
| 205 | _mi_bitmap_claim(&r->in_use, 1, blocks, *bit_idx, NULL); |
| 206 | mi_atomic_store_ptr_release(void,&r->start, start); |
| 207 | |
| 208 | // and share it |
| 209 | mi_region_info_t info; |
| 210 | info.value = 0; // initialize the full union to zero |
| 211 | info.x.valid = true; |
| 212 | info.x.is_large = region_large; |
| 213 | info.x.is_pinned = is_pinned; |
| 214 | info.x.numa_node = (short)_mi_os_numa_node(tld); |
| 215 | mi_atomic_store_release(&r->info, info.value); // now make it available to others |
| 216 | *region = r; |
| 217 | return true; |
| 218 | } |
| 219 | |
| 220 | /* ---------------------------------------------------------------------------- |
| 221 | Try to claim blocks in suitable regions |
no test coverage detected